PixInsight Forum (historical)
Software Development => PCL and PJSR Development => Topic started by: Nocturnal on 2009 July 06 19:57:40
-
Hi,
decided to pick up my profile tool again. It can now plot RGB, R, G and B curves. Clearly it would be nice if it could do L and S curves as well. Trouble is I don't know how to derive these values from an image. I defined a little macro for grabbing R, G and B values:
#define GETPIXEL(x,y) { \
for (color = 0; color < numChannels; color++) {\
P::FromSample(theInterface->theProfile[pIndex].colors[color],\
img.Pixel(x,y, color));\
theInterface->theProfile[pIndex].p.x = x;\
theInterface->theProfile[pIndex].p.y = y;\
}\
}
The P::FromSample is the magic sauce that converts the img.Pixel to the right format. I've looked at the PixelTraits documentation but nothing springs out except the headache it gives me :)
If I can derive Luminance and Saturation from the stored R, G and B values that would be even better. I mean I know I *can* but I don't know how.
Thanks,
Sander
-
Hi Sander,
Sorry for the late answer. Of course you can. Assuming that img is a RGB color image in the code below:
Generic2DImage<P> img;
// ...
RGBColorSystem::sample r, g, b;
Point pos;
P::FromSample( r, img.Pixel( pos, 0 ) );
P::FromSample( g, img.Pixel( pos, 1 ) );
P::FromSample( b, img.Pixel( pos, 2 ) );
// Nonlinear luminance (CIE L* component)
RGBColorSystem::sample L = img.RGBWorkingSpace().CIEL( r, g, b );
// Linear (as long as gamma=1) luminance (CIE Y component)
RGBColorSystem::sample Y = img.RGBWorkingSpace().CIEY( r, g, b );
// Color saturation in the HSV color ordering system
RGBColorSystem::sample Sv = RGBColorSystem::HSVSaturation( r, g, b );
// Color saturation in the HSI color ordering system
RGBColorSystem::sample Si = RGBColorSystem::HSISaturation( r, g, b );
Note that HSVSaturation() and HSISaturation() are both static member functions of RGBColorSystem, so their calculation does not depend on a particular RGB working space, as is the case for CIE components. This is because HSV and HSI are not color spaces (in the strict colorimetric sense defined by PI/PCL) but just color ordering systems, or different representations of the RGB color cube.
The S curve in CurvesTransformation corresponds to the S element of HSV. As an alternative, you can use the CIE c* component, which also represents color saturation (the c curve of CurvesTransformation) with a strict colorimetric basis.
-
Thanks Juan, that looks easy enough. I'll add that and see if I can put out a beta version for people to try.
-
Hi,
ok, not so easy :) VC++ doesn't like it very much.
Here's part of a macro I use:
case CurveTypeParameter::HSVSCurve:\
P::FromSample( r, img.Pixel( x, y, 0 ) );\
P::FromSample( g, img.Pixel( x, y, 1 ) );\
P::FromSample( b, img.Pixel( x, y, 2 ) );\
theInterface->theProfile[pIndex].colors[0] = RGBColorSystem::HSVSaturation( r, g, b );\
break;\
case CurveTypeParameter::HSISCurve:\
P::FromSample( r, img.Pixel( x, y, 0 ) );\
P::FromSample( g, img.Pixel( x, y, 1 ) );\
P::FromSample( b, img.Pixel( x, y, 2 ) );\
theInterface->theProfile[pIndex].colors[0] = RGBColorSystem::HSISaturation( r, g, b );\
break;\
VS2008 complains:
1>..\ProfileInterface.cpp(440) : error C2352: 'pcl::RGBColorSystem::HSVSaturation' : illegal call of non-static member function
1> c:\pcl64\include\pcl/RGBColorSystem.h(457) : see declaration of 'pcl::RGBColorSystem::HSVSaturation'
1>..\ProfileInterface.cpp(440) : error C2352: 'pcl::RGBColorSystem::HSISaturation' : illegal call of non-static member function
1> c:\pcl64\include\pcl/RGBColorSystem.h(478) : see declaration of 'pcl::RGBColorSystem::HSISaturation'
What do I do? The part where I use the img object compiles fine. I also tried to avoid the intermediate assignment to r, g and b by feeding Pixel(x, y, 0) etc into the parameters but that didn't seem to work. I guess I can try that again once I get this code working.
-
Oops! My mistake! :-[
Since a few PCL versions, HSVSaturation and similar functions are no longer static member functions of RGBColorSystem (the reasons are complex and deeply involved with PCL internals). So you need an instance of RGBColorSystem in order to invoke them. I forgot this fact, and hence my answer to your question was incorrect.
Just call:
img.RGBWorkingSpace().HSVSaturation( r, g, b ); // CORRECT
img.RGBWorkingSpace().HSISaturation( r, g, b );
etc., instead of:
RGBColorSystem::HSVSaturation( r, g, b ); // WRONG
RGBColorSystem::HSISaturation( r, g, b );
and your macros should work fine. Let me know.
-
Thanks Juan, that did it. I'll upload a 64 bit windows DynamicProfile module soon.