c# - OpenCV圆圈检测C#实现

标签 c# opencv unity3d hough-transform

我需要任何 C# 和/或 OpenCV 专家的帮助,以使我的圆检测脚本更加准确。

在 OpenCV 中,圆检测是通过称为 HoughCircles 算法或框架的东西来完成的。
http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html

我正在使用 OpenCV 的 C# 包装器(用于 Unity)
OpenCVforUnity HughCircles
这又直接基于 OpenCV 的官方 java 包装器。

我的圈子检测代码如下(当然没有OpenCv依赖) 我还附上了 2 张图片,以便您查看结果。 需要哪些改变来改善结果?我还包含了原始的 2 张图片以供引用。

using UnityEngine;
using System.Collections;
using System;
using OpenCVForUnity;


public class HoughCircleSample : MonoBehaviour{
    Point pt;
    // Use this for initialization
    void Start ()
            {
                        Texture2D imgTexture = Resources.Load ("balls2_bw") as Texture2D;

                        Mat imgMat = new Mat (imgTexture.height, imgTexture.width, CvType.CV_8UC3);

                        Utils.texture2DToMat (imgTexture, imgMat);
                        //Debug.Log ("imgMat dst ToString " + imgMat.ToString ());

                        Mat grayMat = new Mat ();
                        Imgproc.cvtColor (imgMat, grayMat, Imgproc.COLOR_RGB2GRAY);

                        Imgproc.Canny (grayMat, grayMat, 50, 200);

                         Mat circles = new Mat();    
     int minRadius = 0;
       int maxRadius = 0;

        // Apply the Hough Transform to find the circles

        Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, 3, grayMat.rows() / 8, 200, 100, minRadius, maxRadius);

       Debug.Log ("circles toString " + circles.ToString ());
        Debug.Log ("circles dump" + circles.dump ());

        if (circles.cols() > 0)
        for (int x = 0; x < Math.Min(circles.cols(), 10); x++)

        {
                double[] vCircle = circles.get(0, x);

                if (vCircle == null)
                    break;

                pt = new Point(Math.Round(vCircle[0]), Math.Round(vCircle[1]));
                int radius = (int)Math.Round(vCircle[2]);
                // draw the found circle  
                Core.circle(imgMat, pt, radius, new Scalar(255, 0, 0), 1);

            }


 Texture2D texture = new Texture2D (imgMat.cols (), imgMat.rows (), TextureFormat.RGBA32, false);
                        Utils.matToTexture2D (imgMat, texture);

                        gameObject.GetComponent<Renderer> ().material.mainTexture = texture;

                }

        }

circle detection sample 1

circle detection sample 2

enter image description here

enter image description here

最佳答案

此代码是用 C++ 编写的,但您可以轻松转换为 C#。

我需要将 HoughCircleparam2 更改为 200,导致:

HoughCircles(grayMat, circles, CV_HOUGH_GRADIENT, 3, grayMat.rows / 8, 200, 200, 0, 0);

这是

the accumulator threshold for the circle centers at the detection stage. The smaller it is, the more false circles may be detected. Circles, corresponding to the larger accumulator values, will be returned first.

您也不应该向 HoughCircles 提供“Canny-ed”图像,因为它已经处理好了。使用未应用 Canny 边缘检测步骤的 grayMat

结果如下所示。第二个更棘手,因为光照条件。

enter image description here

enter image description here

这是完整的代码。同样,它是 C++,但可用作引用。

#include <opencv2/opencv.hpp>
using namespace cv;

int main(){

    Mat3b src = imread("path_to_image");
    Mat1b src_gray;
    cvtColor(src, src_gray, CV_BGR2GRAY);

    vector<Vec3f> circles;
    HoughCircles(src_gray, circles, CV_HOUGH_GRADIENT, 3, src_gray.rows / 8, 200, 200, 0, 0);

    /// Draw the circles detected
    for (size_t i = 0; i < circles.size(); i++)
    {
        Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
        int radius = cvRound(circles[i][2]);
        // circle center
        circle(src, center, 3, Scalar(0, 255, 0), -1, 8, 0);
        // circle outline
        circle(src, center, radius, Scalar(0, 0, 255), 3, 8, 0);
    }

    imshow("src", src);
    waitKey();

    return 0;
}

关于c# - OpenCV圆圈检测C#实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31320579/

相关文章:

c# - 如何在不使用 Unity 协程的情况下在主线程上运行函数

c# - 我的 Enumerable 类不适用于 C# 中的 .where 等 Linq 语句

c# - 如何为 C# 字典中的多个键分配一个值?

python - OpenCV中的图像阈值

python-3.x - OpenCV 代码打开视频,但显示被阻止的摄像头

c# - Player Movement 使用基于相机朝向的操纵杆

c# - 使用for循环创建ID来创建怪物

c# - DataGridView 更改单元格背景颜色

c# - 如何在不将属性名称作为字符串传递的情况下引发 PropertyChanged 事件?

python - int()参数必须是字符串,类似字节的对象或数字,而不是 'NoneType'