2011-05-18 27 views
12

OpenCV ile uğraştım ve bir sürü deneme ve hata ile fotoğraftaki dairelerin (bozuk paraların) nasıl algılandığını öğrenmeyi başardım. Her şey harika çalışıyor, paraları doğrudan yan yana koymamın dışında (aşağıda görüldüğü gibi, 2. görüntünün baş aşağı olduğu gerçeğini göz ardı edin). OpenCV cvFindContours - bir konturun bileşenlerini nasıl ayırabilirim

Original Photo sikke cvFindContours birbirine çok yakın olduğu için görünüyor Contours Found

aynı nesne olduğunu düşünüyorum. Sorum şu: Bu konturları kendi ayrı nesnelerine nasıl ayırabilirim veya zaten ayrılmış olan konturların bir listesini alabilirim. Ben cvFindContours için kullanılan

parametreler şunlardır:

cvFindContours(img, storage, &contour, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0)); 

Herhangi bir yardım veya tavsiye

büyük takdir.

+3

image/documents/STRAWMAN/cpp/feature_detection.html # cv-houghcircles) görüntünüzdeki çevreleri algılamak için size makul sonuçlar vermelidir – etarion

cevap

13

Bu büyük değil, ama oraya nasıl gösterir: //opencv.willowgarage: Resminiz "sonra" sen dönüştürmek değiştirilmiş Hough kullanabilirsiniz (http itibaren

IplImage* src = cvLoadImage(argv[1], CV_LOAD_IMAGE_UNCHANGED); 
IplImage* gray = cvCreateImage(cvGetSize(src), IPL_DEPTH_8U, 1); 
cvCvtColor(src, gray, CV_BGR2GRAY); 
cvSmooth(gray, gray, CV_GAUSSIAN, 7, 7); 

IplImage* cc_img = cvCreateImage(cvGetSize(gray), gray->depth, 3); 
cvSetZero(cc_img); 
CvScalar(ext_color); 

cvCanny(gray, gray, 10, 30, 3); 

CvMemStorage* storage = cvCreateMemStorage(0); 
CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, src->height/6, 100, 50); 
cvCvtColor(gray, src, CV_GRAY2BGR); 
for (size_t i = 0; i < circles->total; i++) 
{ 
    // round the floats to an int 
    float* p = (float*)cvGetSeqElem(circles, i); 
    cv::Point center(cvRound(p[0]), cvRound(p[1])); 
    int radius = cvRound(p[2]); 

    // draw the circle center 
    //cvCircle(cc_img, center, 3, CV_RGB(0,255,0), -1, 8, 0); 

    // draw the circle outline 
    cvCircle(cc_img, center, radius+1, CV_RGB(0,0,255), 2, 8, 0); 

    //printf("x: %d y: %d r: %d\n", center.x, center.y, radius); 
} 

CvMemStorage *mem; 
mem = cvCreateMemStorage(0); 
CvSeq *contours = 0; 
cvCvtColor(cc_img, gray, CV_BGR2GRAY); 
// Use either this: 
int n = cvFindContours(gray, mem, &contours, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, cvPoint(0,0)); 
// Or this: 
//int n = cvFindContours(gray, mem, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); 

for (; contours != 0; contours = contours->h_next) 
{ 
    ext_color = CV_RGB(rand()&255, rand()&255, rand()&255); //randomly coloring different contours 
    cvDrawContours(cc_img, contours, ext_color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0)); 
} 

cvSaveImage("out.png", cc_img); 

enter image description here

+0

Cevabınız için teşekkürler, ilk yazıdan bahsetmediğim şey, her bir madalyonun büyüklüğünü korumak, proje, her bir madeni paranın büyüklüğüne göre hangi değeri temel aldığını belirlemek olduğu için önemlidir. Kesin bir şekilde düzeltip düzeltemeyeceğimi göreceğim. Tekrar teşekkürler – Grinneh

+0

Tamam, harika. İlginç bir cevap bulduğunuzda bunu yapabilirsiniz. Sitemizin keyfini çıkarın. – karlphillip

3

Görüntüyü eşleştirmeyi (cvThreshold) deneyebilir ve daha sonra, bozuk paraları ayırmak için oluşan ikili görüntüyü aşındırabilirsiniz (cvErode). Sonra aşınmış görüntünün konturlarını bulun.

+1

Öneri için teşekkürler, ancak görüntüyü ayrılabildiğim noktaya aşındırmayı buldum. Konturlar artık madeni paralara benzemeyen paralarla sonuçlandı. Biraz daire hassasiyetini kaybetmek tamam, fakat genel olarak mümkün olduğunca o kadar korumak istiyorum – Grinneh

+0

Evet, bu şekilde bir mikroskop görüntüsü üzerindeki hücreleri ayırmak için OpenCV kitabında da önerilmektedir. –