Greyscale + gaussian

Questions and postings pertaining to the usage of ImageMagick regardless of the interface. This includes the command-line utilities, as well as the C and C++ APIs. Usage questions are like "How do I use ImageMagick to create drop shadows?".
Freeloader
Posts: 8
Joined: 2011-07-24T14:10:19-07:00
Authentication code: 8675308

Greyscale + gaussian

Post by Freeloader »

Hey guys,

I'm looking to have a nip2 routine switched over to another image lib. I'd like to switch over to ImageMagick, since this prog seems easier to implement server-side and somewhat faster as well. With this being my first confrontation with ImageMagick, I'd like to as you guys for some help. I've been all over the docs and searched this forums/google all I could. Eventually, I'm still stuck on some parts. Hopefully you can help me out.

I'm implementing this script server side inside a php class.

These are the implementations I need:

* convert from 1 bit to 8 bit greyscale
* gaussian filter with radius 20
* rescale the gray levels (x3 or autolevel)
* threshold at 40 -> revert to binary image
* do a 5px cropping of the edges

This is what I have so far:

Code: Select all

exec("convert input.png -evaluate multiply 16 -depth 8 -gaussian-blur 20 -white-threshold 40 output.png");
The 'evaluate multiply 16 -depth8' method is something I found in a forum thread in here. Not sure if it applies to what I'm trying to do. It's the only part that seems to work though. When I run that command line, it errors (produces no output). When I remove the blur and the threshold, it gives me an output, but not quite what I was expecting. It seems the gaussian blur is causing the error. Am I using the wrong syntax? Any help is welcome, thanks :-)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Greyscale + gaussian

Post by fmw42 »

exec("convert input.png -evaluate multiply 16 -depth 8 -gaussian-blur 20 -white-threshold 40 output.png");
IM does not need to change from 1-bit to 8-bit, explicitly, as far as I know. It will handle it. That is unless you have a value of 0,1 in a range of 0-65535. Then you need to auto-stretch the values. If it is already full black and full white, then IM will treat is as 0 and 65535 (i.e. keep it full black and full white).

I don't understand the use of -evaluate multiply 16, unless your 16-bit data has a range that is 1/16 of full dynamic range. If not, then it will cause your data to overflow full white. If you want to auto stretch the data to full dynamic range, you can use -auto-level (if on a relatively current version of IM). -gaussian-blur 20 should probably be replaced with radiusxsigma or 0xsigma. typically sigma will be about radius/3 if left out or radius=3sigma if radius=0 for any given sigma. see http://www.imagemagick.org/script/comma ... ssian-blur. However, you can speed it up dramatically by using -blur. See http://www.imagemagick.org/script/comma ... s.php#blur. -white-threshold 40 is going to threshold at 40 out of 65535. You would be better using a meaningful percent threshold -white-threshold 40%. Note -white-threshold will not make your image binary. For that you need to use -threshold. IM will use values in your quantum range for compile Q16 (0-65535) even though you tell the output to be -depth 8. To remove 5-pixels all around use -shave 5x5.

Try

exec("convert input.png -auto-level -blur 20 -auto-level -white-threshold 40% -shave 5x5 -depth 8 output.png 2>&1",$out,$returnval);
print_r($out[0]);

or

exec("convert input.png -auto-level -blur 0x6.7 -auto-level -white-threshold 40% -shave 5x5 -depth 8 output.png 2>&1",$out,$returnval);
print_r($out[0]);

and see what messages are returned.

What version of IM are you using?

Try

<?php
exec("/usr/local/bin/convert -version",$out,$returnval);
print_r($out[0]);
?>

or

<?php
exec("/usr/bin/convert -version",$out,$returnval);
print_r($out[0]);
?>

or to find the path to convert, try

<?php
exec("type -a convert",$out,$returnval);
print_r($out[0]);
?>
Freeloader
Posts: 8
Joined: 2011-07-24T14:10:19-07:00
Authentication code: 8675308

Re: Greyscale + gaussian

Post by Freeloader »

Hi fmw42,

First of, thanks, not just for the code examples, but also for the explanation that went with them. Really helped me understand all this better :)

I read that normal blurring has a considerable speed advantage over gaussian blurring - and speed will be important as I plan to process quite some images - but will this produce the same effects? (Namely: I'm trying to filter out noise from my images.)

Edit: as for the 'multiply 16', it was sth I picked up from a forum post on this forum. It was indeed to convert 16 bit to 8 bit grayscale. So in my case I should just do convert to grayscale?

Also, will your command do the filters in the same order as the one I outlined in my post?

The error I'm getting is:
convert: Unrecognized option (-auto-level).

I'm using a standard godaddy linux hosting account, version is:
ImageMagick 6.2.8 02/25/09 Q16 file:/usr/share/ImageMagick-6.2.8/doc/index.html

In any case, thanks a bunch for helping me out on this :-)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Greyscale + gaussian

Post by fmw42 »

Your IM version 6.2.8 is extremely old (about 430 versions old). If you cannot upgrade, then replace -auto-level with -contrast-stretch 0.

Differences between -blur and -gaussian-blur are generally minimal.

I still don't understand the -evaluate multiply 16. You may have taken that out of context. -depth 8 will convert 16-bit images so that they are 8-bit output. The issue is what range of values does your input image have?

identify -verbose info input.png

and see what range of values you get.
* convert from 1 bit to 8 bit greyscale
* gaussian filter with radius 20
* rescale the gray levels (x3 or autolevel)
* threshold at 40 -> revert to binary image
* do a 5px cropping of the edges
Should be the correct process, except you don't need the first step unless you have some odd form of input image and the first -auto-level will deal with that. -blur should replace nicely your gaussian blur and be faster. The second -auto-level will rescale the result to full dynamic range. The threshold 40% will binary threshold at 40% and should replace -white-threshold. The -shave should do the cropping.

So try:


exec("convert input.png -auto-level -blur 20 -auto-level -threshold 40% -shave 5x5 -depth 8 output.png 2>&1",$out,$returnval);
print_r($out[0]);

or if you cannot upgrade, then

exec("convert input.png -contrast-stretch 0 -blur 20 -contrast-stretch 0 -threshold 40% -shave 5x5 -depth 8 output.png 2>&1",$out,$returnval);
print_r($out[0]);
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Greyscale + gaussian

Post by fmw42 »

P.S. You might be interested in this post (and the following discussion) at viewtopic.php?f=1&t=18219&hilit=nip2#p71830
Freeloader
Posts: 8
Joined: 2011-07-24T14:10:19-07:00
Authentication code: 8675308

Re: Greyscale + gaussian

Post by Freeloader »

It's impossible for me to upgrade this version of ImageMagick, as it's running on a shared hosting account. I could ask GoDaddy support to upgrade their version, but I wouldn't expect too much from that...

I probably did take the evaluate multiply 16 out of context, you can just ignore it :)

Strangely enough, this is my output when running the identify -verbose command:
Image: input.png

The command you gave me - the one with contrast stretch - worked; but it's still not quite giving me the same results as with nip2. When I'm doing these filters with nip2, I end up with a blank canvas (due to threshold forcing the noise and background pixels to white and the image to black). Here, I end up with a black canvas with my image in vague white'ish form on it...

PS: it's an interesting discussion there; but as far as I see it, they're currently working/thinking about introducing either a front-end GUI to ImageMagick or being able to output ImageMagick lines of code from the nip2 front-end. The only function currently in place is that you're able to run ImageMagick commands in nip2, while I need the reverse, right?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Greyscale + gaussian

Post by fmw42 »

I use Godaddy and have repeatedly asked for them to upgrade with no success.

If you post a link to your input image and to your NIPS and IM resulting images, I can take a look at the processing and see if I can figure out what might be the issue. Did you use -threshold or -white-threshold. You need to use -threshold. Also you may have to adjust the threshold to match what you used in NIPS. If you use 40 out 255 that would be 40/255 = 15.7%

The identify -verbose image should have given you much more. Looks like you are getting only the first line. My error! I put only the first element of the out array. Try this:

<?php
exec("/usr/local/bin/identify -verbose yourimage 2>&1",$out,$returnval);
print_r($out);
?>
Freeloader
Posts: 8
Joined: 2011-07-24T14:10:19-07:00
Authentication code: 8675308

Re: Greyscale + gaussian

Post by Freeloader »

Indeed, looks like that was the problem :)

This is my verbose output:

Array ( [0] => Image: 3.png [1] => Format: PNG (Portable Network Graphics) [2] => Class: PseudoClass [3] => Geometry: 360x220 [4] => Type: Grayscale [5] => Endianess: Undefined [6] => Colorspace: Gray [7] => Channel depth: [8] => Gray: 8-bits [9] => Channel statistics: [10] => Gray: [11] => Min: 0 (0) [12] => Max: 254 (0.996078) [13] => Mean: 6.82886 (0.0267799) [14] => Standard deviation: 40.8764 (0.1603) [15] => Colors: 256 [16] => Histogram: [17] => 77011: ( 0, 0, 0) black [18] => 22: ( 31, 31, 31) grey12 [19] => 18: ( 63, 63, 63) #3F3F3F [20] => 2: ( 87, 87, 87) grey34 [21] => 13: ( 95, 95, 95) #5F5F5F [22] => 2: (111,111,111) #6F6F6F [23] => 2: (115,115,115) grey45 [24] => 6: (127,127,127) grey50 [25] => 2: (135,135,135) grey53 [26] => 7: (159,159,159) #9F9F9F [27] => 16: (191,191,191) grey75 [28] => 38: (223,223,223) #DFDFDF [29] => 2061: (254,254,254) #FEFEFE [30] => Rendering intent: Undefined [31] => Resolution: 72x72 [32] => Units: Undefined [33] => Filesize: 4.1kb [34] => Interlace: None [35] => Background color: white [36] => Border color: #DFDFDF [37] => Matte color: grey74 [38] => Page geometry: 360x220+0+0 [39] => Dispose: Undefined [40] => Iterations: 0 [41] => Compression: Zip [42] => Orientation: Undefined [43] => Signature: e4819332df1044067d3723479f718262af85d6efda7bef2c86e37d7f6da9547a [44] => Tainted: False [45] => Version: ImageMagick 6.2.8 02/25/09 Q16 file:/usr/share/ImageMagick-6.2.8/doc/index.html )

I'll see if I can create a sample input and NIP2 output/ImageMagick output. For now, I'll play around a little with the threshold.
Freeloader
Posts: 8
Joined: 2011-07-24T14:10:19-07:00
Authentication code: 8675308

Re: Greyscale + gaussian

Post by Freeloader »

I've PM'ed you some of the image samples :)
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Greyscale + gaussian

Post by fmw42 »

Freeloader wrote:I've PM'ed you some of the image samples :)

I don't think you are doing what you think you are doing in NIPS. Your input is 360x220 and you NIPS output is 335x210. So you are not just trimming 5 pixels all around. In NIPS it would appear that blur works somewhat more like -blur 0x6.7 where radius will be 3*sigma or 3*6.7=20. I am getting close results with that and a threshold of 20%. Note also your NIPS result has a negate in it to invert the white and black.

Try either of these:


convert inputm.png -auto-level \
-blur 0x6.7 \
-auto-level \
-threshold 20% -negate \
-gravity center -crop 335x210-8+0 +repage \
-depth 8 output1.png

convert inputm.png -auto-level \
-blur 0x6.7 \
-auto-level \
-threshold 20% -negate \
-gravity center -shave 0x5 \
-gravity west -chop 5x0 \
-gravity east -chop 20x0 \
-depth 8 output2.png
User avatar
anthony
Posts: 8883
Joined: 2004-05-31T19:27:03-07:00
Authentication code: 8675308
Location: Brisbane, Australia

Re: Greyscale + gaussian

Post by anthony »

Freeloader wrote:I read that normal blurring has a considerable speed advantage over gaussian blurring - and speed will be important as I plan to process quite some images - but will this produce the same effects? (Namely: I'm trying to filter out noise from my images.)
Normal blurring is a LOT faster than gaussian blurring, even though more operations are applied.
The only differences are virtual-pixel edge effects resulting from using two separate operations (IM does not remember how 'virtual pixels' would have changed when two separate operations are applied, when a single operation can).

The effects are usually minor and rarely of any real importance unless exact value of individual pixels become important in highly mathematical operations (a rare requirement).

For more info see the internals, which is detailed in IM Examples, Convolution, Gaussian vs Blur Kernels
http://www.imagemagick.org/Usage/convol ... an_vs_blur
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
Freeloader
Posts: 8
Joined: 2011-07-24T14:10:19-07:00
Authentication code: 8675308

Re: Greyscale + gaussian

Post by Freeloader »

Wow, fmw42, that's quite amazing! I've been working on that one for a week! :)

Also thanks @ Anthony for the clarification, I'm definitely going for a normal blur.

One final question: is it possible to remove smaller objects in the image? (The noise that the blur and the threshold didn't get out.) For example: remove all objects smaller than 20px? Alternatively, if that's not possible, would it be possible to cut the bottom right corner from the image? (As you can see, that one's still on there after the blurring and thresholding).
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Greyscale + gaussian

Post by fmw42 »

If the objects are small enough compared to your main objects, then -morphology open/close (depending upon white on black or vice-versa) will do that. You may see some change in the outline of your figure, though, depending upon how big the morphology shape is. The larger the shape the larger the region it will remove as long. As it is not too close to the size/thickness of your objects, they should have only minor changes. You can easily crop more off the right by using a bigger -gravity east -chop.

This seems to work:

convert inputm.png -auto-level \
-blur 0x6.7 \
-auto-level \
-threshold 20% -negate \
-gravity center -shave 0x5 \
-gravity west -chop 5x0 \
-gravity east -chop 20x0 \
-morphology close diamond:5 \
-depth 8 output3.png


see http://www.imagemagick.org/Usage/morphology/

P.S. with regard to the threshold at 20% rather than 40. It may be possible that NIPS was using 40/255 = 16%, but 20% would be like 51/255. I don't know enough about NIPS to know which way it works.
Freeloader
Posts: 8
Joined: 2011-07-24T14:10:19-07:00
Authentication code: 8675308

Re: Greyscale + gaussian

Post by Freeloader »

Excellent, the smaller threshold worked a lot better.

The morphology doesn't seem to work on GoDaddy, maybe a version issue? Is there an alternative for the version GoDaddy is running?
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Greyscale + gaussian

Post by fmw42 »

Freeloader wrote:Excellent, the smaller threshold worked a lot better.

The morphology doesn't seem to work on GoDaddy, maybe a version issue? Is there an alternative for the version GoDaddy is running?

Sorry, with such an old version of IM, -morphology was not available. There is no good easy answer. If you want to manually locate each such black area, then you can floodfill each to white. Or you can try a large median filter, but that will likely change your object shape.


convert inputm.png -auto-level \
-blur 0x6.7 \
-auto-level \
-threshold 20% -negate \
-gravity center -shave 0x5 \
-gravity west -chop 5x0 \
-gravity east -chop 20x0 \
-fill white -draw "color 333,204 floodfill" +matte \
-depth 8 output.png
Post Reply