Search code examples
pythonopencvimage-processingimage-masking

draw a line until the edge of the mask OpenCV in python


Give an image like the following image

Blue circle on a white back ground

I can create a mask of this quite easily.The masked image looks like this.

Masked image

I use the following code to get the mask.

#Convert to HSV
HSV = cv2.cvtColor(I, cv2.COLOR_BGR2HSV)
#Create a lower and upper range
HSVlower = np.array([0,0,0])
HSVupper = np.array([134,205,255])

#deine a mask
mask = cv2.inRange(HSV , HSVlower , HSVupper)
cv2.imshow("MASK" , mask)
cv2.waitKey(0)

I can then identify the center of the masked area using contours and moments. The image with the center marked is this :

center point identified and drawn on result image

Here is the code I use to get the seed point.

#find biggest cont
contours,hierarchy = 
cv2.findContours(mask,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
#find largest contour in mask, use to compute minEnCircle
c = max(contours, key = cv2.contourArea)
cv2.drawContours(I , c , -1,(255,255,255) , 3 )


#get center of detected circle
moments = cv2.moments(c)
cx = int(moments['m10']/moments['m00'])
cy = int(moments['m01']/moments['m00'])

Here is where my issue lies. I would like to draw N number of lines at N/360 degrees , from the center of this image until the point where the mask from black to white.I have been unable to this.

I have simplify this issue down to a single line and much simpler image and the behavior is the same. I move out from the center one pixel at a time checking the value of that pixel in the mask image. If the value is dark I draw a line and move the next pixel. This process is repeated until i find a pixel that is not dark.

I achieve the following results using the logic above.

Line does not stop where expected

As seen the line does not stop where I expect at the edge of the circle.

This is the code i am using to draw the line and check the pixel value.

localIndex = 0 
##move from the center until we hit white 
while mask[cx,cy + localIndex] < 20:
    cv2.line(img=I, pt1=(cx, cy), pt2=(cx,cy + localIndex), color=(0, 255, 255), 
thickness=3)
    localIndex =  localIndex + 1
    print  mask[cx, cy + localIndex]

cv2.imshow("linedImage" , I)
cv2.waitKey(0)

EDIT: Here is the link to the photo i am using. https://vignette.wikia.nocookie.net/uncyclopedia/images/b/bc/Trick110.png/revision/latest?cb=20170408115814

EDIT: Printing out the pixel values as I loop I can see they are all 0 until the jump to 130.This makes me think that there is a scale issue between the mask and the original image? Also the line is not needed only the point at which the mask changes. The line drawn is there for visualization


Solution

  • Replace the while loop condition correctly. Change it to -

    while (mask[cx,cy + localIndex] ==0)
    

    enter image description here