【问题标题】:OpenCV circle detection C# implementationOpenCV圆检测C#实现
【发布时间】:2015-07-09 14:32:11
【问题描述】:

我需要任何 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;

                }

        }

【问题讨论】:

  • 如果 C++ 中的解决方案没问题,请上传原始图像以便我尝试。但是接下来由您决定转换为 C#
  • 看看是否符合您的预期..
  • 谢谢,但仅更改累加器阈值会产生几乎相同的结果。不过我越来越近了,请看下文。
  • 你也删除了 Canny 步骤吗?

标签: c# opencv unity3d hough-transform


【解决方案1】:

此代码使用 C++,但您可以轻松转换为 C#。

我需要将HoughCircleparam2改为200,结果是:

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

这是

检测阶段圆心的累加器阈值。它越小,可能检测到的错误圆圈就越多。将首先返回对应于较大累加器值的圆圈。

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

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

这是整个代码。同样,它是 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;
}

【讨论】:

  • 你的结果显然是正确的,你能发布你的整个代码吗?
  • @eco_bach 我刚刚尝试在图像上添加 Canny ......结果更糟。不要使用它!
  • 对不起三木。如果我必须将 c++ 版本重写为 c#,这有多复杂?我必须重写哪些类?
【解决方案2】:

在第四个参数中,您设置了 3,但大多数图像的比率接近 1,这可能是一个改进,您还必须在参数 6 和 7 中尝试另一组值,因为这值取决于canny edge detector 提取的轮廓,希望对您有所帮助。

【讨论】:

    【解决方案3】:

    我现在越来越接近每个球对象有 2 个重叠的圆圈。如果我能纠正这个问题,基本上就解决了。

    Imgproc.Canny (grayMat, grayMat, 500, 200);
    
    Mat circles = new Mat();
    int minRadius =50;
    int maxRadius = 200;
    
    Imgproc.HoughCircles(grayMat, circles, Imgproc.CV_HOUGH_GRADIENT, 1, grayMat.rows() / 4, 1000, 1, minRadius, maxRadius);![solution3][1]
    

    【讨论】:

      猜你喜欢
      • 2014-10-17
      • 2017-05-24
      • 1970-01-01
      • 1970-01-01
      • 2014-01-09
      • 2016-06-01
      • 2014-07-27
      • 2018-03-20
      • 1970-01-01
      相关资源
      最近更新 更多