25 #include "ImageConvert.hh"
34 template <
class StorageType>
50 BIASERR(
"ImageConvert::ToHSL() should be called with images of"\
57 res = RGBToHSL_(source,dest);
60 res = BGRToHSL_(source,dest);
63 res = BGRAToHSL_(source,dest);
68 res = ToHSL(tmp,dest);
72 BIASERR(
"Image::ToHSL(): color model not implemented for "<<
82 template <
class StorageType>
86 BIASERR(
"ImageConvert::RGBToHSL only for <float> and <unsgined char> not "<<
97 BIASWARN(
"Unnecessary image copy operation. This may hurt performance.");
101 register float *G = NULL , *B = NULL;
102 register float *ImageDataEnd =
105 register float *S = NULL , *L = NULL;
106 register float Min = 0, Max = 0;
107 float MinVal = 0, MaxVal = 0;
118 if ( (MinVal < 0.0) || (MaxVal > 1.0) )
127 while (R < ImageDataEnd){
129 if ( (*R >= *G) && (*R >= *B) ){
135 }
else if (*G >= *B){
148 *L = (Max + Min) / 2.0f;
154 if ((*L) < 0.5 ) *S=(Max-Min)/(Max+Min);
155 else *S=(Max-Min)/(2.0f-Max-Min);
158 *H = (*G - *B)/(Max - Min);
160 *H = 2.0f + (*B - *R)/(Max - Min);
162 *H = 4.0f + (*R - *G)/(Max - Min);
181 while (R < ImageDataEnd){
184 for (
register int i = 1; i < 3; i++){
192 *L = (Max + Min) / 2.0f;
198 if ((*L) < 0.5 ) *S=(Max-Min)/(Max+Min);
199 else *S=(Max-Min)/(2.0f-Max-Min);
202 *H = (*G - *B)/(Max - Min);
204 *H = 2.0f + (*B - *R)/(Max - Min);
206 *H = 4.0f + (*R - *G)/(Max - Min);
235 BIASERR(
"source not in RGB format");
239 register const unsigned char *R = source.
GetImageData();
240 register const unsigned char *ImageDataEnd =
243 register const unsigned char *G = NULL, *B = NULL;
244 register unsigned char *S = NULL, *L = NULL;
245 register int Min = 0, Max = 0;
246 register int delta,TmpH;
253 while (R < ImageDataEnd){
256 if (Max < *G) Max=*G;
257 if (Max < *B) Max=*B;
258 if (Min > *G) Min=*G;
259 if (Min > *B) Min=*B;
261 *L = (
unsigned char)((Max + Min) / 2);
270 *S= (
unsigned char)(int(255*delta)/ int(Max+Min));
271 else *S= (
unsigned char)(
int(255*delta)/int(510-Max-Min));
275 TmpH = (255 * (*G - *B)) / delta;
277 TmpH = 510 + (255 * (*B - *R)) / delta;
279 TmpH = 1020 + (255 * (*R - *G)) / delta;
282 *H = (
unsigned char)(TmpH + 255);
284 *H = (
unsigned char)TmpH;
288 H++; S++; L++; R++; G++; B++;
297 while (R < ImageDataEnd){
300 if (Max < *G) Max=*G;
301 if (Max < *B) Max=*B;
302 if (Min > *G) Min=*G;
303 if (Min > *B) Min=*B;
305 *L = (
unsigned char)((Max + Min) / 2);
315 *S= (
unsigned char)rint(
float(255*delta)/
float(Max+Min));
316 else *S= (
unsigned char)rint(
float(255*delta)/float(510-Max-Min));
320 TmpH = (255 * (*G - *B)) / delta;
322 TmpH = 510 + (255 * (*B - *R)) / delta;
324 TmpH = 1020 + (255 * (*R - *G)) / delta;
327 *H = (
unsigned char)(TmpH + 255);
329 *H = (
unsigned char)TmpH;
347 template <
class StorageType>
351 BIASERR(
"ImageConvert::BGRToHSL only for <unsgined char> not "<<
367 BIASERR(
"source not in BGR format");
371 register const unsigned char *B = source.
GetImageData();
372 register const unsigned char *ImageDataEnd =
375 register const unsigned char *G = NULL, *R = NULL;
376 register unsigned char *S = NULL, *L = NULL;
377 register unsigned char Min = 0, Max = 0;
378 register int delta,TmpH;
385 while (B < ImageDataEnd){
388 if (Max < *G) Max=*G;
389 if (Max < *B) Max=*B;
390 if (Min > *G) Min=*G;
391 if (Min > *B) Min=*B;
393 *L = (Max + Min) / 2;
402 *S= (
unsigned char)((255*delta)/ (Max+Min));
403 else *S= (
unsigned char)((255*delta)/(510-delta));
406 TmpH = (255 * (*G - *B)) / delta;
408 TmpH = 510 + (255 * (*B - *R)) / delta;
410 TmpH = 1020 + (255 * (*R - *G)) / delta;
413 *H = (
unsigned char)(TmpH + 255);
415 *H = (
unsigned char)TmpH;
419 H++; S++; L++; R++; G++; B++;
428 while (B < ImageDataEnd){
431 if (Max < *G) Max=*G;
432 if (Max < *B) Max=*B;
433 if (Min > *G) Min=*G;
434 if (Min > *B) Min=*B;
436 *L = (Max + Min) / 2;
445 *S= (
unsigned char)((255*delta)/ (Max+Min));
446 else *S= (
unsigned char)((255*delta)/(510-delta));
449 TmpH = (255 * (*G - *B)) / delta;
451 TmpH = 510 + (255 * (*B - *R)) / delta;
453 TmpH = 1020 + (255 * (*R - *G)) / delta;
456 *H = (
unsigned char)(TmpH + 255);
458 *H = (
unsigned char)TmpH;
476 template <
class StorageType>
480 BIASERR(
"ImageConvert::BGRAToHSL only for <unsgined char> not "<<
496 BIASERR(
"source not in BGRA format");
500 register const unsigned char *B = source.
GetImageData();
501 register const unsigned char *ImageDataEnd =
504 register const unsigned char *G = NULL, *R = NULL;
505 register unsigned char *S = NULL, *L = NULL;
506 register unsigned char Min = 0, Max = 0;
507 register int delta,TmpH;
510 BIASERR(
"BGRAToHSL_() not for planar images");
517 while (B < ImageDataEnd){
520 if (Max < *G) Max=*G;
521 if (Max < *B) Max=*B;
522 if (Min > *G) Min=*G;
523 if (Min > *B) Min=*B;
525 *L = (Max + Min) / 2;
534 *S= (
unsigned char)((255*delta)/ (Max+Min));
535 else *S= (
unsigned char)((255*delta)/(510-delta));
538 TmpH = (255 * (*G - *B)) / delta;
540 TmpH = 510 + (255 * (*B - *R)) / delta;
542 TmpH = 1020 + (255 * (*R - *G)) / delta;
545 *H = (
unsigned char)(TmpH + 255);
547 *H = (
unsigned char)TmpH;
569 template <
class StorageType>
584 BIASERR(
"ImageConvert::TohsL() should be called with images of"\
591 res = RGBTohsL_(source,dest);
594 BIASERR(
"Image::TohsL(): color model not implemented for "<<
602 template <
class StorageType>
606 BIASERR(
"ImageConvert::RGBTohsL only for <int> and <unsigned char> and <float> (bit depth 8 for each type)"<<
622 BIASERR(
"source not in RGB format");
627 register const int *ImageDataEnd =
630 register const int *G = NULL, *B = NULL;
631 register int *s = NULL, *L = NULL;
632 register int Min = 0, Max = 0;
633 register int delta,hTemp,sTemp;
635 register float d=0,sat;
637 BIASERR(
"not yet implemented");
643 while (R < ImageDataEnd){
646 if (Max < *G) Max=*G;
647 if (Max < *B) Max=*B;
648 if (Min > *G) Min=*G;
649 if (Min > *B) Min=*B;
651 *L = (Max + Min) / 2;
655 sTemp= 2*(*R) - *G - *B;
656 d=float(sqrt(
double(hTemp*hTemp + sTemp*sTemp)));
659 if ( (delta==0) || (d<1E-07) ) {
665 sat= (float)((255*delta)/ (Max+Min));
666 else sat= (float)((255*delta)/(510-delta));
668 *h= (int)((
float)hTemp * sat / d + 0.5);
669 *s= (int)((
float)sTemp * sat / d + 0.5);
699 BIASERR(
"source not in RGB format");
704 register const float *ImageDataEnd =
707 register const float *G = NULL, *B = NULL;
708 register float *s = NULL, *L = NULL;
709 register float Min = 0, Max = 0;
710 register float delta,hTemp,sTemp;
712 register float d=0,sat;
714 BIASERR(
"not yet implemented");
720 while (R < ImageDataEnd){
723 if (Max < *G) Max=*G;
724 if (Max < *B) Max=*B;
725 if (Min > *G) Min=*G;
726 if (Min > *B) Min=*B;
728 *L = (Max + Min) / 2;
732 sTemp= 2*(*R) - *G - *B;
733 d=float(sqrt(
double(hTemp*hTemp + sTemp*sTemp)));
736 if ( (delta==0) || (d<1E-07) ) {
742 sat= (float)((255*delta)/ (Max+Min));
743 else sat= (float)((255*delta)/(510-delta));
745 *h= (float)hTemp * sat / d + 0.5f;
746 *s= (float)sTemp * sat / d + 0.5f;
776 BIASERR(
"source not in RGB format");
780 register const unsigned char *R = source.
GetImageData();
781 register const unsigned char *ImageDataEnd =
784 register const unsigned char *G = NULL, *B = NULL;
785 register unsigned char *s = NULL;
786 register unsigned char *L = NULL;
787 register unsigned char Min = 0, Max = 0;
788 register unsigned char delta;
789 register float hTemp,sTemp;
791 register float d=0,sat;
793 BIASERR(
"not yet implemented");
799 while (R < ImageDataEnd){
802 if (Max < *G) Max=*G;
803 if (Max < *B) Max=*B;
804 if (Min > *G) Min=*G;
805 if (Min > *B) Min=*B;
807 *L = (Max + Min) / 2;
810 hTemp= float((
int)*G - (
int)*B);
811 sTemp= float(2*(
int)(*R) - (
int)*G - (
int)*B);
812 d=float(sqrt(
double(hTemp*hTemp + sTemp*sTemp)));
815 if ( (delta==0) || (d<1E-07) ) {
821 sat= (float)((127*delta)/ (Max+Min));
822 else sat= (float)((127*delta)/(510-delta));
824 *h= (
unsigned char)(hTemp * sat / d + 127.5);
825 *s= (
unsigned char)(sTemp * sat / d + 127.5);
843 template <
class StorageType>
849 BIASERR(
"source not in HSL format");
853 BIASERR(
"not implemented properly, fix first, only working for float right now")
869 BIASERR(
"Only for interleaved images!");
878 for(
int y = 0; y<(int)height; y++){
879 for(
int x = 0; x<(int)width; x++){
881 float H = float(idaS[y][x*3])/360.0f;
882 float S = float(idaS[y][x*3+1]);
883 float L = float(idaS[y][x*3+2]);
887 idaTmp[y][x*3] = idaTmp[y][x*3+1] = idaTmp[y][x*3+2] = L;
889 float tmp1=0.0,tmp2=0.0,tmp3R=0.0, tmp3G=0.0, tmp3B=0.0;
890 if(L<0.5f) tmp2 = L*(1.0f+S);
891 else if (L >=0.5f) tmp2 = (L+S)-(L*S);
895 tmp3R = H+(1.0f/3.0f);
if(tmp3R<0) tmp3R+=1.0f;
if(tmp3R>1) tmp3R-=1.0f;
896 tmp3G = H;
if(tmp3G<0) tmp3G+=1.0f;
if(tmp3G>1) tmp3G-=1.0f;
897 tmp3B = H-(1.0f/3.0f);
if(tmp3B<0) tmp3B+=1.0f;
if(tmp3B>1) tmp3B-=1.0f;
899 if((tmp3R*6.0f) < 1) idaTmp[y][x*3] = tmp1+(tmp2-tmp1)*6.0f*tmp3R;
900 else if((tmp3R*2.0f) < 1) idaTmp[y][x*3]=tmp2;
901 else if((tmp3R*3.0f) < 2) idaTmp[y][x*3]=tmp1+(tmp2-tmp1)*((2.0f/3.0f)-tmp3R)*6.0f;
902 else idaTmp[y][x*3]=tmp1;
904 if((tmp3G*6.0f) < 1) idaTmp[y][x*3+1] = tmp1+(tmp2-tmp1)*6.0f*tmp3G;
905 else if((tmp3G*2.0f) < 1) idaTmp[y][x*3+1]=tmp2;
906 else if((tmp3G*3.0f) < 2) idaTmp[y][x*3+1]=tmp1+(tmp2-tmp1)*((2.0f/3.0f)-tmp3G)*6.0f;
907 else idaTmp[y][x*3+1]=tmp1;
909 if((tmp3B*6.0f) < 1) idaTmp[y][x*3+2] = tmp1+(tmp2-tmp1)*6.0f*tmp3B;
910 else if((tmp3B*2.0f) < 1) idaTmp[y][x*3+2]=tmp2;
911 else if((tmp3B*3.0f) < 2) idaTmp[y][x*3+2]=tmp1+(tmp2-tmp1)*((2.0f/3.0f)-tmp3B)*6.0f;
912 else idaTmp[y][x*3+2]=tmp1;
917 idaD[y][x*3] = StorageType(idaTmp[y][x*3]*(255.0));
918 idaD[y][x*3+1] = StorageType(idaTmp[y][x*3+1]*(255.0));
919 idaD[y][x*3+2] = StorageType(idaTmp[y][x*3+2]*(255.0));
hsl, similar to HSL but euclidean (h,s) for CNCC
static int BGRAToHSL_(const Image< StorageType > &source, Image< StorageType > &dest)
HSL, similar to HSV but space is a double tipped cone.
bool IsEmpty() const
check if ImageData_ points to allocated image buffer or not
int ScaleShiftBetween(double Min, double Max)
scales and shifts image so afterwards every pixel has a value between Min and Max ...
void SetColorModel(EColorModel Model)
unsigned int GetSizeByte() const
returns the nr.
static BIASImageBase_EXPORT int ToHSL(const Image< StorageType > &source, Image< StorageType > &dest)
Create a HSL converted copy of source image in this Release() and Init() are called if necessary...
static int HSLToRGB_(const BIAS::Image< StorageType > &source, BIAS::Image< StorageType > &dest)
void GetMinMaxPixelValue(StorageType &min, StorageType &max, unsigned short int channel=0, unsigned int *mincoo=NULL, unsigned int *maxcoo=NULL) const
returns the minimal and maximal pixel value in channel only Finds minimum and maximum pixel value in ...
unsigned int GetWidth() const
unsigned int GetBitDepth() const
returns the bits per channel Is not necessairily 8*sizeof(StorageType), could be fewer bits...
static BIASImageBase_EXPORT int TohsL(const Image< StorageType > &source, Image< StorageType > &dest)
Create a hsL converted copy of source image in this Release() and Init() are called if necessary...
void SetInterleaved(bool interleaved)
color values, 3 channels, order: blue,green,red
static int ConvertST(const BIAS::ImageBase &source, BIAS::ImageBase &dest, ImageBase::EStorageType targetST)
Function to convert the storage type of images e.g.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
color values, 3 channels, order: red,green,blue
unsigned int GetHeight() const
UYVY422, 2 channels, full luminance Y, subsampled half U,V inverse order.
static int RGBToHSL_(const Image< StorageType > &source, Image< StorageType > &dest)
The image template class for specific storage types.
static int BGRToHSL_(const Image< StorageType > &source, Image< StorageType > &dest)
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same "size" as Image of other type
void Init(unsigned int Width, unsigned int Height, unsigned int channels=1, enum EStorageType storageType=ST_unsignedchar, const bool interleaved=true)
calls Init from ImageBase storageType is ignored, just dummy argument
const StorageType * GetImageData() const
overloaded GetImageData() from ImageBase
enum EColorModel GetColorModel() const
enum EStorageType GetStorageType() const
static int RGBTohsL_(const Image< StorageType > &source, Image< StorageType > &dest)
unsigned long int GetPixelCount() const
returns number of pixels in image
static int ToRGB(const Image< StorageType > &source, Image< StorageType > &dest)
Create a RGB converted copy of source image in this.
BGRA color values, 4 channels, order: blue,green,red,alpha.
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase