[英]OpenCV circle detection C# implementation
我需要任何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#。
我需要將HoughCircle
的param2
HoughCircle
為200,導致:
HoughCircles(grayMat, circles, CV_HOUGH_GRADIENT, 3, grayMat.rows / 8, 200, 200, 0, 0);
這是
圓的累加器閾值在檢測階段居中。 它越小,可能會檢測到更多的假圓圈。 與較大的累加器值相對應的圓將首先返回。
您也不應在“ HoughCircles
”中添加“ Canny-ed”圖像,因為這已經可以解決了。 使用不應用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;
}
在第四個參數中,您設置了3,但是大多數圖像的比率都接近1,這可能是一個可能的改進,還必須嘗試在參數6和7中設置另一組值,因為該值取決於Canny邊緣檢測器提取的輪廓,希望對您有所幫助。
現在,我與每個球對象有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]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.