如何在二进制图像(cv :: Mat)中找到所有非零像素的位置?我是否必须扫描图像中的每个像素,或者是否有可以使用的高级OpenCV功能?输出应该是点矢量(像素位置)。
例如,这可以在Matlab中完成:
imstats = regionprops(binary_image, 'PixelList');
locations = imstats.PixelList;
或者,甚至更简单
[x, y] = find(binary_image);
locations = [x, y];
编辑:换句话说,如何在cv :: Mat中找到所有非零元素的坐标?
答案 0 :(得分:10)
正如@AbidRahmanK所建议的,OpenCV版本2.4.4中有一个函数cv::findNonZero
。用法:
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
由于某种原因不在文档中。
答案 1 :(得分:10)
我把它作为Alex的答案中的编辑,但它没有得到审核,所以我会在这里发布,因为它是非常有用的信息。
你也可以传递一个点向量,然后更容易用它们做一些事情:
std::vector<cv::Point2i> locations; // output, locations of non-zero pixels
cv::findNonZero(binaryImage, locations);
cv::findNonZero
函数的一个注释:如果binaryImage
包含零非零元素,它将抛出,因为它试图分配&#39; 1 x n&#39;内存,其中n是cv::countNonZero
,n显然是0。我事先通过手动拨打cv::countNonZero
来规避这一点,但我并不是那么喜欢那个解决方案。
答案 2 :(得分:3)
任何想在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的功能相同。有关详细信息,请参阅: