I don't understand color calculation [solved]

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
supermax
Posts: 6
Joined: 2017-05-10T09:42:36-07:00
Authentication code: 1151

I don't understand color calculation [solved]

Post by supermax » 2017-10-20T02:51:49-07:00

I'm trying to calculate the ndvi index using imagemagick in spite of proprietary software, but I obtain different results using different methods with the same mathematical expression.

In a linux console:
convert d0-2017-10-13.jpg -separate d0-%d.png
convert d0-0.png d0-1.png d0-2.png -fx '(u[2])-(u[0]) / (u[2])+(u[0])' d0ndvi.png
-0, -1 and -2 images correspond to rgb channels; u[0] correspond to the first file and u[2] to the third
I obtain a b/n image that should correspond to the ndvi index.

Typing
convert d0-2017-10-13.jpg -fx "(u.b-u.r)/(u.b+u.r)" d0ndvi2.png,
where u.b is the blue channel and u.r is the red channel, I obtain a total black image.

Can you help me to understand why?
Thank you in advance.

This is the image
https://www.flickr.com/photos/152450284 ... ed-public/
ndvi index
https://it.wikipedia.org/wiki/Normalize ... tion_Index
Last edited by supermax on 2017-10-22T09:41:24-07:00, edited 1 time in total.

snibgo
Posts: 9406
Joined: 2010-01-23T23:01:33-07:00
Authentication code: 1151
Location: England, UK

Re: I don't understand color calculation

Post by snibgo » 2017-10-20T03:27:48-07:00

supermax wrote:(u[2])-(u[0]) / (u[2])+(u[0])
Is that what you intended? Look at the parentheses.
supermax wrote:(u.b-u.r)/(u.b+u.r)
Where blue is less than red, the value will be negative, which clamps to black. In your image, blue is mostly less than red. Try adding 0.5.
snibgo's IM pages: im.snibgo.com

User avatar
fmw42
Posts: 22109
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: I don't understand color calculation

Post by fmw42 » 2017-10-20T09:34:41-07:00

try

Code: Select all

(u[2]-u[0]) / (u[2]+u[0])
If the index can be negative, then you need to use HDRI imagemagick and file format such as PFM or TIFF that supports negative values.

Or as snibgo said, add a bias of 0.5.

Also
supermax wrote:convert d0-0.png d0-1.png d0-2.png -fx '(u[2])-(u[0]) / (u[2])+(u[0])' d0ndvi.png
You do not use d0-1.png, so you don't need to include it.

Code: Select all

convert d0-0.png d0-2.png -fx (u[1]-u[0]) / (u[1]+u[0])' d0ndvi.png
or

Code: Select all

convert d0-2017-10-13.jpg -separate -delete 1 -fx (u[1]-u[0]) / (u[1]+u[0])' d0ndvi.png

supermax
Posts: 6
Joined: 2017-05-10T09:42:36-07:00
Authentication code: 1151

Re: I don't understand color calculation

Post by supermax » 2017-10-20T10:07:28-07:00

Thank you for your reply.
Yes, adding 0.5 gives a brighter images but with different contrast.
The range of Ndvi index should be between -1 and 1; I was wondering how the different commands 'convert' it in the range of 0-255 values.
I'm going to compare a series of images of differently fertilized plants and I would like to avoid unexpected gamma or contrast corrections at first.

User avatar
fmw42
Posts: 22109
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: I don't understand color calculation

Post by fmw42 » 2017-10-20T10:57:17-07:00

try adding 1 and dividing by 2, so that the range is 0 to 1.

supermax
Posts: 6
Joined: 2017-05-10T09:42:36-07:00
Authentication code: 1151

Re: I don't understand color calculation

Post by supermax » 2017-10-21T11:12:39-07:00

Near the plants, I putted a white target that I cropped in white.jpg.
convert white.jpg -resize 1x1\! -format "%[pixel:u]\n" info: >white.txt
white.txt contain this text line:
srgb(255,170,231)

I tried to make a white balance adding *255/231 to the blue channel and follow fmw42 suggestion.
convert d0-2017-10-13.jpg -separate -delete 1 -fx '((u[1]*255/231-u[0]/ u[1]*255/231+u[0])+1)/2' d0ndvi.png
convert d0-2017-10-13.jpg -fx "((u.b*255/231-u.r)/(u.b*255/231+u.r)+1)/2" d0ndvi2.png

I expected the two images to be identical. Why are they different?

https://www.flickr.com/photos/152450284@N03/
The first is d0ndvi.png
The second is d0ndvi2.png

User avatar
fmw42
Posts: 22109
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: I don't understand color calculation

Post by fmw42 » 2017-10-21T11:17:57-07:00

'((u[1]*255/231-u[0]/u[1]*255/231+u[0])+1)/2
Parenthesis problem. Divides happen before adds or subtracts. In the above you have u[0]/u[1] which is not what you want. So you need to put paretheses around your subtracts before dividing.

Code: Select all

'((u[1]*255/231-u[0])/(u[1]*255/231+u[0])+1)/2

supermax
Posts: 6
Joined: 2017-05-10T09:42:36-07:00
Authentication code: 1151

Re: I don't understand color calculation

Post by supermax » 2017-10-22T09:41:01-07:00

It is not a parenthesis is problem. It gives the same solution because subtraction come later than division.
I think I found the solution converting to text file:
convert image.png image.txt
supermax wrote:
2017-10-21T11:12:39-07:00
convert d0-2017-10-13.jpg -separate -delete 1 -fx '((u[1]*255/231-u[0]/ u[1]*255/231+u[0])+1)/2' d0ndvi.png
replies a b/n image in which the minimum value become '0' and the maximum '255'.
supermax wrote:
2017-10-21T11:12:39-07:00
convert d3-2017-10-13.jpg -fx "((u.b-u.r)/(u.b+u.r)+1)/2" d0ndvi2.png
the range of the results is between 0 and 1
replies an image in which values are proportionally ranged between 0 and 255.
0.5 become 128

thanke you all!
Last edited by supermax on 2017-10-23T02:59:19-07:00, edited 1 time in total.

User avatar
fmw42
Posts: 22109
Joined: 2007-07-02T17:14:51-07:00
Location: Sunnyvale, California, USA

Re: I don't understand color calculation [solved]

Post by fmw42 » 2017-10-22T10:37:07-07:00

'((u[1]*255/231-u[0]/u[1]*255/231+u[0])+1)/2
In this statement, the order of processing is something like:

u[1]*255/231

u[0]/u[1]*255/231

u[0]

then subtract the first and second terms and add the third. That is not what you want.

You want

((u[1]*255/231-u[0])

(u[1]*255/231+u[0]))

then divide the first by the second.

That is why I added the extra parens in these last two expressions

Post Reply