Matlab和OpenCV为同一图像计算不同的图像矩m00 [英] Matlab and OpenCV calculate different image moment m00 for the same image

查看:283
本文介绍了Matlab和OpenCV为同一图像计算不同的图像矩m00的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于完全相同的图像

Opencv代码:

img = imread("testImg.png",0);
threshold(img, img_bw, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
Mat tmp;
img_bwR.copyTo(tmp);
findContours(tmp, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);

// Get the moment
vector<Moments> mu(contours.size() );
for( int i = 0; i < contours.size(); i++ )
 { mu[i] = moments( contours[i], false ); 

 }

// Display area (m00)
for( int i = 0; i < contours.size(); i++ )
 { 
     cout<<mu[i].m00 <<endl;
     // I also tried the code 
     //cout<<contourArea(contours.at(i))<<endl;  
     // But the result is the same
 }

Matlab代码:

Img = imread('testImg.png');
lvl = graythresh(Img);
bw = im2bw(Img,lvl);
stats = regionprops(bw,'Area');
for k = 1:length(stats)
    Area = stats(k).Area; %m00
end

有人对此有任何想法吗?如何统一它们?我认为他们使用不同的方法来找到轮廓.

Any one has any thought on it? How to unify them? I think they use different methods to find contours.

我在下面的链接上上传了测试图像,以便对此感兴趣的人可以重现该过程

I uploaded the test image at the link below so that someone who is interested in this can reproduce the procedure

这是一个100 x 100的小8位灰度图像,仅具有0和255像素强度.为简单起见,它只有一个斑点. 对于OpenCV,轮廓区域(图像力矩m00)为609.5(非常奇数值) 对于Matlab,轮廓区域(像矩m00)为763.

It is a 100 by 100 small 8 bit grayscale image with only 0 and 255 pixel intensity. For simplicity, it only has one blob on it. For OpenCV, the area of contour (image moment m00) is 609.5 (Very odd value) For Matlab, the area of contour (image moment m00) is 763.

谢谢

推荐答案

对于应如何从二进制图像中提取轮廓,存在许多不同的定义.例如,它可以是多边形,它是二进制图像中白色对象的周长.如果OpenCV使用此定义,则轮廓区域将与Matlab找到的连接组件的区域相同.但这种情况并非如此.通过findContour()函数找到的轮廓是连接相邻边缘像素"中心的多边形.边缘像素是在N4邻域中具有黑色邻居的白色像素.

Exist many different definitions of how contours should be extracted from binary image. For example it can be polygon that is the perimeter of white object in a binary image. If this definition was used by OpenCV, then areas of contours would be the same as areas of connected components found by Matlab. But this is not the case. Contour found by findContour() function is the polygon that connects centers of neighbor "edge pixels". Edge pixel is a white pixel that has black neighbor in N4 neighborhood.

示例:假设您有一幅尺寸为100x100像素的图像.对角线上方的每个像素均为黑色.对角线以下或对角线上的每个像素都是白色(黑色三角形和白色三角形).精确的分离多边形在1个像素的距离处将具有近200个顶点:(0,0),(1,0),(1,1),(2,1),(2,2),....(100 ,99),(100,100),(0,100).如您所见,从实际的角度来看,这个定义不是很好. OpenCV返回的多边形将具有3个定义三角形所需的顶点:(0,0),(99,99),(0,99).其面积为(99 x 99/2)像素.它不等于白色像素的数量.它甚至不是整数.但是这个多边形比以前的多边形更实用.

Example: suppose you have an image whose size is 100x100 pixels. Every pixel above the diagonal is black. Every pixel below or on the diagonal is white (black triangle and white triangle). Exact separation polygon will have almost 200 vertexes at distance of 1 pixel: (0,0), (1,0), (1,1), (2,1), (2,2),.... (100,99), (100,100), (0,100). As you can see this definition is not very good from practical point of view. Polygon returned by OpenCV will have exactly 3 vertexes needed to define the triangle: (0,0), (99,99), (0,99). Its area is (99 x 99 / 2) pixels. It is not equal to number of white pixels. It is not even an integer. But this polygon is more practical than previous one.

这些不是多边形提取的唯一可能定义.存在许多其他定义.其中一些(在我看来)可能比OpenCV使用的更好.但这是很多人实施和使用的.

Those are not the only possible definitions for polygon extraction. Many other definitions exist. Some of them (in my opinion) may be better than the one used by OpenCV. But this is the one that was implemented and used by a lot of people.

当前,您的问题没有有效的解决方法.如果要从MATLAB和OpenCV中获得完全相同的数字,则必须在某些黑色图像上绘制foundContours找到的轮廓,并在图像上使用moments()函数.我知道即将发布的OpenCV 3具有查找已连接组件的功能,但我自己没有尝试过.

Currently there no effective workaround for your problem. If you want to get exactly same numbers from MATLAB and OpenCV you will have to draw the contours found by foundContours on some black image, and use function moments() on image. I know that upcoming OpenCV 3 have function that finds connected components but I didn't tried it myself.

这篇关于Matlab和OpenCV为同一图像计算不同的图像矩m00的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆