How to use the label() functionality in CImg library

150 Views Asked by At

I'm looking for help on how to use the label() functionality with the CImg library. What I want to do is simple. I have a white background with big black dots separated from each other and I just want to count them. I think it's possible with label() but I don't understand the parameters of this function. Thank you for the help !

The library informations' : [1]: https://cimg.eu/reference/structcimg__library_1_1CImg.html#aaff4a10071470e4cd255653c5c2f043e

1

There are 1 best solutions below

0
Mark Setchell On

Basically, you pass it an image and it returns another image wherein each group of similar pixels is assigned to the same class, i.e. it has the same greyscale intensity. So, if we start with this:

enter image description here

And run this:

#include "CImg.h"
#include <iostream>

using namespace cimg_library;
using namespace std;

int main()
{
    // Create solid white image 
    CImg<unsigned char> img(320,240);
    img.fill(255);

    // Draw some black circles
    unsigned char black[] = {0};
    img.draw_circle(50, 50,30,black);
    img.draw_circle(130,100,50,black);
    img.draw_circle(200,200,35,black);
    img.draw_circle(280,140,30,black);
    img.save("start.png");

    // Label the connected components
    CImg<> labels = img.label(true,64);

    // Save result
    labels.save("result.png");

}

We will get this:

enter image description here

Which is very underwhelming, until we look at the histogram - I am using ImageMagick here:

identify -verbose result.png

Image:
  Filename: result.png
  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 320x240+0+0
  Units: Undefined
  Colorspace: Gray
  Type: Grayscale
  Base type: Undefined
  Endianness: Undefined
  Depth: 8-bit
  Channel depth:
    Gray: 8-bit
  Channel statistics:
    Pixels: 76800
    Gray:
      min: 0  (0)
      max: 4 (0.0156863)
      mean: 0.565234 (0.00221661)
      median: 0 (0)
      standard deviation: 1.13898 (0.00446658)
      kurtosis: 2.3448
      skewness: 1.89382
      entropy: 0.520843
  Colors: 5
  Histogram:
    59036: (0,0,0) #000000 gray(0)      <--- HERE
    2909: (1,1,1) #010101 gray(1)
    8005: (2,2,2) #020202 gray(2)
    2909: (3,3,3) #030303 gray(3)
    3941: (4,4,4) #040404 gray(4)   

And you can see there are 5 different greyscale values, corresponding to 5 components in the input image. I can also contrast-stretch the image so you can see the components, each identified with a different intensity:

magick result.png -auto-level z.png

enter image description here

The true parameter tells CImg to consider components North-East, South-East South-West and North-West of any pixel as connected. If you set this false, it only considers neighbours North, South, East and West of any pixel to be connected.

The threshold says how much a pixel may vary from others in its class while still being considered similar enough to be a neighbour - so it's a tolerance on colour matching.

Keywords: C++, CImg, image processing, labels, label, connected component analysis, blob analysis.