簡體   English   中英

Matlab和OpenCV為同一圖像計算不同的圖像矩m00

[英]Matlab and OpenCV calculate different image moment m00 for the same image

對於完全相同的圖像

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

有人有任何想法嗎? 如何統一他們? 我認為他們使用不同的方法來尋找輪廓。

我在下面的鏈接上傳了測試圖像,以便對此感興趣的人可以重現該過程

它是一個100 x 100的小8位灰度圖像,只有0和255像素強度。 為簡單起見,它只有一個blob。 對於OpenCV,輪廓區域(圖像力矩m00)為609.5(非常奇數值)對於Matlab,輪廓區域(圖像力矩m00)為763。

謝謝

存在關於如何從二值圖像中提取輪廓的許多不同定義。 例如,它可以是多邊形,它是二進制圖像中白色對象的周長。 如果OpenCV使用此定義,則輪廓區域將與Matlab找到的連接組件區域相同。 但這種情況並非如此。 findContour()函數找到的輪廓是連接相鄰“邊緣像素”中心的多邊形。 邊緣像素是在N4鄰域中具有黑色鄰居的白色像素。

示例:假設您有一個大小為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)像素。 它不等於白色像素的數量。 它甚至不是整數。 但是這個多邊形比以前的多邊形更實用。

這些不是多邊形提取的唯一可能定義。 存在許多其他定義。 其中一些(在我看來)可能比OpenCV使用的更好。 但這是許多人實施和使用的。

目前沒有針對您的問題的有效解決方法。 如果你想從MATLAB和OpenCV獲得完全相同的數字,你必須在一些黑色圖像上繪制由foundContours找到的輪廓,並在圖像上使用函數moment()。 我知道即將推出的OpenCV 3具有查找連接組件的功能,但我自己沒有嘗試過。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM