2013-03-05 346 views
11

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

例如,这可以在Matlab进行简单的:

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

,或者更简单

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

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

+1

你使用哪个版本的opencv?在2.4.4 python版本中,我可以找到类似的函数“cv2.findNonzero”,这意味着它也应该在C++中。但它不在文档中。因此安装2.4.4并检查该功能。 – 2013-03-05 18:32:25

+0

Thx,在我的OpenCV版本2.4.2(C++)中没有cv :: findNonzero。 – Alexey 2013-03-05 19:20:51

+0

我认为它在2.4.4。我从2.4.4 python版本中得到它。所以,如果你想使用它,你可能会更新到2.4.4 – 2013-03-05 19:22:39

回答

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由于某种原因未在文档中。

2

任何想在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

9

我把这个在Alex的答案编辑,它没有得到审查,虽然,所以我会张贴在这里,因为它是有用的信息,恕我直言。

您也可以通过点的载体,可以更容易地做一些与他们算账:对于一般的cv::findNonZero功能

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

一个注意:如果binaryImage包含零非零元素,它会因为它试图分配'1 xn'内存,其中n是cv::countNonZero,并且n显然将是0。我通过预先手动呼叫cv::countNonZero来规避这种情况,但我并不太喜欢这种解决方案。