Friday 2 January 2015

Pendeteksian Lingkaran Menggunakan OpenCV dan C++

Advertisement

Pada kesempatan kali ini, saya ingin berbagi bagaimana caranya mendeteksi lingkaran dalam suatu citra menggunakan OpenCV dan C++. Dalam library OpenCV, kita sudah disediakan fungsi cvHoughCircles() untuk melakukan ini.

#include <iostream>
#include <cv.h>
#include <highgui.h>
#include <math.h>

using namespace std;
using namespace cv;

int main()
{
IplImage* img = cvLoadImage("img.jpg", CV_LOAD_IMAGE_UNCHANGED);
IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
CvMemStorage* storage = cvCreateMemStorage(0);

cvCvtColor(img,gray, CV_BGR2GRAY);

// This is done so as to prevent a lot of false circles from being detected
cvSmooth(gray, gray, CV_GAUSSIAN, 7, 7);

IplImage *canny = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1);
IplImage *rgbcanny = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 3);

//Lakukan edge detection menggunakan algoritma Canny
cvCanny(gray, canny,50,100,3);

//Lakukan pencarian lingkaran menggunakan algoritma Hough
//Parameter
//gray : gambar grayscale dimana ingin dicari lingkaran-lingkarannya
//storage : memory storage tempat menyimpan hasil pencarian
//CV_HOUGH_GRADIENT: metode pencarian lingkaran. Untuk saat ini baru ada metode ini di OpenCV
//1 : Inverse ratio dari resolusi
//70 : jarak piksel minimum antar lingkaran yang terdeteksi, semakin pendek bisa semakin banyak lingkaran yang terdeteksi (tergantung pada gambarnya)
//250 : upper threshold untuk algoritma Canny
//100 : threshold untuk deteksi titik pusat lingkaran
//0 : Radius lingkaran minimum untuk dideteksi, jika tidak diketahui, beri nilai 0 saja
//0 : Radius lingkaran maksimum untuk dideteksi, jika tidak diketahui, beri nilai 0 saja
//==================================================================================================
//Referensi: http://docs.adaptive-vision.com/4.1/studio/filters/FeatureDetection/cvHoughCircles.html
//==================================================================================================
CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, 70, 250, 100,0,0);

//Konversi ke nilai RGB
cvCvtColor(canny, rgbcanny, CV_GRAY2BGR);

//Untuk tiap lingkaran yang terdeteksi...
for(size_t i=0;i<circles->total;i++) {
//Ambil lingkaran ke-i yang terdeteksi. Hasilnya berupa suatu sekuens dengan urutan koordinat x dan y lingkaran, kemudian radius lingkaran
float* p = (float*)cvGetSeqElem(circles,i);
//Ambil koordinat x(p[0]) dan y(p[1])
cv::Point center(cvRound(p[0]), cvRound(p[1]));
int radius = cvRound(p[2]);

// gambarkan pusat lingkaran
cvCircle(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0 );

// gambarkan lingkaran
cvCircle(rgbcanny, center, radius+1, CV_RGB(0,0,255), 2, 8, 0 );

//cetak informasi ttg lingkaran (koordinat x dan y serta radius)
printf("x: %d y: %d r: %d\n",center.x,center.y, radius);
}

cvNamedWindow("input", 1);
cvShowImage("input", img);

cvNamedWindow("circles", 1);
cvShowImage("circles", rgbcanny);

cvWaitKey(0);

return 0;
}


Berikut ini hasilnya:

Hasil cvHoughCircles
Hasil cvHoughCircles

Sumber





EmoticonEmoticon