Robustly find N circles with the same diameter: alternative to bruteforcing Hough transform threshold

前端 未结 3 1171
再見小時候
再見小時候 2021-02-07 08:31

I am developing application to track small animals in Petri dishes (or other circular containers). Before any tracking takes place, the first few frames are used to define areas

相关标签:
3条回答
  • 2021-02-07 08:57

    You don't explain why you are using a black background. Unless you are using a telecentric lens (which seems unlikely, given the apparent field of view), and ignoring radial distortion for the moment, the images of the dishes will be ellipses, so estimating them as circles may lead to significant errors.

    All and all, it doesn't seem to me that you are following a good approach. If the goals is simply to remove the background, so you can track the bugs inside the dishes, then your goal should be just that: find which pixels are background and mark them. The easiest way to do that is to take a picture of the background without dishes, under the same illumination and camera, and directly detect differences with the picture with the images. A colored background would be preferable to do that, with a color unlikely to appear in the dishes (e.g. green or blue velvet). So you'd have reduced the problem to bluescreening (or chroma keying), a classic technique in machine vision as applied to visual effects. Do a google search for "matte petro vlahos assumption" to find classic algorithms for solving this problem.

    0 讨论(0)
  • 2021-02-07 09:14

    Within the current algorithm, the biggest thing that sticks out is the for(int t=5; t<400; t=t+2) loop. Trying recording score values for some test images. Graph score(t) versus t. With any luck, it will either suggest a smaller range for t or be a smoothish curve with a single maximum. In the latter case you can change your loop over all t values into a smarter search using Hill Climbing methods.

    Even if it's fairly noisy, you can first loop over multiples of, say, 30, and for the best 1 or 2 of those loop over nearby multiples of 2.

    Also, in your score function, you should disqualify any results with overlapping circles and maybe penalize overly spaced out circles.

    0 讨论(0)
  • 2021-02-07 09:23

    The following approach should work pretty well for your case:

    1. Binarize your image (you might need to do this on several levels of threshold to make algorithm independent of the lighting conditions)
    2. Find contours
    3. For each contour calculate the moments
    4. Filter them by area to remove too small contours
    5. Filter contours by circularity:

      double area = moms.m00;
      double perimeter = arcLength(Mat(contours[contourIdx]), true);
      double ratio = 4 * CV_PI * area / (perimeter * perimeter);
      

      ratio close to 1 will give you circles.

    6. Calculate radius and center of each circle

      center = Point2d(moms.m10 / moms.m00, moms.m01 / moms.m00);
      

    And you can add more filters to improve the robustness.

    Actually you can find an implementation of the whole procedure in OpenCV. Look how the SimpleBlobDetector class and findCirclesGrid function are implemented.

    0 讨论(0)
提交回复
热议问题