3
$\begingroup$

I have thousands images similar to the following one:

enter image description here This image was produced with the following color table:

colTable = {{Black}, Table[{Blend[{Blue, Green, Yellow, Red}, x]}, {x, 1/255, 1, 1/255}]}; colTable = Flatten[colTable]; ... image = Colorize[Image[image], ColorFunction -> (Blend[colTable, #] &)] 

Now I would like to smooth this image pixel by pixel following a defined function.

The idea behind the smoothing is: I want to calculate around each pixel the number of black pixels plus the number of red pixels in a defined sourrounding rectangle (e.g. rectangle size: dx=dy=40 pixels). This number value is devided by the number of rectangle pixels and the final value determines a certain smoothed color for the corresponding pixel.

The code which I wrote is the following:

dim = ImageDimensions[image]; sx = dim[[1]]; sy = dim[[2]]; dx = 40; dy = 40; smoothImage = ConstantArray[0, {sx, sy}]; Table[ Table[ subImage = ImageTake[ image, {iy - dy/2, iy + dy/2 - 1}, {ix - dx/2, ix + dx/2 - 1}]; data = ImageData[subImage]; sumRB = Count[data, {0., 0., 0.}, Infinity] + Count[data, {1., 0., 0.}, Infinity]; smoothValues[[ix, iy]] = sumRB/(dx*dy); , {ix, dx/2 + 1, sx - dx/2 + 1} ]; , {iy, dy/2 + 1, sy - dy/2 + 1} ] max = Max[smoothValues]; smoothImage = Image[smoothValue/max]; smoothImage = Colorize[Image[smoothImage], ColorFunction -> (Blend[colTable, #] &)] 

The problem is: this code is extremely slow and lasts for hours (only for one image) ... it might also be I made somewhere a mistake ...

Is there another way (e.g. by compilation, parallel processing, cuda or any other fast routines) to solve this problem?

My expectation is to get such a smoothed image depending on the color table and the used color range (this image I have produced with IDL which takes 1 sec).

enter image description here

$\endgroup$
2
  • 1
    $\begingroup$ Why don't you process the source image (before the Colorize step) - wouldn't that make the counting easier? $\endgroup$ Commented Jul 7, 2015 at 17:29
  • $\begingroup$ could you not use ImageFilter ? also ParallelTable would be a quick way to parallelize. $\endgroup$ Commented Jul 7, 2015 at 17:37

2 Answers 2

4
$\begingroup$

As long as you're only counting/summing pixel values in a sliding window, you don't have to recalculate the whole sum for every pixel. You can just "count" red/black pixels in a "1x1 window" and then use a moving average or "box" filter to sum over neighborhoods.

First calculate two images where every red/black pixel is 1, other pixels 0:

image = Import["https://i.sstatic.net/Pgppv.png"] dx = 40; dy = 40; red = {1, 0, 0}; black = {0, 0, 0}; redPixels = Binarize[ColorNegate@ImageApply[Norm[# - red] &, image], 10^-5]; blackPixels = Binarize[ColorNegate@ImageApply[Norm[# - black] &, image], 10^-5]; 

Then apply a box filter to those images and add them:

box = BoxMatrix[Floor[{dx, dy}/2]]; ImageAdd[ImageConvolve[redPixels, box], ImageConvolve[blackPixels, box]] // ImageAdjust 

enter image description here

$\endgroup$
6
  • 1
    $\begingroup$ Norm[# - {0, 0, 0}] & is the same as plain Norm, no? $\endgroup$ Commented Jul 7, 2015 at 18:38
  • 1
    $\begingroup$ @Guesswhoitis. I wanted to make the step from Count[data, {0., 0., 0.}, Infinity] to Norm[# - {0,0,0}] more obvious. $\endgroup$ Commented Jul 8, 2015 at 6:18
  • $\begingroup$ Ah, of course; more illustrative that way. :) $\endgroup$ Commented Jul 8, 2015 at 6:26
  • $\begingroup$ @nikie: great and fast. thanks a lot. How would the code look like for a circular filter with a certain radius r? $\endgroup$ Commented Jul 8, 2015 at 9:45
  • $\begingroup$ @mrz: You would simply use DiskMatrix instead of BoxMatrix $\endgroup$ Commented Jul 8, 2015 at 9:59
1
$\begingroup$

You can use ColorReplace:

image = Import["https://i.sstatic.net/Pgppv.png"]; dx = 40; dy = 40; redblack = ColorReplace[image, {Red -> White, Black -> White, _ -> Black}]; box = BoxMatrix[Floor[{dx, dy}/2]]; ImageAdjust[ImageConvolve[redblack, box]] 

filtered image

$\endgroup$
1
  • $\begingroup$ very interesting and helpful ... thanks for the help. $\endgroup$ Commented Jul 8, 2015 at 9:50

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.