15

如何找到二进制图像(cv::Mat)中所有非零像素的位置?我是否必须扫描图像中的每个像素,或者是否有可以使用的高级 OpenCV 函数?输出应该是一个点向量(像素位置)。

例如,这可以在 Matlab 中简单地完成为:

imstats = regionprops(binary_image, 'PixelList');
locations = imstats.PixelList;

或者,甚至更简单

[x, y] = find(binary_image);
locations = [x, y];

编辑:换句话说,如何在 cv::Mat 中找到所有非零元素的坐标?

4

3 回答 3

14

我将此作为编辑放在亚历克斯的答案中,但它没有得到审查,所以我会在这里发布,因为它是有用的信息恕我直言。

您还可以传递点向量,以便之后更轻松地使用它们:

std::vector<cv::Point2i> locations;   // output, locations of non-zero pixels 
cv::findNonZero(binaryImage, locations);

cv::findNonZero函数的一般注意事项:如果binaryImage包含零个非零元素,它将抛出,因为它试图分配“1 x n”内存,其中 n 是cv::countNonZero,那么 n 显然会是 0。我通过事先手动调用来规避这一点,cv::countNonZero但我不太喜欢那个解决方案。

于 2013-12-27T16:22:54.767 回答
12

正如@AbidRahmanK 所建议的,cv::findNonZeroOpenCV 2.4.4 版中有一个功能。用法:

cv::Mat binaryImage; // input, binary image
cv::Mat locations;   // output, locations of non-zero pixels 
cv::findNonZero(binaryImage, locations);

它完成了这项工作。此功能在 OpenCV 2.4.4 版本中引入(例如,在 2.4.2 版本中不可用)。此外,由于某种原因,截至目前findNonZero不在文档中。

于 2013-03-05T22:21:44.323 回答
4

任何希望在 python 中执行此操作的人。也可以使用 numpy 数组来执行此操作,因此您无需升级您的 opencv 版本(或使用未记录的函数)。

mask = np.zeros(imgray.shape,np.uint8)
cv2.drawContours(mask,[cnt],0,255,-1)
pixelpoints = np.transpose(np.nonzero(mask))
#pixelpoints = cv2.findNonZero(mask)

注释掉的是使用 openCV 代替的相同功能。有关更多信息,请参阅:

https://github.com/abidrahmank/OpenCV2-Python-Tutorials/blob/master/source/py_tutorials/py_imgproc/py_contours/py_contour_properties/py_contour_properties.rst

于 2013-09-25T01:33:50.027 回答