Commit 3f57c39b authored by Sebastien Barre's avatar Sebastien Barre
Browse files

FIX: the vtkImageRGBToHSV and vtkImageHSVToRGB were actually doing HSI<->RGB...

FIX: the vtkImageRGBToHSV and vtkImageHSVToRGB were actually doing HSI<->RGB conversion. Fix those, and keep the old implementation as RGB<->HSI filters.
parent f70feea2
......@@ -51,6 +51,7 @@ vtkImageGaussianSource.cxx
vtkImageGradient.cxx
vtkImageGradientMagnitude.cxx
vtkImageGridSource.cxx
vtkImageHSIToRGB.cxx
vtkImageHSVToRGB.cxx
vtkImageHybridMedian2D.cxx
vtkImageIdealHighPass.cxx
......@@ -81,6 +82,7 @@ vtkImagePadFilter.cxx
vtkImagePermute.cxx
vtkImageQuantizeRGBToIndex.cxx
vtkImageRFFT.cxx
vtkImageRGBToHSI.cxx
vtkImageRGBToHSV.cxx
vtkImageRange3D.cxx
vtkImageRectilinearWipe.cxx
......
......@@ -47,6 +47,7 @@ IF (VTK_USE_RENDERING)
TestFFTCorrelation
TestGradientMagnitude
TestGradientMagnitude2
TestHSIToRGB
TestHSVToRGB
TestHybridMedian2D
TestIdealLowPass
......
# Use the painter to draw using colors.
# This is not a pipeline object. It will support pipeline objects.
# Please do not use this object directly.
package require vtk
vtkImageCanvasSource2D imageCanvas
imageCanvas SetNumberOfScalarComponents 3
imageCanvas SetScalarTypeToUnsignedChar
imageCanvas SetExtent 0 320 0 320 0 0
imageCanvas SetDrawColor 0 0 0
imageCanvas FillBox 0 511 0 511
# r, g, b
imageCanvas SetDrawColor 255 0 0
imageCanvas FillBox 0 50 0 100
imageCanvas SetDrawColor 128 128 0
imageCanvas FillBox 50 100 0 100
imageCanvas SetDrawColor 0 255 0
imageCanvas FillBox 100 150 0 100
imageCanvas SetDrawColor 0 128 128
imageCanvas FillBox 150 200 0 100
imageCanvas SetDrawColor 0 0 255
imageCanvas FillBox 200 250 0 100
imageCanvas SetDrawColor 128 0 128
imageCanvas FillBox 250 300 0 100
# intensity scale
imageCanvas SetDrawColor 5 5 5
imageCanvas FillBox 0 50 110 210
imageCanvas SetDrawColor 55 55 55
imageCanvas FillBox 50 100 110 210
imageCanvas SetDrawColor 105 105 105
imageCanvas FillBox 100 150 110 210
imageCanvas SetDrawColor 155 155 155
imageCanvas FillBox 150 200 110 210
imageCanvas SetDrawColor 205 205 205
imageCanvas FillBox 200 250 110 210
imageCanvas SetDrawColor 255 255 255
imageCanvas FillBox 250 300 110 210
# saturation scale
imageCanvas SetDrawColor 245 0 0
imageCanvas FillBox 0 50 220 320
imageCanvas SetDrawColor 213 16 16
imageCanvas FillBox 50 100 220 320
imageCanvas SetDrawColor 181 32 32
imageCanvas FillBox 100 150 220 320
imageCanvas SetDrawColor 149 48 48
imageCanvas FillBox 150 200 220 320
imageCanvas SetDrawColor 117 64 64
imageCanvas FillBox 200 250 220 320
imageCanvas SetDrawColor 85 80 80
imageCanvas FillBox 250 300 220 320
vtkImageRGBToHSI convert
convert SetInput [imageCanvas GetOutput]
vtkImageHSIToRGB convertBack
convertBack SetInput [convert GetOutput]
vtkImageCast cast
cast SetInput [convertBack GetOutput]
cast SetOutputScalarTypeToFloat
cast ReleaseDataFlagOff
vtkImageViewer viewer
viewer SetInput [convertBack GetOutput]
#viewer SetInput [imageCanvas GetOutput]
viewer SetColorWindow 256
viewer SetColorLevel 127.5
viewer Render
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageHSIToRGB.cxx
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkImageHSIToRGB.h"
#include "vtkImageData.h"
#include "vtkImageProgressIterator.h"
#include "vtkObjectFactory.h"
#include <math.h>
vtkCxxRevisionMacro(vtkImageHSIToRGB, "1.1");
vtkStandardNewMacro(vtkImageHSIToRGB);
//----------------------------------------------------------------------------
vtkImageHSIToRGB::vtkImageHSIToRGB()
{
this->Maximum = 255.0;
}
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
template <class T>
void vtkImageHSIToRGBExecute(vtkImageHSIToRGB *self,
vtkImageData *inData,
vtkImageData *outData,
int outExt[6], int id, T *)
{
vtkImageIterator<T> inIt(inData, outExt);
vtkImageProgressIterator<T> outIt(outData, outExt, self, id);
float R, G, B, H, S, I;
float max = self->GetMaximum();
float temp;
float third = max / 3.0;
int idxC;
// find the region to loop over
int maxC = inData->GetNumberOfScalarComponents()-1;
// Loop through ouput pixels
while (!outIt.IsAtEnd())
{
T* inSI = inIt.BeginSpan();
T* outSI = outIt.BeginSpan();
T* outSIEnd = outIt.EndSpan();
while (outSI != outSIEnd)
{
// Pixel operation
H = (float)(*inSI); ++inSI;
S = (float)(*inSI); ++inSI;
I = (float)(*inSI); ++inSI;
// compute rgb assuming S = 1.0;
if (H >= 0.0 && H <= third) // red -> green
{
G = H/third;
R = 1.0 - G;
B = 0.0;
}
else if (H >= third && H <= 2.0*third) // green -> blue
{
B = (H - third)/third;
G = 1.0 - B;
R = 0.0;
}
else // blue -> red
{
R = (H - 2.0 * third)/third;
B = 1.0 - R;
G = 0.0;
}
// add Saturation to the equation.
S = S / max;
//R = S + (1.0 - S)*R;
//G = S + (1.0 - S)*G;
//B = S + (1.0 - S)*B;
// what happend to this?
R = S*R + (1.0 - S);
G = S*G + (1.0 - S);
B = S*B + (1.0 - S);
// Use intensity to get actual RGB
// normalize RGB first then apply intensity
temp = R + G + B;
//I = 3 * I / (temp * max);
// and what happend to this?
I = 3 * I / (temp);
R = R * I;
G = G * I;
B = B * I;
// clip below 255
//if (R > 255.0) R = max;
//if (G > 255.0) G = max;
//if (B > 255.0) B = max;
// mixed constant 255 and max ?????
if (R > max)
{
R = max;
}
if (G > max)
{
G = max;
}
if (B > max)
{
B = max;
}
// assign output.
*outSI = (T)(R); ++outSI;
*outSI = (T)(G); ++outSI;
*outSI = (T)(B); ++outSI;
for (idxC = 3; idxC <= maxC; idxC++)
{
*outSI++ = *inSI++;
}
}
inIt.NextSpan();
outIt.NextSpan();
}
}
//----------------------------------------------------------------------------
void vtkImageHSIToRGB::ThreadedExecute(vtkImageData *inData,
vtkImageData *outData,
int outExt[6], int id)
{
vtkDebugMacro(<< "Execute: inData = " << inData
<< ", outData = " << outData);
// this filter expects that input is the same type as output.
if (inData->GetScalarType() != outData->GetScalarType())
{
vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
<< ", must match out ScalarType " << outData->GetScalarType());
return;
}
// need three components for input and output
if (inData->GetNumberOfScalarComponents() < 3)
{
vtkErrorMacro("Input has too few components");
return;
}
if (outData->GetNumberOfScalarComponents() < 3)
{
vtkErrorMacro("Output has too few components");
return;
}
switch (inData->GetScalarType())
{
vtkTemplateMacro6(vtkImageHSIToRGBExecute,this, inData,
outData, outExt, id, static_cast<VTK_TT *>(0));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
void vtkImageHSIToRGB::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Maximum: " << this->Maximum << "\n";
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageHSIToRGB.h
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkImageHSIToRGB - Converts HSI components to RGB.
// .SECTION Description
// For each pixel with hue, saturation and intensity components this filter
// outputs the color coded as red, green, blue. Output type must be the same
// as input type.
// .SECTION See Also
// vtkImageRGBToHSI
#ifndef __vtkImageHSIToRGB_h
#define __vtkImageHSIToRGB_h
#include "vtkImageToImageFilter.h"
class VTK_IMAGING_EXPORT vtkImageHSIToRGB : public vtkImageToImageFilter
{
public:
static vtkImageHSIToRGB *New();
vtkTypeRevisionMacro(vtkImageHSIToRGB,vtkImageToImageFilter);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Hue is an angle. Maximum specifies when it maps back to 0.
// HueMaximum defaults to 255 instead of 2PI, because unsigned char
// is expected as input.
// Maximum also specifies the maximum of the Saturation, and R, G, B.
vtkSetMacro(Maximum,float);
vtkGetMacro(Maximum,float);
protected:
vtkImageHSIToRGB();
~vtkImageHSIToRGB() {};
float Maximum;
void ThreadedExecute(vtkImageData *inData, vtkImageData *outData,
int ext[6], int id);
private:
vtkImageHSIToRGB(const vtkImageHSIToRGB&); // Not implemented.
void operator=(const vtkImageHSIToRGB&); // Not implemented.
};
#endif
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageRGBToHSI.cxx
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkImageRGBToHSI.h"
#include "vtkImageData.h"
#include "vtkImageProgressIterator.h"
#include "vtkObjectFactory.h"
#include <math.h>
vtkCxxRevisionMacro(vtkImageRGBToHSI, "1.1");
vtkStandardNewMacro(vtkImageRGBToHSI);
//----------------------------------------------------------------------------
vtkImageRGBToHSI::vtkImageRGBToHSI()
{
this->Maximum = 255.0;
}
//----------------------------------------------------------------------------
// This templated function executes the filter for any type of data.
template <class T>
void vtkImageRGBToHSIExecute(vtkImageRGBToHSI *self,
vtkImageData *inData,
vtkImageData *outData,
int outExt[6], int id, T *)
{
vtkImageIterator<T> inIt(inData, outExt);
vtkImageProgressIterator<T> outIt(outData, outExt, self, id);
int idxC, maxC;
float R, G, B, H, S, I;
float max = self->GetMaximum();
float temp;
// find the region to loop over
maxC = inData->GetNumberOfScalarComponents()-1;
// Loop through ouput pixels
while (!outIt.IsAtEnd())
{
T* inSI = inIt.BeginSpan();
T* outSI = outIt.BeginSpan();
T* outSIEnd = outIt.EndSpan();
while (outSI != outSIEnd)
{
// Pixel operation
R = (float)(*inSI); inSI++;
G = (float)(*inSI); inSI++;
B = (float)(*inSI); inSI++;
// Saturation
temp = R;
if (G < temp)
{
temp = G;
}
if (B < temp)
{
temp = B;
}
float sumRGB = R+G+B;
if(sumRGB == 0.0)
{
S = 0.0;
}
else
{
S = max * (1.0 - (3.0 * temp / sumRGB));
}
temp = (float)(R + G + B);
// Intensity is easy
I = temp / 3.0;
// Hue
temp = sqrt((R-G)*(R-G) + (R-B)*(G-B));
if(temp != 0.0)
{
temp = acos((0.5 * ((R-G) + (R-B))) / temp);
}
if (G >= B)
{
H = max * (temp / 6.2831853);
}
else
{
H = max * (1.0 - (temp / 6.2831853));
}
// assign output.
*outSI = (T)(H); outSI++;
*outSI = (T)(S); outSI++;
*outSI = (T)(I); outSI++;
for (idxC = 3; idxC <= maxC; idxC++)
{
*outSI++ = *inSI++;
}
}
inIt.NextSpan();
outIt.NextSpan();
}
}
//----------------------------------------------------------------------------
void vtkImageRGBToHSI::ThreadedExecute(vtkImageData *inData,
vtkImageData *outData,
int outExt[6], int id)
{
vtkDebugMacro(<< "Execute: inData = " << inData
<< ", outData = " << outData);
// this filter expects that input is the same type as output.
if (inData->GetScalarType() != outData->GetScalarType())
{
vtkErrorMacro(<< "Execute: input ScalarType, " << inData->GetScalarType()
<< ", must match out ScalarType " << outData->GetScalarType());
return;
}
// need three components for input and output
if (inData->GetNumberOfScalarComponents() < 3)
{
vtkErrorMacro("Input has too few components");
return;
}
if (outData->GetNumberOfScalarComponents() < 3)
{
vtkErrorMacro("Output has too few components");
return;
}
switch (inData->GetScalarType())
{
vtkTemplateMacro6(vtkImageRGBToHSIExecute, this, inData,
outData, outExt, id, static_cast<VTK_TT *>(0));
default:
vtkErrorMacro(<< "Execute: Unknown ScalarType");
return;
}
}
void vtkImageRGBToHSI::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Maximum: " << this->Maximum << "\n";
}
/*=========================================================================
Program: Visualization Toolkit
Module: vtkImageRGBToHSI.h
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) 1993-2002 Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// .NAME vtkImageRGBToHSI - Converts RGB components to HSI.
// .SECTION Description
// For each pixel with red, blue, and green components this
// filter output the color coded as hue, saturation and intensity.
// Output type must be the same as input type.
#ifndef __vtkImageRGBToHSI_h
#define __vtkImageRGBToHSI_h
#include "vtkImageToImageFilter.h"
class VTK_IMAGING_EXPORT vtkImageRGBToHSI : public vtkImageToImageFilter
{
public:
static vtkImageRGBToHSI *New();
vtkTypeRevisionMacro(vtkImageRGBToHSI,vtkImageToImageFilter);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// Hue is an angle. Maximum specifies when it maps back to 0. HueMaximum
// defaults to 255 instead of 2PI, because unsigned char is expected as
// input. Maximum also specifies the maximum of the Saturation.
vtkSetMacro(Maximum,float);
vtkGetMacro(Maximum,float);
protected:
vtkImageRGBToHSI();
~vtkImageRGBToHSI() {};
float Maximum;
void ThreadedExecute(vtkImageData *inData, vtkImageData *outData,
int ext[6], int id);
private:
vtkImageRGBToHSI(const vtkImageRGBToHSI&); // Not implemented.
void operator=(const vtkImageRGBToHSI&); // Not implemented.
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment