Reputation: 111
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 library
Upvotes: 0
Views: 128
Reputation: 51933
I do not think that it can be done by simple filter instead I would do this:
compute histogram
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]]++;
pick the most common nonzero color
cnt[]
ignoring index 0ix
is the colorreplace 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]
for(x/y...)
for the correct image boundariespixel[y][x]
for correct image pixel accessUpvotes: 1
Reputation: 111
Thanks for the response. I found a very good way to do this.
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.
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.
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);
The result is then as shown in the figure below
I hope it helps.
Upvotes: 0