convert 50% of pixels to black, 50% to white

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?".
Post Reply
jlehrer
Posts: 3
Joined: 2012-08-29T19:13:33-07:00
Authentication code: 67789

convert 50% of pixels to black, 50% to white

Post by jlehrer »

I've spent about 3 hours trying to figure this out and finally am reaching out for help.

I have a JPG color image. I would like to convert to a black and white image (all pixels are black or white) with no dithering where 50% of the pixels are black and 50% of the pixels are white.

I have tried using linear-stretch 50x50% but that gives me a solid white image.

Can anyone help?

Version: ImageMagick 6.7.7-10 2012-07-12

Thank you,

J
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: convert 50% of pixels to black, 50% to white

Post by fmw42 »

try this

convert input.jpg -colorspace gray -linear-stretch 50x50% output.gif

that seems to work fine for me with the zelda image.
jlehrer
Posts: 3
Joined: 2012-08-29T19:13:33-07:00
Authentication code: 67789

Re: convert 50% of pixels to black, 50% to white

Post by jlehrer »

> convert input.jpg -colorspace gray -linear-stretch 50x50% output.gif

Thank you, that worked.

Can you explain why it didn't work for me without the "-set colorspace RGB" and "-colorspace gray" before the "-linear-stretch 50x50%"?

Without those two modifiers I get a white image. You gave me the answer, now I want to understand better so I don't have to ask next time.

Thanks,

-J
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: convert 50% of pixels to black, 50% to white

Post by fmw42 »

jlehrer wrote:> convert input.jpg -colorspace gray -linear-stretch 50x50% output.gif

Thank you, that worked.

Can you explain why it didn't work for me without the "-set colorspace RGB" and "-colorspace gray" before the "-linear-stretch 50x50%"?

Without those two modifiers I get a white image. You gave me the answer, now I want to understand better so I don't have to ask next time.

Thanks,

-J
The -set colorspace RGB is not needed. It was my mistake. Actually not a mistake, but I got better (more even histogram counts) without it.

Without the -colorspace gray, -linear-stretch will get the combined statistics and apply the same value to each channel. But as each channel is different, you get different results for each channel. So I would expect to see a colored image and not white. That is exactly what I get -- a colored image -- with my test zelda image.

Converting to gray mixes the channels unequally according to a standard mix ratio. See http://www.imagemagick.org/script/comma ... colorspace. But if you want equal weights for each channel, then use

convert input.jpg -colorspace OHTA -channel R -separate +channel -linear-stretch 50%x50% output.gif

The same reference shows that the first channel (R) of the OHTA colorspace is an equal mix of R,G,B i.e. the average (R+G+B)/3. This should be the same (or very close) result as getting the global histogram of all the channels together. Probably what you were hoping to do.

Also note that this kind of thresholding is called Ptile or Percentile thresholding. When it uses 50,50, then it is called Balanced Thresholding.

see
http://en.wikipedia.org/wiki/Balanced_h ... resholding
http://www.pvv.org/~perchrh/papers/data ... report.pdf

It is a strange coincidence as I was about to start tomorrow creating a script to do ptile thresholding. Turns out your question raised a flag that -linear-stretch will do just that without having separately to compute the cumulative histogram. Though it won't tell us what exact graylevel that percentile is equivalent to.

This is a very interesting and useful applications of -linear-stretch.

Note you may find some of my other thresholding scripts of interest. You can find them at the link below and also a summary of all the thresholding scripts. No one thresholding method is good for every image and often there is no good threshold value.
jlehrer
Posts: 3
Joined: 2012-08-29T19:13:33-07:00
Authentication code: 67789

Re: convert 50% of pixels to black, 50% to white

Post by jlehrer »

> convert input.jpg -colorspace OHTA -channel R -separate +channel -linear-stretch 50%x50% output.gif

Wow, thanks for the quick responses.

Unfortunately, this does not give me an image with half black and half white. The images are mostly white. This does generate a neat edge-detection effect but that isn't exactly what I am going for.

What I am doing is trying to detect motion between two frames of webcam video, about 1 minute apart. I get a lot of changes in sunlight in the window so converting to 50/50 black/white seems to normalize away those sun bursts.

My current solution is to apply the following to each image:

-resize 256x96 -blur 0x1 -colorspace gray -linear-stretch 50x50%

then to compare the two images with

compare -metric PSNR image1 image2 JPG:/dev/null

I then look at the result of the compare. For my purposes, a value < 9.0 indicates motion.

So far it appears to be working well.

Thanks,

J
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: convert 50% of pixels to black, 50% to white

Post by fmw42 »

> convert input.jpg -colorspace OHTA -channel R -separate +channel -linear-stretch 50%x50% output.gif

Wow, thanks for the quick responses.

Unfortunately, this does not give me an image with half black and half white. The images are mostly white. This does generate a neat edge-detection effect but that isn't exactly what I am going for.

It worked fine for me on IM 6.7.9.2 Q16 Mac OSX Snow Leopard with my test image.


convert zelda3.jpg -colorspace OHTA -channel R -separate +channel -linear-stretch 50%x50% zelda3_thresh3.gif

identify -verbose zelda3_thresh3.gif
...

Histogram:
8196: ( 0, 0, 0) #000000 gray(0,0,0)
8188: (255,255,255) #FFFFFF gray(255,255,255)

Pretty close to 50%, though not quite as close as using -colorspace gray.

convert zelda3.jpg -colorspace gray -linear-stretch 50%x50% zelda3_thresh2.gif

8193: ( 0, 0, 0) #000000 gray(0,0,0)
8191: (255,255,255) #FFFFFF gray(255,255,255)


I suspect it is just an issue of bin quantization of the histogram for the given image.
Post Reply