2016-01-16 137 views
2

我有一個包含一些形狀的簡單圖像:一些矩形和一些橢圓形,總數爲4或5個。形狀可以旋轉,縮放和重疊。有一個示例輸入: Sample image 我的任務是檢測所有這些數字,並準備一些有關它們的信息:大小,位置,旋轉等。在我看來,核心問題是這樣的事實,形狀可以重疊彼此。我試圖搜索關於這類問題的一些信息,並發現OpenCV庫可能非常有用。重疊形狀識別(OpenCV)

OpenCV能夠檢測輪廓,然後嘗試使橢圓或矩形適合這些輪廓。問題是當形狀被覆蓋時,輪廓被混淆。

我想到下面的算法:檢測所有的特徵點:並把白點放在它們上面。我得到了類似這樣的東西,每個圖都分爲不同的部分: enter image description here 然後我可以嘗試使用一些信息來鏈接這些部分,例如複雜度值(我將曲線approxPolyDP擬合到輪廓並讀取它的多少部分具有)。但它開始變得非常困難。另一個想法是嘗試所有連接輪廓並試圖使數字適合它們的排列組合。最佳編譯將輸出。

任何想法如何創建簡單而優雅的解決方案?

+0

你如何找到結合點?我認爲如下所示的模糊不是基於某種數學屬性,而是基於它自己的嘗試 - 如果你能找到交點,那麼它就成爲一個圖形問題。每個傳入段都會有可能的輸出段,並基於曲率進行匹配。但你如何檢測交點? – gpasch

+0

我嘗試了很多方法來找到角落,並發現'goodFeaturesToTrack'在這種情況下效果最好。 Disadventage是它不僅檢測路口,還檢測矩形的核心。 在我看來,僅檢測連接點的能力只是算法。 –

+0

如果它檢測到矩形拐角就好 - 你必須將一個線段與一個線段配對 - 如果goodFeaturesToTrack找到所有突出顯示的點,那麼它就是你需要的 – gpasch

回答

0

模糊圖像有助於找到交叉口的代碼所示

#include "opencv2/imgproc.hpp" 
#include "opencv2/highgui.hpp" 

using namespace cv; 

int main(int argc, char** argv) 
{ 
    Mat src = imread(argv[1]); 
    Mat gray, blurred; 
    cvtColor(src, gray, COLOR_BGR2GRAY); 
    threshold(gray, gray, 127, 255, THRESH_BINARY); 
    GaussianBlur(gray, blurred, Size(), 9); 
    threshold(blurred, blurred, 200, 255, THRESH_BINARY_INV); 
    gray.setTo(255, blurred); 
    imshow("result",gray); 
    waitKey(); 

    return 0; 
} 

結果圖像:enter image description here

第2步

簡單地說,從generalContours_demo2.cpp

#include "opencv2/imgproc.hpp" 
#include "opencv2/highgui.hpp" 

using namespace cv; 
using namespace std; 

int main(int argc, char** argv) 
{ 
    Mat src = imread(argv[1]); 
    Mat gray, blurred; 
    cvtColor(src, gray, COLOR_BGR2GRAY); 
    threshold(gray, gray, 127, 255, THRESH_BINARY); 
    GaussianBlur(gray, blurred, Size(), 5); 
    threshold(blurred, blurred, 180, 255, THRESH_BINARY_INV); 
    gray.setTo(255, blurred); 
    imshow("result of step 1",gray); 

    vector<vector<Point> > contours; 

    /// Find contours 
    findContours(gray.clone(), contours, RETR_TREE, CHAIN_APPROX_SIMPLE); 

    /// Find the rotated rectangles and ellipses for each contour 
    vector<RotatedRect> minRect(contours.size()); 
    vector<RotatedRect> minEllipse(contours.size()); 

    for(size_t i = 0; i < contours.size(); i++) 
    { 
     minRect[i] = minAreaRect(Mat(contours[i])); 
     if(contours[i].size() > 5) 
     { 
      minEllipse[i] = fitEllipse(Mat(contours[i])); 
     } 
    } 

    /// Draw contours + rotated rects + ellipses 
    for(size_t i = 0; i< contours.size(); i++) 
    { 
     Mat drawing = src.clone(); 
     // contour 
     //drawContours(drawing, contours, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point()); 
     // ellipse 
     ellipse(drawing, minEllipse[i], Scalar(0, 0, 255), 2); 
     // rotated rectangle 
     Point2f rect_points[4]; 
     minRect[i].points(rect_points); 
     for(int j = 0; j < 4; j++) 
      line(drawing, rect_points[j], rect_points[(j+1)%4], Scalar(0, 255, 0), 2); 
     /// Show in a window 
     imshow("results of step 2", drawing); 
     waitKey(); 
    } 

    return 0; 
} 

你借碼可以得到以下結果圖像等等。我希望你能解決最後一步。 enter image description here enter image description here enter image description here enter image description here

+0

謝謝你,我會試着分析你的解決方案,它似乎是非常簡單直接的反對我的想法。 –

+1

我希望它能幫助你。你可以嘗試改變'GaussianBlur'和'threshold'的參數(看看我如何改變第一和第二代碼) – sturkmen