使用OpenCV和机器学习简单的对象检测
我必须使用OpenCV编码一个对象检测器(在这种情况下,一个球)。 问题是,谷歌上的每一个search都会返回一个带有FACE DETECTION的东西。 所以我需要帮助从哪里开始,使用什么等。
一些信息:
- 球没有固定的颜色,它可能是白色的,但可能会改变。
- 我必须使用机器学习,不必是一个复杂和可靠的,build议是KNN(这是更简单和更容易)。
- 在我所有的search之后,我发现计算样本的球状图像的直方图并将其教给ML可能是有用的,但是我的主要关注点是球尺寸可以并且将会改变(距离相机越来越近)和我不知道要传递给ML来为我分类,我的意思是..我不能(或者我可以吗?)只是testing每个可能的大小的图像的每个像素(从可以说,5×5到WxH ),并希望find一个积极的结果。
- 可能会有一个不统一的背景,比如人,球后面的布等等。
- 正如我所说,我必须使用MLalgorithm,这意味着没有哈尔或Violaalgorithm。
-
另外,我想使用轮廓在Canny的图像上寻找圆,只需要find一种方法将轮廓转换为一行数据来教KNN。
那么…build议?
提前致谢。 ;)
那么,基本上你需要检测圈子 。 你见过cvHoughCircles()
吗? 你可以使用它吗?
这个页面有很多关于如何检测OpenCV的信息 。 你可能对2.5节更感兴趣。
这是我刚刚写的一个小图片,用来检测这张图片中的硬币。 希望你可以使用代码的一部分,以利于您。
input :
产出 :
// compiled with: g++ circles.cpp -o circles `pkg-config --cflags --libs opencv` #include <stdio.h> #include <cv.h> #include <highgui.h> #include <math.h> int main(int argc, char** argv) { IplImage* img = NULL; if ((img = cvLoadImage(argv[1]))== 0) { printf("cvLoadImage failed\n"); } 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); cvCanny(gray, canny, 50, 100, 3); CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, gray->height/3, 250, 100); cvCvtColor(canny, rgbcanny, 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(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0 ); // draw the circle outline cvCircle(rgbcanny, center, radius+1, CV_RGB(0,0,255), 2, 8, 0 ); printf("x: %dy: %dr: %d\n",center.x,center.y, radius); } cvNamedWindow("circles", 1); cvShowImage("circles", rgbcanny); cvSaveImage("out.png", rgbcanny); cvWaitKey(0); return 0; }
圆的检测很大程度上取决于cvHoughCircles()
的参数。 请注意,在这个演示中我也使用了Canny。