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
# 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!