Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python - opencv morphologyEx remove specific color

After remove captcha's background.
The image remain digits and noise.
Noise line is all in one color : RGB(127,127,127)
And then using morphology method.

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

Some part of digit will be remove.
How to use morphologyEx() remove only color in RGB(127,127,127) ?

enter image description hereenter image description here

like image 612
Yich Lin Avatar asked Mar 04 '17 04:03

Yich Lin


People also ask

How do I remove one color from an image in OpenCV?

In order to eliminate color within a particular range you have to use cv2. inRange() function. You carry on from here. Save this answer.

How do I remove a specific color from an image in Python?

Going through each pixel of the image and setting the (r,g,b) value as (0,g,b), i.e setting the value for RED as 0. If you want to remove GREEN or BLUE color then assign the values accordingly. Saving our image after removing RED color from it, and naming it “changed. jpeg”.

How do I remove the blue color from an image in Python?

To remove blue channel from color image, read image to BGR array using cv2. imread() and assign zeros to the 2D array corresponding to blue channel. In this tutorial, we shall use OpenCV Python library and transform an image, such that no red channel is present in the image.


3 Answers

In order to eliminate color within a particular range you have to use cv2.inRange() function.

Here is the code:

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)

This is what I got for the two images you have:

Image 1:

enter image description here

Image 2:

enter image description here

You carry on from here.

like image 132
Jeru Luke Avatar answered Oct 16 '22 05:10

Jeru Luke


Here is my solution.
Your answer is obvious better than my.

 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)

final result: enter image description here enter image description here

like image 26
Yich Lin Avatar answered Oct 16 '22 07:10

Yich Lin


COLOR RANGE

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]]}

CREDITS:

Ali Hashemian

HOW TO REMOVE A COLOR FROM YOUR IMAGE USING OPENCV

Since most of you would like to do that, i.e. in my case the task was to remove blue color from the image, I used the following code, to remove blue ink stamps and, blue tick marks from my image in order for proper OCR using Tesseract.

[COLOR REMOVAL] CODE

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]

Original Image

Blue Mark Extraction

Blue Tick Marks Determined

Final Image

enter image description here

Here you can see that all of the tick marks are almost, removed the reason is that because there is always room for improvement, but this, as it seems, is the best we can get because even removing these little marks is not going to have a profound effect on the OCR using Tesseract.

HOPE THAT HELPS!

like image 21
Muneeb Ahmad Khurram Avatar answered Oct 16 '22 07:10

Muneeb Ahmad Khurram