1 #include "HistogramEqualization.hh"
2 #include <Image/HistogramImage.hh>
3 #include <Base/Image/ImageIO.hh>
9 template <
class InputStorageType,
class OutputStorageType>
14 BIASERR(
"HistogramEqualization: not for multiple channel images");
27 unsigned bincount =(unsigned) (1.0 + std::numeric_limits<InputStorageType>::max() +
28 fabs((
double) std::numeric_limits<InputStorageType>::min()));
30 hsrc.
AddHist<InputStorageType>(src);
35 map<unsigned,unsigned> filledbins;
37 for(
unsigned b=0; b<binnum; b++){
38 unsigned val = (unsigned) hsrc.
GetBin(b);
45 map<unsigned,unsigned>::iterator it;
47 map<InputStorageType,InputStorageType> NewGreyVal;
50 double maxval = (double)std::numeric_limits<InputStorageType>::max();
51 double minval = (double)std::numeric_limits<InputStorageType>::min();
52 double valrange = (maxval-minval);
53 for(it=filledbins.begin(); it != filledbins.end(); it++){
54 sum+= (double) it->second;
55 InputStorageType oldgreyvalue = (InputStorageType)
56 (it->first - fabs((
double) std::numeric_limits<InputStorageType>::min()));
57 NewGreyVal[oldgreyvalue] = (InputStorageType)
58 (((sum/(
double)pixnum)*valrange)+minval);
67 for(
unsigned y=0; y<hei; y++)
68 for(
unsigned x=0; x<wid; x++){
70 InputStorageType oldgreyval = pDat[y][x];
72 pDstDat[y][x]= (OutputStorageType) NewGreyVal[oldgreyval];
80 template <
class InputStorageType,
class OutputStorageType>
83 unsigned int numRows,
unsigned int numCols){
86 BIASERR(
"HistogramEqualization: not for multiple channel images");
95 unsigned int imWidth = src.
GetWidth();
97 unsigned int numPxCellx = imWidth/numRows;
98 unsigned int numPxCelly = imHeight/numCols;
101 BIASERR(
"bit depth not set in image ");
105 unsigned int histoSize = 1;
106 for (
unsigned int i = 0; i < src.
GetBitDepth(); i++){
111 vector<vector<unsigned int> > histograms(numRows*numCols, vector<unsigned int>(histoSize, 0));
112 vector<vector<unsigned int> > newGreyVals(numRows*numCols, vector<unsigned int>(histoSize, 0));
113 vector<unsigned int> histoPixNum(numRows*numCols, 0);
114 vector<Vector2<unsigned int> > cellCenters(numRows*numCols);
118 unsigned int startInCellX=0, startInCellY=0;
119 unsigned int endInCellX=0, endInCellY=0;
120 unsigned int histoCount=0;
121 InputStorageType val=0;
122 for(
unsigned int cx=0; cx < numRows; cx++){
123 for(
unsigned int cy=0; cy < numCols; cy++){
124 startInCellX = cx*numPxCellx;
125 startInCellY = cy*numPxCelly;
126 endInCellX = (cx+1)*numPxCellx;
127 endInCellY = (cy+1)*numPxCelly;
128 histoCount = numRows*cy+cx;
131 (endInCellY-numPxCelly/2));
133 for(
unsigned int x=startInCellX; x < endInCellX; x++){
134 for(
unsigned int y=startInCellY; y < endInCellY; y++){
136 if(val < minCutOff_) val = minCutOff_;
137 if(val > maxCutOff_) val = maxCutOff_;
138 histograms[histoCount][val]++;
144 for(
unsigned int hs=0; hs < histoSize; hs++){
145 histoPixNum[histoCount] += histograms[histoCount][hs];
150 double maxval = (double)std::numeric_limits<InputStorageType>::max();
151 double minval = (double)std::numeric_limits<InputStorageType>::min();
152 double valrange = (maxval-minval);
153 for(
unsigned int hs=0; hs < histoSize; hs++){
154 sum+= (double) histograms[histoCount][hs];
155 InputStorageType oldgreyvalue = (InputStorageType)
156 (hs - fabs((
double) std::numeric_limits<InputStorageType>::min()));
157 newGreyVals[histoCount][oldgreyvalue] = (InputStorageType)
158 (((sum/(
double)histoPixNum[histoCount])*valrange)+minval);
171 unsigned int cx1 = 0;
172 unsigned int cx2 = 0;
173 unsigned int cy1 = 0;
174 unsigned int cy2 = 0;
175 double distx1=0, distx2=0;
176 double disty1=0, disty2=0;
177 int xm1=0, xm2=0, ym1=0, ym2=0;
178 for(
unsigned y=0; y<imHeight; y++){
179 for(
unsigned x=0; x<imWidth; x++){
181 xm1 = ((int)x-numPxCellx/2);
182 xm2 = ((int)x+numPxCellx/2);
183 ym1 = ((int)y-numPxCelly/2);
184 ym2 = ((int)y+numPxCelly/2);
189 if(xm2 >= (
int)imWidth) xm2 = imWidth-1;
191 if(ym2 >= (
int)imHeight) ym2 = imHeight-1;
193 cx1 = xm1 / numPxCellx;
194 cx2 = xm2 / numPxCellx;
195 cy1 = ym1 / numPxCelly;
196 cy2 = ym2 / numPxCelly;
198 if(cx2 >= numRows) cx2 = numRows-1;
199 if(cy2 >= numCols) cy2 = numCols-1;
201 distx1 = fabs((
double)x-(
double)cellCenters[cy1*numRows+cx1][0]);
202 distx2 = fabs((
double)cellCenters[cy1*numRows+cx2][0]-(
double)x);
203 disty1 = fabs((
double)y-(
double)cellCenters[cy1*numRows+cx1][1]);
204 disty2 = fabs((
double)cellCenters[cy2*numRows+cx2][1]-(
double)y);
207 distx1 /= numPxCellx;
208 distx2 /= numPxCellx;
209 disty1 /= numPxCelly;
210 disty2 /= numPxCelly;
213 distx2 = 1.0 - distx1;
216 disty2 = 1.0 - disty1;
226 InputStorageType oldgreyval = srcPtr[y][x];
227 unsigned int oldIndex = (
unsigned int)oldgreyval;
236 pDstDat[y][x]= (OutputStorageType) (w00*newGreyVals[cy1*numRows+cx1][oldIndex] +
237 w01*newGreyVals[cy1*numRows+cx2][oldIndex] +
238 w10*newGreyVals[cy2*numRows+cx1][oldIndex] +
239 w11*newGreyVals[cy2*numRows+cx2][oldIndex]);
248 #define INST(intype,outtype) \
249 template class BIASImage_EXPORT HistogramEqualization<intype,outtype>;
252 INST(
unsigned char,
unsigned char)
void Release()
reimplemented from ImageBase
int AboveThresholdToValue(StorageType Threshold, StorageType Value)
sets alls pixels with values above Threshold to Value
class for handling different region of interest (ROI) representations...
int InitHist(unsigned int bincount=256, unsigned int histcount=1)
reserves the internal data structures for histcount histograms with bincount bins in each in one imag...
int BelowThresholdToValue(StorageType Threshold, StorageType Value)
sets alls pixels with values below Threshold to Value
int AdaptiveHistogramEqualization(const Image< InputStorageType > &src, Image< OutputStorageType > &dst, unsigned int numRows=8, unsigned int numCols=8)
unsigned int GetWidth() const
unsigned int GetBitDepth() const
returns the bits per channel Is not necessairily 8*sizeof(StorageType), could be fewer bits...
double GetBin(unsigned int bin, unsigned int hist=0)
Get the counted number of bin from hist, -1 for invalid bin/hist.
int AddHist(const Image< StorageType > &Image, unsigned int hist=0)
calculates the histogram of image and adds them to the internal data structures
ROI * GetROI()
Returns a pointer to the roi object.
bool IsInROI(const double &x, const double &y) const
ROI check if pixel position is inside the ROI.
unsigned int GetChannelCount() const
returns the number of Color channels, e.g.
unsigned int GetHeight() const
bool SamePixelAndChannelCount(const ImageBase &Image) const
checks if data area has same "size" as Image of other type
Class for easy histogram image generation.
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
virtual int Filter(const Image< InputStorageType > &src, Image< OutputStorageType > &dst)
prototyp for filter computation function
unsigned int GetBinCount()
const StorageType ** GetImageDataArray() const
overloaded GetImageDataArray() from ImageBase