0

I would like to implement component labeling algo for a color image.

The color distances of the four neighbors from the current pixel at (i,j) are computed and the algorithm proceeds as follows:

  1. If none of the neighbors have a color distance smaller than a predefined threshold(T), assign a new label to pixel (i,j).

  2. If only one of the neighbors has a color distance smaller than T, assign its label to pixel (i,j).

  3. (a) If two or more neighbors have color distance smaller than T, pixel at (i,j) is assigned the label of the one that has the least color distance.

    (b) The label of the pixel with least color distance is also assigned to the other neighbor pixels.

    (c) All the previously labeled pixels in the image that have the same label as that of the other neighbor pixels are re-assigned with the label of the pixel having the least color distance.

I want to implement the code in C++ using opencv library. What is the best data structure I can use to implement the above algorithm? Should I use a std::map to store the neighbor distance values?

Also, if any one condition satisfies(1-3), I need to assign the label of that corresponding pixel to the current pixel(i,j). So I also need to know which neighbor's label it is (i.e. left, top, upper left diagonal, upper right diagonal). How do I get that?

Ann
  • 186
  • 4
  • 15
  • You can just use a Mat (of integers, Mat1i) to store the label value. You don't need maps or hash tables – Miki Oct 15 '15 at 08:49
  • I know a Mat can be used to store label values. My question was not that! I asked what data structure I can use to store the neighbor distances and do the comparisons. – Ann Oct 16 '15 at 10:53
  • You can store also distance values in a Mat. If you have 8 neighbours you can make a 8 channel Mat of float. But you algorithm seems a single scan on the image to set labels, and a second scan to solve labels equivalences, I don't get why you need to store the distance at all. Just compute it for every pixel on the fly and set the label accordingly. Probably at least some pseudocode will be more informative than a numbered list – Miki Oct 16 '15 at 11:01

2 Answers2

0

A hash table would work well for this use-case:

unordered_map<srcpixel,vector<pair<targetpixel,dist> > >

So, each srcpixel would act as a key into hash table, and the value would be a vector containing it's distances from it's neighbours.

This would be quick, O(1) lookup time for each srcpixel and then a linear traversal for it's neighbours.

basav
  • 1,475
  • 12
  • 20
  • You mean srcpixel = current pixel (i,j) ? How do I do the comparisons with the neighbor distances stored in this vector> ? Could you please help as I am not much versed with C++. – Ann Oct 16 '15 at 10:50
0

To store the color distance to the 4 neighbors of each pixel, you should use an array-based datastructure, i.e. std::vector, plain C-arrays or perhaps even an opencv-image, whatever is most convenient for you to use. To store a values for a pixels of an image in a 1-dimensional array, the array is usually indexed row-wise, i.e. the index j * imageWidth + i is used to address pixel (i, j).

For example, using std::vector, you could store the values for the distance to the neighbor below like this:

std::vector<uint8_t> colorDistDown(imageWidth * (imageHeight-1));
for(int j = 0; j < imageHeight - 1; ++j) {
  for(int i = 0; i < imageWidth; ++i) {
    colorDistDown[j * imageWidth + i] = colorDistance(image, i,j, i,j+1);
  }
}

Using std::map or std::unordered_map would be much slower. However, using a map-datastructure might make sense if you'd only want to store entries for small (and non-rectangular) regions of your image.

matz
  • 626
  • 6
  • 18
  • colorDistDown(imageWidth * (imageHeight-1)) why need a vector of this size? I need to compute distance of 4 neighbors of the current pixel (i,j) in a raster scan. Also, if any one condition satisfies(1-3), I need to assign the label of that corresponding pixel to the current pixel(i,j). So I also need to know which neighbor's label it is (i.e. left, top, upper left diagonal, upper right diagonal). How do I get that? – Ann Oct 16 '15 at 11:06