簡體   English   中英

如何使用 OpenCV Python 在圖像中僅保留黑色文本?

[英]How to keep Only Black color text in the image using OpenCV Python?

我有以下圖像:

這個圖片 .

我只想保留黑色文本 0790 並從圖片中刪除所有內容。 這個 stackoverflow 問題去除顏色。 但是,我需要保留顏色,而不是刪除它。

一種可能的解決方案包括將圖像轉換為CMYK顏色空間並提取K (Key - black)通道,對其進行閾值化並應用一些形態學來清理二進制圖像。

OpenCV 沒有實現從BGRCMYK的轉換,所以我們必須手動計算K通道。 代碼如下所示:

# Imports
import cv2
import numpy as np

# Read image
imagePath = "D://opencvImages//"
inputImage = cv2.imread(imagePath + "A6RXi.png")

# Conversion to CMYK (just the K channel):

# Convert to float and divide by 255:
imgFloat = inputImage.astype(np.float) / 255.

# Calculate channel K:
kChannel = 1 - np.max(imgFloat, axis=2)

# Convert back to uint 8:
kChannel = (255 * kChannel).astype(np.uint8)

這是 K(黑色)通道:

現在,使用固定值對圖像進行閾值處理。 在這種情況下,我將閾值設置為190

# Threshold image:
binaryThresh = 190
_, binaryImage = cv2.threshold(kChannel, binaryThresh, 255, cv2.THRESH_BINARY)

這是二進制圖像:

這是一點噪音,但如果我們實施區域過濾器,我們可以去除較小的斑點。 function 在本文末尾定義。 讓我們應用最小值100的過濾器。 所有小於此的 blob 都將被刪除:

# Filter small blobs:
minArea = 100
binaryImage = areaFilter(minArea, binaryImage)

這是過濾后的圖像:

涼爽的。 讓我們用一個關閉過濾器來改善 blob 的形態:

# Use a little bit of morphology to clean the mask:
# Set kernel (structuring element) size:
kernelSize = 3
# Set morph operation iterations:
opIterations = 2
# Get the structuring element:
morphKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
# Perform closing:
binaryImage = cv2.morphologyEx(binaryImage, cv2.MORPH_CLOSE, morphKernel, None, None, opIterations, cv2.BORDER_REFLECT101)

cv2.imshow("binaryImage [closed]", binaryImage)
cv2.waitKey(0)

這是最終結果:

這就是areaFilter function。 它接收一個最小區域和一個二值圖像,它返回沒有小斑點的圖像:

def areaFilter(minArea, inputImage):
    # Perform an area filter on the binary blobs:
    componentsNumber, labeledImage, componentStats, componentCentroids = \
        cv2.connectedComponentsWithStats(inputImage, connectivity=4)

    # Get the indices/labels of the remaining components based on the area stat
    # (skip the background component at index 0)
    remainingComponentLabels = [i for i in range(1, componentsNumber) if componentStats[i][4] >= minArea]

    # Filter the labeled pixels based on the remaining labels,
    # assign pixel intensity to 255 (uint8) for the remaining pixels
    filteredImage = np.where(np.isin(labeledImage, remainingComponentLabels) == True, 255, 0).astype('uint8')

    return filteredImage

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM