2012-05-18 2 views
2

Я использую cvHoughCircles найти два белых овалов в следующем изображении:OpenCV: Ошибка при использовании cvHoughCircles

enter image description here

я впервые использовал пороговая для обнаружения белых областей, а затем использовали преобразование хафа. Но выход не подходит правильно, как показано ниже:

enter image description here

Я не в состоянии понять, что происходит? Почему он обнаруживает 3 круга и почему только один обнаружен правильно? Какие-либо предложения?

Ниже мой код:

#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/imgproc/imgproc.hpp" 
#include <iostream> 
#include <stdio.h> 
#include <math.h> 
#include <ctype.h> 
#include <stdlib.h> 
#include "opencv/cv.h" 
#include "opencv/highgui.h" 
#include<conio.h> 
#include<malloc.h> 



using namespace cv; 
using namespace std; 
int main() { 
IplImage* image = cvLoadImage( 
"testing.bmp", 
    CV_LOAD_IMAGE_GRAYSCALE 
); 

IplImage* src = cvLoadImage("testing.bmp"); 
CvMemStorage* storage = cvCreateMemStorage(0); 


cvThreshold(src, src, 200, 255, CV_THRESH_BINARY); 

CvSeq* results = cvHoughCircles( 
image, 
storage, 
CV_HOUGH_GRADIENT, 
3, 
image->width/10 
); 

for(int i = 0; i < results->total; i++) 
{ 
float* p = (float*) cvGetSeqElem(results, i); 
CvPoint pt = cvPoint(cvRound(p[0]), cvRound(p[1])); 
cvCircle( 
    src, 
    pt, 
    cvRound(p[2]), 
    CV_RGB(0xff,0,0) 
); 
} 
cvNamedWindow("HoughCircles", 1); 
cvShowImage("HoughCircles", src); 
cvWaitKey(0); 
} 

Edit:

Поскольку я не получаю удовлетворительные результаты с преобразования Хока, я готов пойти на какой-то другой способ. Я могу предположить, что каждая белая блоба на рисунке имеет одинаковый размер (размер известен), а также известно расстояние между блобом. Есть ли нетривиальный способ найти вертикальную линию (касательную), касающуюся левой части левой белой капли? Как только я узнаю эту касательную, я получу представление о граничном расположении, затем нарисую круг в точке x = (это местоположение + радиус (который известен)), y = это местоположение. Могу ли я найти такие координаты x и y, используя некоторые нетривиальные способы?

решаемые путем изменения согласно ниже:

cvThreshold(image, image, 220, 255, CV_THRESH_BINARY); 

cvCanny(image, image, 255, 255, 3); 


cvNamedWindow("edge", 1); 
cvShowImage("edge", image); 
cvWaitKey(0); 

CvMemStorage* storage = cvCreateMemStorage(0); 
CvSeq* results = cvHoughCircles( 
      image, 
      storage, 
      CV_HOUGH_GRADIENT, 
      4, 
      image->width/4, 100,100,0,50); 

Вот результат:

enter image description here

+1

Возможно, я не знаком с OpenCv, но разве вы не должны использовать краевое изображение, а не пороговое значение как вход для алгоритма Hough? –

+0

с использованием обнаружения края канны, за которым следовал Hough Transformed! Но когда я беру другое изображение, больше нет. из белых капель, то же самое не удалось. – gpuguy

+0

@ Андрей, как вы думаете, для определения овальной формы необходимо использовать ту же процедуру? (Потому что в моем случае на самом деле фигуры овальные, а не круговые) – gpuguy

ответ

2

Вы должны использовать края обнаружены изображения в качестве входных данных, а не пороговую. Во-вторых, круги Hough не будут работать для elipses, если они не очень близки к кругам. Я рекомендую прочитать около Generalized Hough Transform и реализовать его для эллипсов.

+0

Thershoding следует делать, а затем резать, а затем преобразовывать. В моем случае для изображений с почти круглой формой растворы работали, но овальной формы не было. Таким образом, я думаю, что преобразование Хрустальное Хед может быть лучшим решением. Приложение в руке на самом деле намного проще, поскольку я знаю размер и многие другие параметры белых капель, поэтому в моем случае может быть и некоторый тривиальный метод. – gpuguy

3

It's all aboutthe parameters:

IplImage* src = cvLoadImage(argv[1]); 
if (!src) 
{ 
    cout << "Failed: unable to load image " << argv[1] << endl; 
    return -1; 
} 

//IplImage* image = cvLoadImage(argv[1], CV_LOAD_IMAGE_GRAYSCALE); 
IplImage* image = cvCreateImage(cvSize(src->width, src->height), IPL_DEPTH_8U, 1); 
cvCvtColor(src, image, CV_RGB2GRAY); 

cvThreshold(image, image, 220, 255, CV_THRESH_BINARY); 
// cvNamedWindow("thres", 1); 
// cvShowImage("thres", image); 
// cvWaitKey(0); 

CvMemStorage* storage = cvCreateMemStorage(0); 
CvSeq* results = cvHoughCircles( 
       image, 
       storage, 
       CV_HOUGH_GRADIENT, 
       4, 
       image->width/3); 

std::cout << "> " << results->total << std::endl; 

for(int i = 0; i < results->total; i++) 
{ 
    float* p = (float*) cvGetSeqElem(results, i); 
    CvPoint pt = cvPoint(cvRound(p[0]), cvRound(p[1])); 
    cvCircle(src, 
      pt, 
      cvRound(p[2]), 
      CV_RGB(0xff,0,0)); 
} 

cvNamedWindow("HoughCircles", 1); 
cvShowImage("HoughCircles", src); 
cvWaitKey(0); 

Если вы «Ве сделал немного больше экспериментов вы бы в конечном итоге выяснилось, что with different parameters you get different results:

+0

Попытался изо всех сил, использовал ваши и эти параметры: CvSeq * results = cvHoughCircles ( image, storage, CV_HOUGH_GRADIENT, 2,1); Но не работает, не обнаружен круг, return> 0 – gpuguy

+0

. Вышеприведенный код предоставил изображение, которое я поделил. Я использовал OpenCV 2.3.1. Я предлагаю вам проверить это на другой машине. – karlphillip

+0

У меня есть библиотеки, такие как opencv_core240.lib, значит, у меня есть opencv 2.4. Ваши значения 4, image-> width/3 соответствуют «dp = 1: обратное отношение разрешения» и «Минимальное расстояние между обнаруженными центрами». Правильно ли я? – gpuguy

Смежные вопросы