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
convert 50% of pixels to black, 50% to white
- 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
try this
convert input.jpg -colorspace gray -linear-stretch 50x50% output.gif
that seems to work fine for me with the zelda image.
convert input.jpg -colorspace gray -linear-stretch 50x50% output.gif
that seems to work fine for me with the zelda image.
Re: convert 50% of pixels to black, 50% to white
> 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
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
- 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
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.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
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.
Re: convert 50% of pixels to black, 50% to white
> 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
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
- 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
> 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.