Umair
Umair

Reputation: 111

Special ImageFilter

Please have a look at the image attached. It's a small part of a matrix generated by reading in a larger 16bit image. I want to devise a filter so that all the non-zero values get the value of the most frequent number I was thinking to use a modal filter which will pick the mode(most frequent number in a kernel overlap) but it won't work for the non-zero numbers at the edges because then 0 would be the mode. Any ideas? It would be better if I find such a filter in Emgu CV libraryShowing only 8x7 pixels of a larger image

Upvotes: 0

Views: 128

Answers (2)

Spektre
Spektre

Reputation: 51933

I do not think that it can be done by simple filter instead I would do this:

  1. compute histogram

    • create and set to zero integer counter per each possible color
    • loop through all pixels (x,y) and increment used color counter

      int i,x,y,cnt[65536];
      for (i=0;i<65536;i++) cnt[i]=0;
      for(y...)
       for(x...)
        cnt[pixel[y][x]]++;
      
  2. pick the most common nonzero color

    • just find max number in cnt[] ignoring index 0
    • found index ix is the color
  3. replace non-zero pixels with that color

    • just replace each zero pixel

      for(y...)
       for(x...)
        if (pixel[y][x]!=0)
         pixel[y][x]=ix;
      

[notes]

  • pseudo code is in C++
  • change the for(x/y...) for the correct image boundaries
  • change pixel[y][x] for correct image pixel access

Upvotes: 1

Umair
Umair

Reputation: 111

Thanks for the response. I found a very good way to do this.

  1. Take a mask m out of the original Image object 'img'. The mask m tells us which pixels are zeros and which are non-zeros.

  2. Dilate the image object by imgNew = img.Dilate(1) in emgu CV. The dilate function dilates the pixels by spreading the maximum value in the original image which overlaps with the dilate kernel. In the case above, the value 1056 replaces other smaller values such 304, 320, 272 etc. These values are spread further away from the center.

  3. Since we now have more non-zero pixels due to dilation. One can multiply the imgNew with the mask m through the command cvInvoke.cvMul(imgNew.Ptr, mask.Ptr, imgNew.Ptr, 1);

  4. The result is then as shown in the figure below enter image description here

I hope it helps.

Upvotes: 0

Related Questions