Python - OpenCV morphologyEx 移除特定颜色

10

移除验证码背景后,图像中仍然保留有数字和噪点。
噪点线全部为一种颜色:RGB(127,127,127)。
接下来使用形态学方法。

    kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (2, 2))
    self.im = cv2.morphologyEx(self.im, cv2.MORPH_CLOSE, kernel)

数字的某些部分将被删除。
如何使用morphologyEx()仅删除RGB(127,127,127)中的颜色?

进入图像描述这里 进入图像描述这里

3个回答

12
为了在特定范围内消除颜色,您需要使用 cv2.inRange() 函数。
以下是代码:
lower = np.array([126,126,126])  #-- Lower range --
upper = np.array([127,127,127])  #-- Upper range --
mask = cv2.inRange(img, lower, upper)
res = cv2.bitwise_and(img, img, mask= mask)  #-- Contains pixels having the gray color--
cv2.imshow('Result',res)

这是我得到的两张图片:

图片1:

enter image description here

图片2:

enter image description here

你从这里继续。


4

颜色范围

color_dict_HSV = {'black': [[180, 255, 30], [0, 0, 0]],
              'white': [[180, 18, 255], [0, 0, 231]],
              'red1': [[180, 255, 255], [159, 50, 70]],
              'red2': [[9, 255, 255], [0, 50, 70]],
              'green': [[89, 255, 255], [36, 50, 70]],
              'blue': [[128, 255, 255], [90, 50, 70]],
              'yellow': [[35, 255, 255], [25, 50, 70]],
              'purple': [[158, 255, 255], [129, 50, 70]],
              'orange': [[24, 255, 255], [10, 50, 70]],
              'gray': [[180, 18, 230], [0, 0, 40]]}

致谢:

阿里·哈什米安

使用OpenCV如何从图像中去除颜色

由于大多数人都需要这样做,例如我的情况是需要从图像中删除蓝色,我使用以下代码从图像中删除蓝色印章和蓝色勾号,以便在使用Tesseract进行正确的OCR。

[颜色去除] 代码

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

# image path:    
#path = "D://opencvImages//"
#fileName = "out.jpg"

# Reading an image in default mode:
inputImage = cv2.imread('0.jpg')

# Convert RGB to grayscale:
grayscaleImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2GRAY)

# Convert the BGR image to HSV:
hsvImage = cv2.cvtColor(inputImage, cv2.COLOR_BGR2HSV)

# Create the HSV range for the blue ink:
# [128, 255, 255], [90, 50, 70]
lowerValues = np.array([90, 50, 70])
upperValues = np.array([128, 255, 255])

# Get binary mask of the blue ink:
bluepenMask = cv2.inRange(hsvImage, lowerValues, upperValues)
# Use a little bit of morphology to clean the mask:
# Set kernel (structuring element) size:
kernelSize = 3
# Set morph operation iterations:
opIterations = 1
# Get the structuring element:
morphKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (kernelSize, kernelSize))
# Perform closing:
bluepenMask = cv2.morphologyEx(bluepenMask, cv2.MORPH_CLOSE, morphKernel, None, None, opIterations, cv2.BORDER_REFLECT101)

# Add the white mask to the grayscale image:
colorMask = cv2.add(grayscaleImage, bluepenMask)
_, binaryImage = cv2.threshold(colorMask, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
cv2.imwrite('bwimage.jpg',binaryImage)
thresh, im_bw = cv2.threshold(binaryImage, 210, 230, cv2.THRESH_BINARY)
kernel = np.ones((1, 1), np.uint8)
imgfinal = cv2.dilate(im_bw, kernel=kernel, iterations=1)
cv2.imshow(imgfinal)

BEFORE [原始图像]

Original Image

蓝色标记抽取

Blue Tick Marks Determined

最终图像

enter image description here

在这里,您可以看到几乎去除了所有的勾号,原因是始终有改进的空间,但似乎这已经是我们能够得到的最好结果,因为即使去除这些小标记也不会对使用Tesseract的OCR产生深刻影响。

希望这可以帮助!


1
你好,你的代码对于从图像中提取一种颜色非常有帮助。但是我如何同时提取两种颜色呢?比如原始图像上有红色和蓝色标记。感谢你的回复。 - Won Chul Chung
@WonChulChung,您可以通过首先为红色制作一个掩码,然后为蓝色制作一个掩码,接着从原始图像中删除第一个掩码并将所有值替换为白色,最后使用第二个掩码(红色)并将所有红色像素删除到白色来实现此操作。希望这也能帮助其他人。 - Muneeb Ahmad Khurram

3

这是我的解决方案。
你的答案显然比我的更好。

 def mop_close(self):
    def morphological(operator=min):
        height, width, _ = self.im.shape
        # create empty image
        out_im = np.zeros((height,width,3), np.uint8)
        out_im.fill(255) # fill with white
        for y in range(height):
            for x in range(width):
                try:
                    if self.im[y,x][0] ==127 and self.im[y,x][1] ==127 and self.im[y,x][2] ==127:
                        nlst = neighbours(self.im, y, x)

                        out_im[y, x] = operator(nlst,key = lambda x:np.mean(x))
                    else:
                        out_im[y,x] = self.im[y,x]
                except Exception as e:
                    print(e)
        return out_im

    def neighbours(pix,y, x):
        nlst = []
        # search pixels around im[y,x] add them to nlst
        for yy in range(y-1,y+1):
            for xx in range(x-1,x+1):
                try:
                    nlst.append(pix[yy, xx])
                except:
                    pass
        return np.array(nlst)

    def erosion(im):
        return morphological(min)

    def dilation(im):
        return morphological(max)

    self.im = dilation(self.im)
    self.im = erosion(self.im)

最终结果: 输入图像描述 输入图像描述

酷,只要它能工作,我就满意了。如果您不介意,请也发布最终结果。 :DFinal result: 酷,只要它能工作,我就满意了。如果您不介意,请也发布最终结果。 :D - Jeru Luke
我在方法中进行了小的调整。我将结果附在文章后面。 - Yich Lin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接