A question arose on the Magick-Users Forum about how to find the location of a given color or brightness pixel. I came up with the following:
convert rose: -type Grayscale -fx "u==rgb(255,255,255)?debug(u):1; u" null:
which returns a list to the terminal as follows:
ROSE[11,61].red: u=1
ROSE[11,61].green: u=1
ROSE[11,61].blue: u=1
ROSE[15,62].red: u=1
ROSE[15,62].green: u=1
ROSE[15,62].blue: u=1
ROSE[16,62].red: u=1
ROSE[16,62].green: u=1
ROSE[16,62].blue: u=1
...etc...
I am not a Unix expert, so I would like to know how to redirect the output to a file or to a string for further processing
I tried:
convert rose: -type Grayscale -fx "u==rgb(255,255,255)?debug(u):1; u" null: > rose.txt
but the file is empty.
Likewise:
str=`convert rose: -type Grayscale -fx "u==rgb(255,255,255)?debug(u):1; u" null:`
but
str is empty, also.
Removing null: and replacing with rose.txt produces the whole image in the text file and not just the debug listing.
So I am stumped about this. Anyone know how to handle this?
How To Find Location Of A Given Brightness Pixel
-
- Posts: 1015
- Joined: 2005-03-21T21:16:57-07:00
Re: How To Find Location Of A Given Brightness Pixel
Hi Fred,
I sent the answer direct to you via PM but just in case anyone else needs the answer:
The redirect "> rose.txt" sends the standard output (file descriptor 1) to the file, but the debug output is being sent to the error output (file descriptor 2). To redirect that you need "2> rose.txt". This even works on Windows!
Best Wishes
Pete
I sent the answer direct to you via PM but just in case anyone else needs the answer:
The redirect "> rose.txt" sends the standard output (file descriptor 1) to the file, but the debug output is being sent to the error output (file descriptor 2). To redirect that you need "2> rose.txt". This even works on Windows!
Best Wishes
Pete
- anthony
- Posts: 8883
- Joined: 2004-05-31T19:27:03-07:00
- Authentication code: 8675308
- Location: Brisbane, Australia
Re: How To Find Location Of A Given Brightness Pixel
WARNING
An expression for the form
u==rgb(255,128,0)
Will for a red channel run test
u==255
for green it will test
u==128
and for blue it will test
u==0
That means it will print a line is ANY of the above is true, whcih happen if any one channel matches, not nessarilly all three.
In other word the output will only be correct is ALL three channel tests were output for a specific pixel location
For correct handling you will need to test ALL three values simultaniously.
For example
-channel R -fx '( u.r==1.0 && u.g==0.5 && u.b==0.0 ) ? debug(u) : 1; u'
However as 'u' values are floating point even that may be tricky to get right.
The -channel limits the -fx to only executing once per pixel, rather than once per image channel value, speeding it up a bit.
I think a better method might be to give the image a alpha channel, make the desired pixel transparent, or some other specific 'known' color, then test for transparency or that color. It may be a lot faster!!!
You can even then to a straight text search (grep) using the 'txt' output, to find that pixel location. As you are looking for the well known specific color white, just look for white!
convert rose: txt:- | grep white
And you have your list of white pixels!!!
There is always more than one way to skin a cat!!!
An expression for the form
u==rgb(255,128,0)
Will for a red channel run test
u==255
for green it will test
u==128
and for blue it will test
u==0
That means it will print a line is ANY of the above is true, whcih happen if any one channel matches, not nessarilly all three.
In other word the output will only be correct is ALL three channel tests were output for a specific pixel location
For correct handling you will need to test ALL three values simultaniously.
For example
-channel R -fx '( u.r==1.0 && u.g==0.5 && u.b==0.0 ) ? debug(u) : 1; u'
However as 'u' values are floating point even that may be tricky to get right.
The -channel limits the -fx to only executing once per pixel, rather than once per image channel value, speeding it up a bit.
I think a better method might be to give the image a alpha channel, make the desired pixel transparent, or some other specific 'known' color, then test for transparency or that color. It may be a lot faster!!!
You can even then to a straight text search (grep) using the 'txt' output, to find that pixel location. As you are looking for the well known specific color white, just look for white!
convert rose: txt:- | grep white
And you have your list of white pixels!!!
There is always more than one way to skin a cat!!!
Anthony Thyssen -- Webmaster for ImageMagick Example Pages
https://imagemagick.org/Usage/
https://imagemagick.org/Usage/
Re: How To Find Location Of A Given Brightness Pixel
Hi, I have used the command
a=execute("convert Arm1/Arm1.png txt:- | grep white")
but "a" is <type 'NoneType'>, so I can't check if it's empty or not in a loop for using the length, as if it was a string...
Does anybody know how to save "a" as a string or any other way to solve this?
a=execute("convert Arm1/Arm1.png txt:- | grep white")
but "a" is <type 'NoneType'>, so I can't check if it's empty or not in a loop for using the length, as if it was a string...
Does anybody know how to save "a" as a string or any other way to solve this?
- fmw42
- Posts: 25562
- Joined: 2007-07-02T17:14:51-07:00
- Authentication code: 1152
- Location: Sunnyvale, California, USA
Re: How To Find Location Of A Given Brightness Pixel
LeyreM wrote:Hi, I have used the command
a=execute("convert Arm1/Arm1.png txt:- | grep white")
but "a" is <type 'NoneType'>, so I can't check if it's empty or not in a loop for using the length, as if it was a string...
Does anybody know how to save "a" as a string or any other way to solve this?
I presume you are on PHP using the exec command. You should put in the remaining parts to see any errors. You probably need to change "a" to an array variable, but I am not a PHP expert and so cannot say how to do that for sure. But then you could print out the array of values that you will get back from txt:-