Determining if All Pixels Fall Within a Color Range

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?".
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Determining if All Pixels Fall Within a Color Range

Post by dfelder »

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!
User avatar
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

Post by fmw42 »

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
User avatar
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

Post by anthony »

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.

Code: Select all

convert image.png  -separate -evaluate pow 2 -evaluate-sequence add \
            -evaluate pow 0.5 color_distance.png
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
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
User avatar
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

Post by fmw42 »

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.
Right!

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!
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

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.
User avatar
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

Post by fmw42 »

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.
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

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.
snibgo
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

Post by snibgo »

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.
snibgo's IM pages: im.snibgo.com
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

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.
snibgo
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

Post by snibgo »

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
User avatar
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

Post by fmw42 »

dfelder wrote: 2017-08-25T09:44:00-07:00 3) Contains colors OTHER THAN black or white (between the 2%-98% mean value).
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.
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

My source images will never be in grayscale. They'll always be RGB PNGs, even if they're all white or all black.
User avatar
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

Post by fmw42 »

dfelder wrote: 2017-08-25T15:16:31-07:00 My source images will never be in grayscale. They'll always be RGB PNGs, even if they're all white or all black.
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.
dfelder
Posts: 42
Joined: 2011-02-25T16:49:09-07:00
Authentication code: 8675308

Re: Determining if All Pixels Fall Within a Color Range

Post by dfelder »

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.
User avatar
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

Post by fmw42 »

dfelder wrote: 2017-08-25T15:33:01-07:00 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.
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)
Post Reply