Reputation: 23
I want to get rid of the black vertical and horizontal lines in my image. This is the code I've written until now
#convert RGB to grayscale
gray_slide = cv.cvtColor(slide_ds, cv.COLOR_BGR2GRAY)
#remove black areas
gray_slide[np.where(gray_slide<=[10])] = [255]
#remove edges
linek = np.zeros((11,11),dtype=np.uint8)
linek[5,...]=1
x=cv.morphologyEx(gray_slide, cv.MORPH_OPEN, linek ,iterations=1)
gray_slide+=x
But it doesn't do the job. I want this image
to be converted to this
Can you help me please? BTW this was the original image original image
Upvotes: 0
Views: 565
Reputation: 1265
Inpainting (OpenCV docs) is one way to do this.
>>> img = cv2.imread("blacklines.jpg")
>>> mask = cv2.imread("blacklines_MASK.jpg", 0)
>>> dst = cv2.inpaint(img, mask, 4, cv2.INPAINT_TELEA) # you can fiddle with the parameters
>>> cv2.imwrite("dst.jpg", dst) # save the image
Original image:
Partial mask drawn by hand for demonstration purposes:
Final result:
Now, if you want to do this programmatically for multiple images, you should consider programmatically creating masks. One approach to that is to filter images according to pixel values (e.g. what it seems you're doing with your gray_slide
).
Edit: I tried fiddling with a few parameters myself, and it comes close, but not quite there yet...
>>> mask = np.zeros(gray.shape)
>>> mask[np.where(gray<=140)] = [255]
>>> cv2.imwrite('mask.jpg', mask)
True
>>> mask = cv2.imread("mask.jpg", 0)
>>> i = cv2.inpaint(img, mask, 25, cv2.INPAINT_TELEA)
>>> cv2.imwrite("i2.jpg", i)
True
New mask (dropping the threshold to 120 seemed better since it did not touch the inner areas, but I kept this version instead):
Result, still some black elements here and there:
In the end, if you reach the mask stage I've shown above, you just need to make those lines "wider". It is worth a try (maybe use dilation/erosion or something).
Upvotes: 2