i need c# , or opencv experts in making circle detection script more accurate.
in opencv circle detection accomplished called houghcircles algorithm or framework.
http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_circle/hough_circle.html
i using c# wrapper of opencv (for unity)
opencvforunity hughcircles
in turn directly based on official java wrapper of opencv.
my circle detection code follows (without opencv dependencies of course) i've attached 2 images can see results. changes needed improve results? i've included original 2 images reference.
using unityengine; using system.collections; using system; using opencvforunity; public class houghcirclesample : monobehaviour{ point pt; // use initialization void start () { texture2d imgtexture = resources.load ("balls2_bw") 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 hough transform find 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) (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 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; } } 



this code in c++, can convert c#.
i needed change param2 of houghcircle 200, resulting in:
houghcircles(graymat, circles, cv_hough_gradient, 3, graymat.rows / 8, 200, 200, 0, 0); which is
the accumulator threshold circle centers @ detection stage. smaller is, more false circles may detected. circles, corresponding larger accumulator values, returned first.
you should't feed houghcircles "canny-ed" image, since take care of this. use graymat without canny edge detection step applied.
results shown below. second 1 more tricky, because of light conditions.


here whole code. again, it's c++, may useful reference.
#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 circles detected (size_t = 0; < 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; }
Comments
Post a Comment