Reputation: 4406
I have been using OpenCV's findContours()
to find areas of contiguous black pixels. Sometimes it selects the area of white pixels surrounding the black pixels, e.g. in this figure the "g", "e", and "n" are selected with black pixels as I expect, but the other three letters are selected by the surrounding area of white pixels, as shown by the green points of the contour:
Sometimes, the "g" with the white area inside the bowl is selected as a contour, and other times the white area inside the bowl is a different contour.
For both examples, I could deal with the hierarchy and check which contours are children of which other contours, but I think I am missing something simpler.
How can I get OpenCV to select and return each separate area of contiguous black pixels?
Upvotes: 2
Views: 2051
Reputation: 4561
This is caused by findContours
, that starts by looking for white shapes on a black background. Simply inverting you image will improve results. The code below will draw contours one by one with a keypress, so you can see that it is the black pixels that are selected.
import cv2
import numpy as np
# Read image in color (so we can draw in red)
img = cv2.imread("vBQa7.jpg")
# convert to gray and threshold to get a binary image
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
th, dst = cv2.threshold(gray, 20, 255, cv2.THRESH_BINARY)
# invert image
dst = cv2.bitwise_not(dst)
# find contours
countours,hierarchy=cv2.findContours(dst,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
# draw contours
for cnt in countours:
cv2.drawContours(img,[cnt],0,(0,0,255),2)
cv2.imshow("Result",img)
cv2.waitKey(0)
# show image
cv2.imshow("Result",img)
cv2.waitKey(0)
cv2.destroyAllWindows()
You'll find that there are also some small black patches selected, as well as the background area. You can remove these by setting a minimum and maximum size and check the contourArea
for each contour. (docs)
Upvotes: 3
Reputation: 270
I dont know whether this is an option for your use case, but you could take the following steps:
identify the black pixels with filters/ thresholds
use a clustering algorithm (DBscan here I think) to group the pixels together
Upvotes: 1