检测台球与OpenCV的 [英] Detecting billiard balls with OpenCV

查看:346
本文介绍了检测台球与OpenCV的的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做一个Android应用程序,它取一个台球游戏的图像进行中,检测出不同的球的位置。该图像是从别人的电话,所以我当然没有表的完美的俯视图。现在,我使用houghcircles找到了球,而且它做一个好工作,但它似乎在这里和那里错过了几个球,然后有误报。

我的最大的问题,现在的问题是,我该如何减少误报发现外面的桌子?我使用的是投资回报率,以切断图像的顶部,因为它主要是浪费的空间,但我不能让任何小的或我就有可能切断表的一部分,因为它是一个梯形形状。我现在的想法是覆盖承担图像的顶部的照片时,用户可以看到的指导,但是,问题是,我不知道自己的照相机的分辨率将是,因此覆盖可能包括错了点。理想情况下,我想我会想使用houghlines但是当我试了一下我的应用程序从我相信这是一个缺少内存崩溃。任何想法?

下面是一个链接,结果我得到:

http://graphiquest.com/cvhoughcircles.html

下面是我的code:

 的IplImage IMG = cvLoadImage(/ SD卡/ DCIM /测试/图片+ I +JPG,1);
    IplImage的灰= opencv_core.cvCreateImage(opencv_core.cvSize(img.width(),img.height()),opencv_core.IPL_DEPTH_8U,1);

    cvCvtColor(IMG,灰色,opencv_imgproc.CV_RGB2GRAY);
    。cvSetImageROI(灰色,cvRect(0,(int)的(img.height()* 15),(int)的img.width(),(int)的(img.height() - (img.height()* 20 ))));


    cvSmooth(灰色,灰色,opencv_imgproc.CV_GAUSSIAN,9,9,2,2);

    指针圈= CvMemStorage.create();
    CvSeq序列= cvHoughCircles(灰色,圆形,CV_HOUGH_GRADIENT,2.5D,(双)gray.height()/ 30,70D,100D,0,80);

    对于(INT J = 0; J< seq.total(); J ++){
        CvPoint3D32f点=新CvPoint3D32f(cvGetSeqElem(SEQ,J));

        浮XYR [] = {point.x(),point.y(),point.z()};
        CvPoint中心=新CvPoint(Math.round(XYR [0]),Math.round(XYR [1]));

        INT半径= Math.round(XYR [2]);
        cvCircle(灰色,中心,3个,CvScalar.GREEN,-1,8,0);
        cvCircle(灰色,圆心,半径,CvScalar.BLUE,3,8,0);
    }
    字符串路径=/ SD卡/ DCIM /测试/;
    档案照片=新的文件(路径,图片报+ I +_ 2.JPG);

    如果(photo.exists())
    {
        photo.delete();
    }
   cvSaveImage(/ SD卡/ DCIM /测试/图片+ I +_ 2.JPG,灰色);
 

解决方案

有一些非常有帮助的限制,你可以申请。除了做感兴趣的矩形区域,您应该掩盖你的结果与台球桌的实际梯形形状。使用的图像的颜色信息来找到池表区域。你知道,台球桌是纯色。这并不一定是绿色的 - 你可以使用一些直方图技术在HSV颜色空间中寻找图像中的最prevalent色彩,也许有利于向中心像素​​。这是非常有可能以检测池表的颜色。选择像素匹配这种颜色,执行形态运算以消除噪声,然后就可以把面膜作为一个轮廓,并找到它的凸形轮廓。填船体以去除由球池形成的孔。

我说什么,到目前为止应该提出一个不同的方法比霍夫圆。霍夫界恐怕不是工作太清楚,因为台球不是均匀照亮。因此,另一种方式来找到台球是从它的凸形轮廓减去台球桌颜色的面具。你会离开与被遮蔽的球桌上的领域。

I'm making an android app that takes an image of a billiards game in progress and detects the positions of the various balls. The image is taken from someone's phone, so of course I don't have a perfect overhead view of the table. Right now I'm using houghcircles to find the balls, and it's doing an ok job, but it seems to miss a few balls here and there, and then there are the false positives.

My biggest problem right now is, how do I cut down on the false positives found outside the table? I'm using an ROI to cut off the top portion of the image because it's mostly wasted space, but I can't make it any smaller or I risk cutting off portions of the table since it's a trapezoidal shape. My current idea is to overlay the guide that the user sees when taking the picture on top of the image, but the problem with that is that I don't know what the resolution of the their cameras would be, and therefore the overlay might cover up the wrong spots. Ideally I think I would want to use houghlines but when I tried it my app crashed from what I believe was a lack of memory. Any ideas?

Here is a link to the results I'm getting:

http://graphiquest.com/cvhoughcircles.html

Here is my code:

    IplImage img = cvLoadImage("/sdcard/DCIM/test/picture"+i+".jpg",1);
    IplImage gray = opencv_core.cvCreateImage( opencv_core.cvSize( img.width(), img.height() ), opencv_core.IPL_DEPTH_8U, 1);

    cvCvtColor(img, gray, opencv_imgproc.CV_RGB2GRAY );
    cvSetImageROI(gray, cvRect(0, (int)(img.height()*.15), (int)img.width(), (int)(img.height()-(img.height()*.20))));


    cvSmooth(gray,gray,opencv_imgproc.CV_GAUSSIAN,9,9,2,2);

    Pointer circles = CvMemStorage.create();        
    CvSeq seq = cvHoughCircles(gray, circles, CV_HOUGH_GRADIENT, 2.5d, (double)gray.height()/30, 70d, 100d, 0, 80);

    for(int j=0; j<seq.total(); j++){
        CvPoint3D32f point = new CvPoint3D32f(cvGetSeqElem(seq, j));

        float xyr[] = {point.x(),point.y(),point.z()};
        CvPoint center = new CvPoint(Math.round(xyr[0]), Math.round(xyr[1]));

        int radius = Math.round(xyr[2]);
        cvCircle(gray, center, 3, CvScalar.GREEN, -1, 8, 0);
        cvCircle(gray, center, radius, CvScalar.BLUE, 3, 8, 0);
    }
    String path = "/sdcard/DCIM/test/";
    File photo=new File(path, "picture"+i+"_2.jpg");

    if (photo.exists()) 
    {
        photo.delete();
    }
   cvSaveImage("/sdcard/DCIM/test/picture"+i+"_2.jpg", gray);

解决方案

There are some very helpful constraints you could apply. In addition to doing a rectangular region of interest, you should mask your results with the actual trapezoidal shape of the pool table. Use the color information of the image to find the pool table region. You know that the pool table is a solid color. It doesn't have to be green - you can use some histogram techniques in HSV color space to find the most prevalent color in the image, perhaps favoring pixels toward the center. It's very likely to detect the color of the pool table. Select pixels matching this color, perform morphological operations to remove noise, and then you can treat the mask as a contour, and find its convexHull. Fill the hull to remove the holes created by the pool balls.

What I've said so far should suggest a different approach than Hough circles. Hough circles is probably not working too well since the billiard balls are not evenly illuminated. So, another way to find billiard balls is to subtract the pool table color mask from its convexHull. You'll be left with the areas of the table that are obscured by balls.

这篇关于检测台球与OpenCV的的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆