0

I am trying to refine an image through removing the noise. The image has a red color as dominant so I am trying to remove any other color except the red .. Here's an example of the image enter image description here

I have found this code but couldn't use it properly. Please if you will put an answer consider me as very newbie and take it step by step as I need to learn not only to solve a problem

import cv2
import numpy as np

# Load image
im = cv2.imread('Output.png')

# Make all perfectly green pixels white
im[np.all(im == (193, 47, 47), axis=-1)] = (0,0,0)

# Save result
cv2.imwrite('result1.png',im)

I need to keep only the red color and the white as a background color.

I would like to refine the image so as to be able to extract numbers from it using such a code

def getCaptcha(img):
    pytesseract.pytesseract.tesseract_cmd=r'C:\\Program Files\\Tesseract-OCR\\tesseract.exe'
    img=Image.open(img)
    text=pytesseract.image_to_string(img, lang='eng',config='--psm 10 --oem 3 -c tessedit_char_whitelist=0123456789')
    return text

print(getCaptcha('red_numerals_thresh.jpg'))
print(getCaptcha('red_numerals_result.jpg'))
YasserKhalil
  • 9,138
  • 7
  • 36
  • 95
  • 1
    Take a look at https://stackoverflow.com/questions/53977777/how-can-i-only-keep-text-with-specific-color-from-image-via-opencv-and-python – Adi Dec 09 '20 at 14:22
  • Thanks a lot. In fact, I have searched and found many threads but I felt lost and need a starter solution (suitable for any beginner to get and understand) – YasserKhalil Dec 09 '20 at 14:25
  • The answer I was pointing to is to use the .inrange(..) function, with the range being what colors of red are acceptable for your application. – Adi Dec 09 '20 at 14:27
  • Can you show me please an example as an answer? – YasserKhalil Dec 09 '20 at 14:28
  • I think the dominant color is `[163.95652174 38.57391304 38.72173913]` – YasserKhalil Dec 09 '20 at 14:29
  • From the above link, cv2.inRange(hsv, (Lower range), (Upper range)) is your required image. Im assuming you went with RGB color scheme, you need to use HSV, use the color scale in that answer to calculate a range, and adjust it till you get the mask. Hue will be 0-10 and sat/value can be 0-255 – Adi Dec 09 '20 at 14:35
  • Thanks anyway. It seems I have to search again to get more information myself. – YasserKhalil Dec 09 '20 at 14:40

1 Answers1

1

Here is one way to do that in Python OpenCV using cv2.inRange().

Input:

enter image description here

import cv2
import numpy as np

# Read image
img = cv2.imread('red_numerals.jpg')

# threshold red
lower = np.array([0, 0, 0])
upper = np.array([40, 40, 255])
thresh = cv2.inRange(img, lower, upper)
    
# Change non-red to white
result = img.copy()
result[thresh != 255] = (255,255,255)

# save results
cv2.imwrite('red_numerals_thresh.jpg', thresh)
cv2.imwrite('red_numerals_result.jpg', result)

cv2.imshow('thresh', thresh)
cv2.imshow('result', result)
cv2.waitKey(0)
cv2.destroyAllWindows()

Threshold image:

enter image description here

Result:

enter image description here

fmw42
  • 46,825
  • 10
  • 62
  • 80
  • Amazing. Thanks a lot for great help. Can you tell me what are the numbers in the code refer to? `[40, 40, 255])` – YasserKhalil Dec 09 '20 at 19:19
  • 1
    Those are the upper values for the range of red colors. The red is not perfectly red, but has some blue and green in it. I use a GUI tool to find the range of colors in the red numerals. Then if needed, I lower the values for the lower range and increase the values for the upper range until the threshold image looks clean. Sometimes, one needs to use morphology to clean up extraneous white or dark spots. But it was not needed for this case. – fmw42 Dec 09 '20 at 19:24
  • I have updated the question with the code I am using to extract numbers from the image. But both the output of the code doesn't return correct number – YasserKhalil Dec 09 '20 at 19:24
  • Can you provide me with the GUI tool you used? – YasserKhalil Dec 09 '20 at 19:25
  • 1
    For OCR, you should just take the threshold image and invert it so the characters are black on a white background. No need to get the red letters. I used a Mac-based tool called GraphicsConverter. But you can use any GUI tool that you can find on Google or Apple stores or simply use GIMP (or Photoshop). Some people write Python code with sliders, etc. So search this forum about that. – fmw42 Dec 09 '20 at 19:28
  • Thanks a lot for your support. Can you show me how to convert to black on white background..? – YasserKhalil Dec 09 '20 at 19:29
  • `thresh = 255 - thresh` is one way. thresh=cv2.bitwise_not(thresh) is another. See https://docs.opencv.org/4.1.1/d2/de8/group__core__array.html#ga0002cf8b418479f4cb49a75442baee2f – fmw42 Dec 09 '20 at 20:13
  • Amazing. Thanks a lot. – YasserKhalil Dec 09 '20 at 20:39