4

I have a input image similar to

enter image description here

I am referring to: How to fill the gaps in letters after Canny edge detection

I want to plot black pixels on this image. The proposed solution on the above url is first find all black pixels using

import matplotlib.pyplot as pp
import numpy as np

image = pp.imread(r'/home/cris/tmp/Zuv3p.jpg')
bin = np.all(image<100, axis=2)

My question is dow do I plot this black pixels (data stored in bin ) on image while ignoring all other colour channels.

Ajinkya
  • 1,797
  • 3
  • 24
  • 54
  • What do you mean by "plot the black pixels"? Do you want to show a histogram of the black pixels after you've extracted them? – rayryeng Mar 04 '19 at 07:41
  • No, I want to cv2.imwrite('output.jpg', image). Where image highlights only the language in the above image. I want to highlight the letters and remove the background from the image – Ajinkya Mar 04 '19 at 07:44
  • The question you linked already does that. – rayryeng Mar 04 '19 at 07:44
  • The suggested solution in above link finds all pixels where all three channels are below a value of 100. I want to plot the image with these newly defined values below 100 – Ajinkya Mar 04 '19 at 07:52

1 Answers1

6

In the answer is stated that np.all(image<100, axis=2) is used to select pixels where R,G and B are all lower then 100, which is basically color separation. Personally, I like to use the HSV-colorspace for that.

Result:

enter image description here

Note: if you want to improve the green letters, it is best to create a separate mask for that, and tweak the hsv values for green.

Code:

    import numpy as np 
    import cv2
    # load image
    img = cv2.imread("img.jpg")

     # Convert BGR to HSV
    hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

    # define range of black color in HSV
    lower_val = np.array([0,0,0])
    upper_val = np.array([179,255,127])

    # Threshold the HSV image to get only black colors
    mask = cv2.inRange(hsv, lower_val, upper_val)

    # invert mask to get black symbols on white background
    mask_inv = cv2.bitwise_not(mask)

    # display image
    cv2.imshow("Mask", mask_inv)
    cv2.imshow("Img", img)

    cv2.waitKey(0)
    cv2.destroyAllWindows()
J.D.
  • 4,511
  • 2
  • 7
  • 20
  • I found this answer for a project I am working on. I am trying to do something similar. Although I do not want to extract grey, i only want BLACK. When I use this it is pulling a lot of the background from my image. I have been messing around with the upper_val numbers but cant get it right. What would the Upper/lower vals have to be to only pull out TRUE black, and then I can try and work from there. – Lzypenguin Aug 25 '20 at 19:30
  • The upper_val numbers are [Hue, Saturation,Value]. as you can see in [this](https://en.wikipedia.org/wiki/HSL_and_HSV#/media/File:HSV_color_solid_cylinder_saturation_gray.png) image, you want all hue, all saturation, and threshold the Value. Lower = darker. You can test values on your image using [this script](https://github.com/twenty-twenty/opencv_basic_color_separator) – J.D. Aug 26 '20 at 20:46
  • If with true black you mean #000000, i would suggest using a [binary threshold](https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_thresholding/py_thresholding.html) – J.D. Aug 26 '20 at 20:50