Determining if All Pixels Fall Within a Color Range
Determining if All Pixels Fall Within a Color Range
Hello,
I am trying to determine if EVERY pixel within an artpiece is within, say, 1% of solid black (in RGB and CMYK). Conversely, if all pixels are within 1% of solid white.
Ultimately, I'd like to analyze an image to know if the creator intended for it to be solid black or solid white.
What does NOT work is something that will tell me the average pixel color because, for example, you might have a picture of a ghost (white sheet) with two tiny black eyes. The average would essentially be white. I need to know if there are any pixels outside of the "almost pure white" or "almost pure black" range.
I found this link, but it doesn't really solve my problem: http://www.fmwconcepts.com/imagemagick/ ... or_percent
Any ideas?
Thanks!
I am trying to determine if EVERY pixel within an artpiece is within, say, 1% of solid black (in RGB and CMYK). Conversely, if all pixels are within 1% of solid white.
Ultimately, I'd like to analyze an image to know if the creator intended for it to be solid black or solid white.
What does NOT work is something that will tell me the average pixel color because, for example, you might have a picture of a ghost (white sheet) with two tiny black eyes. The average would essentially be white. I need to know if there are any pixels outside of the "almost pure white" or "almost pure black" range.
I found this link, but it doesn't really solve my problem: http://www.fmwconcepts.com/imagemagick/ ... or_percent
Any ideas?
Thanks!
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Determining if All Pixels Fall Within a Color Range
try creating a pure black ( or pure white) image the same as your image, then do a -compose difference and then get the average value of the difference as a measure of how much different they are.
convert yourimage \( +clone -fill black -colorize 100% \) -compose difference -composite -format "%[fx:100*mean]" info
this will give the the percent difference on average
see http://www.imagemagick.org/Usage/compose/#difference and http://www.imagemagick.org/script/fx.php
alternately, just get the mean value of your image and compare to 0 for black or 1 for white and see how much difference you have
convert yourimage \( +clone -fill black -colorize 100% \) -compose difference -composite -format "%[fx:100*mean]" info
this will give the the percent difference on average
see http://www.imagemagick.org/Usage/compose/#difference and http://www.imagemagick.org/script/fx.php
alternately, just get the mean value of your image and compare to 0 for black or 1 for white and see how much difference you have
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: Determining if All Pixels Fall Within a Color Range
A compose difference of any image against pure black would produce... the same image. It is a No-Op
against white, just negate the image. for any other color, then a difference image is recommended.
To get the color difference of all pixels with regard to black do the following...
separate the channels, square the values, add, and get the square root.
Note this assumes the colors are linear! and not in sRGB space!
For testing threshold to 1%, or extract the mean, min, max values of the resulting image.
This is is similar to a 'fuzz' factor difference (when transparency is not involved). Though fuzz factor would also divide the squares by 3 before adding to make 0 to 1 the distance between white and black. Also fuzz would do all the calculations with doubles rather than as integers (and so produce quantum rounding effects).
See IM Examples, Comparing Images, Difference Images
http://www.imagemagick.org/Usage/ompare/#difference
against white, just negate the image. for any other color, then a difference image is recommended.
To get the color difference of all pixels with regard to black do the following...
separate the channels, square the values, add, and get the square root.
Code: Select all
convert image.png -separate -evaluate pow 2 -evaluate-sequence add \
-evaluate pow 0.5 color_distance.png
For testing threshold to 1%, or extract the mean, min, max values of the resulting image.
This is is similar to a 'fuzz' factor difference (when transparency is not involved). Though fuzz factor would also divide the squares by 3 before adding to make 0 to 1 the distance between white and black. Also fuzz would do all the calculations with doubles rather than as integers (and so produce quantum rounding effects).
See IM Examples, Comparing Images, Difference Images
http://www.imagemagick.org/Usage/ompare/#difference
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Determining if All Pixels Fall Within a Color Range
Right!A compose difference of any image against pure black would produce... the same image. It is a No-Op
against white, just negate the image. for any other color, then a difference image is recommended.
My second way was probably better as one just computes the mean of the image for a comparison to black.
Good point about the negating with respect to comparing to white!
Re: Determining if All Pixels Fall Within a Color Range
Guys, thank you so much for your reply. Admittedly, this is way above my head, so let me ask if I'm interpreting this correctly:
1) There is a command within IM that will compare every pixel within an image to, say, black CMYK(0,0,0,100)/RGB(0,0,0).
2) I can extract from said analysis the maximum percentage difference from black.
These are some extended yet basic examples using a 3x3 image (9 total pixels):
Example 1:
- ALL nine pixels are within the following CMYK range (0,0,0,99) - (100,100,100,100) with K value ALWAYS either 99 or 100
RESULT: ALL BLACK
Example 2:
- Eight of the nine pixels are within the following CMYK range (0,0,0,99) - (100,100,100,100) with K value ALWAYS either 99 or 100
- One pixel is (23,53,66,98) which is NOT within 1% of 100K
RESULT: NOT ALL BLACK
Example 3:
- ALL nine pixels are within the following CMYK range (0,0,0,0) - (1,1,1,1)
RESULT: ALL WHITE
Example 4:
- Eight of the nine pixels are within the following CMYK range (0,0,0,0) - (1,1,1,1)
- One pixel is (23,53,66,98)
RESULT: NOT ALL WHITE
______________________________________
If my interpretation is correct, can you guys please give me a little better explanation about how to do this for both CMYK and RGB? And perhaps you can explain the concern about sRGB?
Ultimately, I'm a relative novice that has learned a ton from this forum, and I need to translate this into VBA.
Typically, my "code" would look something like this:
MaxColorDiff = Max(IM_Process[My_Image])
If MaxColorDiff <= 1% then [My_Image] = "All Black"
I just need to derive the "IM_Process" in my code.
I hope this makes sense...
Thanks.
1) There is a command within IM that will compare every pixel within an image to, say, black CMYK(0,0,0,100)/RGB(0,0,0).
2) I can extract from said analysis the maximum percentage difference from black.
These are some extended yet basic examples using a 3x3 image (9 total pixels):
Example 1:
- ALL nine pixels are within the following CMYK range (0,0,0,99) - (100,100,100,100) with K value ALWAYS either 99 or 100
RESULT: ALL BLACK
Example 2:
- Eight of the nine pixels are within the following CMYK range (0,0,0,99) - (100,100,100,100) with K value ALWAYS either 99 or 100
- One pixel is (23,53,66,98) which is NOT within 1% of 100K
RESULT: NOT ALL BLACK
Example 3:
- ALL nine pixels are within the following CMYK range (0,0,0,0) - (1,1,1,1)
RESULT: ALL WHITE
Example 4:
- Eight of the nine pixels are within the following CMYK range (0,0,0,0) - (1,1,1,1)
- One pixel is (23,53,66,98)
RESULT: NOT ALL WHITE
______________________________________
If my interpretation is correct, can you guys please give me a little better explanation about how to do this for both CMYK and RGB? And perhaps you can explain the concern about sRGB?
Ultimately, I'm a relative novice that has learned a ton from this forum, and I need to translate this into VBA.
Typically, my "code" would look something like this:
MaxColorDiff = Max(IM_Process[My_Image])
If MaxColorDiff <= 1% then [My_Image] = "All Black"
I just need to derive the "IM_Process" in my code.
I hope this makes sense...
Thanks.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Determining if All Pixels Fall Within a Color Range
For an rgb grayscale image (r=g=b), the 100*mean of the image (mean in the range 0 to 1) is the average percent difference from pure black. If you get 0, the image is pure black, if you get 100, the image is pure white.
meanpct=`convert image -colorspace gray -format "%[fx:100*mean]" info:`
The above is a unix command (using `...`) to get the result into a variable. For windows see http://www.imagemagick.org/Usage/windows/
Of course the command itself is also windows dependent as % need to be escaped as %%. So the command is likely
convert image -colorspace gray -format "%%[fx:100*mean]" info:
Test your 3x3 images in command line mode and see what you get.
However, as I am not a windows user, you should read the reference above.
meanpct=`convert image -colorspace gray -format "%[fx:100*mean]" info:`
The above is a unix command (using `...`) to get the result into a variable. For windows see http://www.imagemagick.org/Usage/windows/
Of course the command itself is also windows dependent as % need to be escaped as %%. So the command is likely
convert image -colorspace gray -format "%%[fx:100*mean]" info:
Test your 3x3 images in command line mode and see what you get.
However, as I am not a windows user, you should read the reference above.
Re: Determining if All Pixels Fall Within a Color Range
First, let me apologize for dropping this conversation...6 years ago. I got pulled off the project and had not been reassigned until now.
I'm sorry to re-open this thread, but in response to Fred's response, if I understand the theory correctly, if 100% of pixels are black, the mean is 0. ALL BLACK. If 100% of the pixels are white, the mean is 1. ALL WHITE.
BUT...anywhere in between fails proof (I think).
If 50% of the pixels are white, and 50% are black, the mean is 0.5. But 50% doesn't necessarily mean that the image contains white. It could be 25% grey plus 75% grey to equal a mean of 0.5. Unfortunately, I need to know the following situations:
1) 100% black (within 2%)
2) Contains ANY white (within 2%)
3) Contains colors OTHER THAN black or white (between the 2%-98% mean value).
I was thinking about your concept, and considering converting to greyscale and grab the mean, but it's still the same result. No proof that white exists, only that it's not 100% black.
So, I'm wondering if you have other thoughts on this.
And again, I apologize for the absence.
I'm sorry to re-open this thread, but in response to Fred's response, if I understand the theory correctly, if 100% of pixels are black, the mean is 0. ALL BLACK. If 100% of the pixels are white, the mean is 1. ALL WHITE.
BUT...anywhere in between fails proof (I think).
If 50% of the pixels are white, and 50% are black, the mean is 0.5. But 50% doesn't necessarily mean that the image contains white. It could be 25% grey plus 75% grey to equal a mean of 0.5. Unfortunately, I need to know the following situations:
1) 100% black (within 2%)
2) Contains ANY white (within 2%)
3) Contains colors OTHER THAN black or white (between the 2%-98% mean value).
I was thinking about your concept, and considering converting to greyscale and grab the mean, but it's still the same result. No proof that white exists, only that it's not 100% black.
So, I'm wondering if you have other thoughts on this.
And again, I apologize for the absence.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Determining if All Pixels Fall Within a Color Range
For CMYK, I would convert this to sRGB.
1) You want to know whether all pixels are within 2% of black. So convert to grayscale and find the maximum lightness. If this is less than 2%, that's the answer.
(Or you might ask a slightly different question: are all the pixel values within 2% of zero. If that's the question, don't convert to grayscale.)
2) Does it contain any white? Similar question, but now you do want the maximum lightness to be more than 98%.
3) Contains anything other than nearly black or nearly white? Turn the nearly black colours from (1) to exactly black. Turn the nearly white colours from (2) also to exactly black. Now the question is: are there any non-black pixels? Find the maximum. If this is zero, all the colours are black. If the maximum isn't zero, then some colour are not black, so some of the input pixels are neither nearly black nor nearly white.
Sorry, I don't do Visual Basic.
1) You want to know whether all pixels are within 2% of black. So convert to grayscale and find the maximum lightness. If this is less than 2%, that's the answer.
(Or you might ask a slightly different question: are all the pixel values within 2% of zero. If that's the question, don't convert to grayscale.)
2) Does it contain any white? Similar question, but now you do want the maximum lightness to be more than 98%.
3) Contains anything other than nearly black or nearly white? Turn the nearly black colours from (1) to exactly black. Turn the nearly white colours from (2) also to exactly black. Now the question is: are there any non-black pixels? Find the maximum. If this is zero, all the colours are black. If the maximum isn't zero, then some colour are not black, so some of the input pixels are neither nearly black nor nearly white.
Sorry, I don't do Visual Basic.
snibgo's IM pages: im.snibgo.com
Re: Determining if All Pixels Fall Within a Color Range
Thanks so much for the response. Your concept checks out, but admittedly don't know the IM commands (even without Visual Basic).
Basically, I need:
If MaxBright <0.02 then All Black (and exit routine)
else
if MaxBright >0.98 then Contains White (and exit routine)
else
If MaxBright >=0.02 and MaxBright <= 0.98 then Contains Something Other Than White/Black (and exit routine)
end if
I explain it this way because at the moment I detect white (step 2), I don't need to know it contains other colors.
So, would it be possible to ask how you would write it in whatever format works for you? (I know how to convert standard IM commands to VB.)
Thanks in advance.
Basically, I need:
If MaxBright <0.02 then All Black (and exit routine)
else
if MaxBright >0.98 then Contains White (and exit routine)
else
If MaxBright >=0.02 and MaxBright <= 0.98 then Contains Something Other Than White/Black (and exit routine)
end if
I explain it this way because at the moment I detect white (step 2), I don't need to know it contains other colors.
So, would it be possible to ask how you would write it in whatever format works for you? (I know how to convert standard IM commands to VB.)
Thanks in advance.
-
- Posts: 12159
- Joined: 2010-01-23T23:01:33-07:00
- Authentication code: 1151
- Location: England, UK
Re: Determining if All Pixels Fall Within a Color Range
Here are commands in Windows BAT syntax. %SRC% is the input image. Each command returns 0 ("no") or 1 ("yes"). For V7, use "magick" instead of "convert".
Code: Select all
rem Are all pixels close to black?
convert ^
%SRC% ^
-colorspace Gray ^
-format "%%[fx:maxima<0.02?1:0]" ^
info:
rem Are any pixels close to white?
convert ^
%SRC% ^
-colorspace Gray ^
-format "%%[fx:maxima>0.98?1:0]" ^
info:
rem Contains anything other than nearly black or nearly white?
convert ^
%SRC% ^
-colorspace Gray ^
-fuzz 2%% -fill Black ^
-opaque Black ^
-opaque White ^
-format "%%[fx:maxima>0?1:0]" ^
info:
snibgo's IM pages: im.snibgo.com
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Determining if All Pixels Fall Within a Color Range
Do you care if the "colors" are grayscale or only non-grayscale? If the latter, then using the intensity in the range 2 to 98 will not tell you whether those colors or grayshades or non-gray colors.
Re: Determining if All Pixels Fall Within a Color Range
My source images will never be in grayscale. They'll always be RGB PNGs, even if they're all white or all black.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Determining if All Pixels Fall Within a Color Range
So you only care if
1) all white (within 2%)
2) all black (within 2%)
3) anything in between in intensity
Is that correct? So you do not care if actual color or grayshades other than near black or near white, correct? If so, then snibgo's solution should work fine.
Re: Determining if All Pixels Fall Within a Color Range
No. I care:
1) ANY white (within 2%). ANY white at all.
2) ALL Black (within 2%). Completely black.
3) not conditions 1 or 2.
1) ANY white (within 2%). ANY white at all.
2) ALL Black (within 2%). Completely black.
3) not conditions 1 or 2.
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: Determining if All Pixels Fall Within a Color Range
You care about what? For case 3) do you only want non-grayscale colors to be caught or do you include gray values between 2% and 98%
"Not conditions 1 or 2" will include gray shades as well as colors (non-gray-shades)