1

I'm trying to detect the circles in this image: image and then drawing such circles in another blank image using DIPlib in C++.

Following the advices of Cris Luengo I've changed the code and now looks like this:

#include <iostream>
#include <vector>
#include <diplib.h>
#include <dipviewer.h>
#include <diplib/file_io.h>
#include <diplib/display.h>
#include <diplib/color.h>
#include <diplib/linear.h>
#include <diplib/detection.h>
#include <diplib/generation.h>

using namespace std;

int main()
{
    try{
    //read image
    dip::Image img;
    dip::ImageReadTIFF(img,"circle.tif");
    dip::ColorSpaceManager csm;
    img = csm.Convert(img, "grey");

    //circle detection
    //first convert the image in binary
    dip::Image bin_img = img<128;

    //Now calculate the gradient vector of the images
    dip::Image gv=dip::Gradient(img);

    //Apply the Hough transform to find the cicles
    dip::FloatCoordinateArray circles;
    circles=dip::FindHoughCircles(bin_img,gv,{},0.0,0.2);

    //Draw circles
    dip::Image detec_img= g_img.Similar(dip::DT_UINT8);
    for(auto i: circles){
                dip::FloatArray center;
                center.push_back(i[0]);
                center.push_back(i[1]);

                dip::dfloat diameter=i[2]*2;
                dip::DrawBandlimitedBall(detec_img,diameter,center, {255}, "empty");

                center.clear();
                }
    dip::ImageWriteTIFF(detec_img, "detected.tif");

I also changed the parameters of the FindHoughCircles function because there are two concentric circles in the image so the distance between centers has to be 0.0 but the program is unable to detect it. This is the result:

This is the updated result

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • I’m not sure, I haven’t used the Hough implementation in DIPlib, but I suspect that you want to invert your input binary image. White is an object pixel, black is background. So you have a lot of object pixels that can form any number of circles. You could do for example `dip::Image bin_img = g_img == 0`, if you don’t have any compression artifacts in the grayscale image, or `dip::Image bin_img = g_img < 128` for a more robust solution. – Cris Luengo Feb 14 '22 at 01:58
  • By the way, instead of `dip::Image gv; dip::Gradient(g_img, gv);` you can do `dip::Image gv = dip::Gradient(g_img);`. – Cris Luengo Feb 14 '22 at 01:58
  • @CrisLuengo thank you for the advice. I edited the question with the new code but now there is a problem with the concentric circles as the algorithm is unable to detect it. Thank you again. – Oscar Ayala Feb 15 '22 at 11:27

1 Answers1

0

The documentation for dip::FindHoughCircles reads:

Finds circles in 2D binary images using the 2-1 Hough transform. First, circle centers are computed using dip::HoughTransformCircleCenters, and then a radius is calculated for each center. Note that only a single radius is returned per center coordinates.

That is, this function is not able to find concentric circles.

One workaround could be to run the function twice, with different limits for the circle sizes.


In DIPlib, all allocated images (either through the dip::Image constructor, though img.Forge(), through img.Similar(), etc.) are not initialized. You need to explicitly set the pixels to zero before you start drawing in it: detec_img.Fill(0). Your output image has some very nice display of previous memory use in the bottom half, I wonder what computations lead to that! :)

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120