2016-04-28 87 views
2

我一直在試圖執行形狀分析使用二進制圖像形狀分析,以從其他形狀區分矩形

的一些可能的實施例以區分從非矩形物體的矩形對象(如半圓形)

矩形

enter image description hereenter image description here

非矩形

enter image description hereenter image description here

我的算法工作如下:

  1. 使用輪廓提取物面具 - OpenCV的(你可以在上面的例子中看到)
  2. 執行形狀分析或計算統計數據以檢測對象是否爲矩形

到目前爲止,我已經嘗試了偏心和矩形度量。

例如:理想情況下,矩形只適用於矩形。在我的實驗中,我有時會得到矩形或圓形物體的類似矩形。因此,我不能使用這種方法進行分析,因爲它不可靠。

同樣的問題與偏心有關。理想情況下,一個圓的偏心率爲零,對於矩形物體,它應該非常高。但它原來是非常類似的矩形或圓形

有沒有辦法找出對象是否大致矩形或不使用任何幾何信息?

任何幫助將是非常讚賞

+0

請界定 「正常工作」, 「穩健」 和 「精確」。分析代碼是什麼樣的?你的預期結果是什麼?你現在得到的實際結果是什麼? –

+0

嗨,我已編輯的問題,並提供詳細信息 – user1388142

回答

2

我認爲你可以使用approxPolyDP。我用C++給你程序,我認爲在python中很容易翻譯。想法正在尋找具有接近實際輪廓的四個角的形狀,然後計算四個角(角角)。而輪廓點數大於4時,新輪廓與實際輪廓之間的誤差增大。 當你認爲它不是矩形時,你必須選擇一個閾值角度(90 +/- x°)。 (對不起,我英文不好)

#include "opencv2/opencv.hpp" 
#include <iostream> 

using namespace cv; 
using namespace std; 


int main(int argc, char **argv) 
{ 
vector<String> fileName; 
fileName.push_back("2nrTo.jpg"); 
fileName.push_back("G3I4t.jpg"); 
fileName.push_back("Q4ZtM.jpg"); 
fileName.push_back("vWgKx.jpg"); 
for (int i = 0; i < static_cast<int>(fileName.size()); i++) 
{ 
    Mat mThresh; 
    Mat m=imread(fileName[i],CV_LOAD_IMAGE_GRAYSCALE); 
    Mat mc; 
    vector<vector<Point> > contours; 
    vector<Vec4i> hierarchy; 
    threshold(m,mThresh,80,255,THRESH_BINARY); 
    findContours(mThresh,contours,hierarchy, cv::RETR_CCOMP, cv::CHAIN_APPROX_NONE, cv::Point(0,0)); 
    cout << "Image " << fileName[i] << "\n"; 
    imshow(fileName[i],m); 
    mc = Mat::zeros(m.size(),CV_8UC3); 
    drawContours(mc,contours,0,Scalar(255,0,0),1); 
    vector<Point> approx; 
    double d=0; 
    do 
    { 
     d=d+1; 
     approxPolyDP(contours[0],approx,d,true); 
    } 
    while (approx.size()>4); 
    cout << "#vertices =" <<approx.size() << "\t error max= " <<d<<endl; 
    if (approx.size() == 4) 
    { 
     cout << "Angles\n"; 
     Point2d u(approx[1]-approx[0]),v(approx[2]-approx[1]),w(approx[3]-approx[2]),x(approx[3]-approx[0]); 
     cout<<acos(u.dot(v)/norm(u)/norm(v))<<"\n"; 
     cout<<acos(v.dot(w)/norm(v)/norm(w))<<"\n"; 
     cout<<acos(w.dot(x)/norm(w)/norm(x))<<"\n"; 
     cout<<acos(x.dot(u)/norm(x)/norm(u))<<"\n"; 

    } 
    else 
     cout << "looks like a triangle\n"; 
    contours.push_back(approx); 
    drawContours(mc,contours,contours.size()-1,Scalar(0,0,255),1); 
    imshow("Ctr",mc); 
    waitKey(); 
} 

return 0; 
} 

與以往的圖像程序放入系統給出的結果:

Image 2nrTo.jpg 
#vertices =4  error max= 17 
Angles 
93.3283 
90.2247 
90 
93.553 
Image G3I4t.jpg 
#vertices =4  error max= 15 
Angles 
112.503 
46.3837 
110.346 
48.5412 
Image Q4ZtM.jpg 
#vertices =4  error max= 6 
Angles 
88.9191 
90.0297 
88.9488 
90 
Image vWgKx.jpg 
#vertices =4  error max= 49 
Angles 
87.0753 
117.999 
90.3148 
114.76 
+0

只是爲了澄清。角度之間的兩點計算正確?你能解釋一下邏輯嗎!謝謝 – user1388142