2017-12-21 3 views
1

Ich versuche, alle Kreise in einem Bild zu identifizieren. Nach dem Erhöhen des Kontrasts, benutze den Schwellenwert, benutze schlaue Kanten Ich finde alle Konturen und durchlaufe sie, wobei immer Fläche> 0 im Ergebnisbild vorhanden ist. Die Ergebnisse sind nicht gut. Bitte helfen ...Konturbereich zeigt nicht alle relevanten Bereiche

#include <opencv2/opencv.hpp> 

using namespace cv; 
using namespace std; 
void changeGain(cv::Mat&,double,int); 


int main(int argc, char** argv) 
{ 

// Load the original image and make a duplication 
cv::Mat rawImage = cv::imread("..\\3.png"); 
cv::Mat duplicateImage= rawImage.clone(); 

// Add contrast 
changeGain(duplicateImage,1.9 ,-240); 


// Apply thershold 
cv::threshold(duplicateImage, duplicateImage, 150, 200, cv::THRESH_BINARY); 


// Use canny edges 
cv::Mat img_canny; 
cv::Canny(duplicateImage,img_canny,150,200); 

// Find all the contours from the canny image 
vector<vector<cv::Point>> contours; 
findContours(img_canny, contours, RETR_TREE, CHAIN_APPROX_SIMPLE); 

// Approximate contours to polygons + get circles 
vector<vector<Point> > contours_poly; 

for(int i = 0; i < contours.size(); i++) 
{ 
    double area = contourArea(contours[i],true); 
    if (area > 0) 
     contours_poly.push_back(contours[i]); 
} 

// Draw the circles on the image 
drawContours(rawImage, contours_poly, -1, Scalar(rand() & 255, rand() & 255, rand() & 255)); 

// Show result 
cv::imshow("Final Result", rawImage); 
cv::waitKey(0); 
imwrite("..\\contour_result.jpg",rawImage); 

} 

void changeGain(cv::Mat& image,double alpha, int beta) 
{ 
//cv::Mat new_image = cv::Mat::zeros(image.size(), image.type()); 

/// Do the operation new_image(i,j) = alpha*image(i,j) + beta 
for(int y = 0; y < image.rows; y++) 
{ 
    for(int x = 0; x < image.cols; x++) 
    { 
     for(int c = 0; c < 3; c++) 
      image.at<cv::Vec3b>(y,x)[c] = 
        cv::saturate_cast<uchar>(alpha*(image.at<cv::Vec3b>(y,x)[c]) + beta); 

    } 
} 

return; 

}

Dies ist das Originalbild

This is the original image

Dies ist das Ergebnis, wenn alle Konturen zeigt

This is the result when showing all contours

Dies ist das Ergebnis wh en mit einer Fläche nur Konturen zeigen> 0

This is the result when showing only contours with area >0

Ein Bild nach thershold

An image after thershold

Image after canny

+0

Gibt es eine Chance, dass Sie einen Verweis auf das Schwellenwertbild speichern könnten? Das wäre am hilfreichsten für das Debuggen –

+0

Das Bild nach dem ursprünglichen Post hinzugefügt. @PatrickRoberts –

+0

Wenn Sie den Schwellenwert betrachten, scheint es, dass Blobs mit hervorstehenden Kanten dazu führen, dass Ihre Konturen die Schleife nicht vollständig schließen. Siehst du das? –

Antwort

0

Zunächst betrachten Morphologie (https://docs.opencv.org/trunk/d9/d61/tutorial_py_morphological_ops.html), um mit dann aufzuräumen schwellen Bild. Wenn Sie etwas wie Öffnen und Schließen verwenden, werden Rauschen und Lücken im Schwellenwertbild entfernt.

Zweitens müssen Sie keine Canny-Kanten erkennen. Sie können die Konturen aus dem Schwellwert extrahieren, einfach, das ist es, was ich für mein aktuelles Projekt mache.

Drittens, ich nehme an, Sie suchen nach Kreisen, in diesem Fall können Sie minEnclosingCircle (https://docs.opencv.org/3.3.1/d3/dc0/group__imgproc__shape.html#ga8ce13c24081bbc7151e9326f412190f1) verwenden. Da die Form ein Kreis ist, sollte sie nur den Kreis einschließen, etwas, das Sie durch den Vergleich der contourArea einer Kontur und der Fläche eines Kreises mit dem Radius minEnclosingCircle ermitteln konnten. Wenn Ihre Kontur tatsächlich ein Kreis ist, sollte dieses Verhältnis nahe bei 1 liegen. (Dies ist auch eine Technik, die ich derzeit verwende).

+0

Danke, Oscar. Ich werde versuchen zu sehen, wie es geht –

Verwandte Themen