Finding nearest non-zero pixel [closed]
I've got a binary image noObjectMask
(CV_8UC1
) and a given point objectCenter
(cv::Point
). If the objectCenter
is a zer-value pixel, I need to find the nearest non-zero pixel starting from the given point.
The number of non-zero points in the whole image can be large (even up to 50%), so calculating distances for each point returned from cv::findNonZero
seems to be non-optimal. As the highest probability is that the pixel will be in the close neighborhood, I currently use:
# my prototype script in Python, but the final version will be implemented in C++
if noObjectMask[objectCenter[1],objectCenter[0]] == 0:
# if the objectCenter is zero-value pixel, subtract sequentially its neighborhood ROIs
# increasing its size (r), until the ROI contains at least one non-zero pixel
for r in range(noObjectMask.shape[1]/2):
rectL = objectCenter[1]-r-1
rectR = objectCenter[1]+r
rectT = objectCenter[0]-r-1
rectB = objectCenter[0]+r
# Pythonic way of subtracting ROI: noObjectMask(cv::Rect(...))
rect = noObjectMask[rectL:rectR, rectT:rectB]
if cv2.countNonZero(rect)>0: break
nonZeroNeighbours = cv2.findNonZero(rect)
# calculating the distances between objectCenter and each of nonZeroNeighbours
# and choosing the closest one
This works okay, as in my images the non-zero pixels are typically in the closest neighborhood (r
<=10px), but the processing time increases dramatically with the distance of the closest pixel. Each repetition of countNonZero
repeats counting of the previous pixels. This could be improved by incrementing the radius r
by more than one, but this still looks a bit clumsy to me.
How to improve the procedure? And ideas? -Thanks!
what about cv::distanceTransform
Okay, this will show me how far I am from the closest non-zero point, and the local gradient will let me estimate the direction of closest point, right? Seems a good idea...