|
@@ -37,17 +37,10 @@ P & MultiChannelImage3DT<P>::operator() (int x, int y, int z, uint channel)
|
|
}
|
|
}
|
|
|
|
|
|
template<class P>
|
|
template<class P>
|
|
-MultiChannelImageT<P> MultiChannelImage3DT<P>::operator[] (uint c)
|
|
|
|
-{
|
|
|
|
- // This was our first idea ... but it creates a real copy
|
|
|
|
- // ImageT<P> tmp ( data[c], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::noAlignment );
|
|
|
|
- // This is the correct version. The funny thing about this is that shallowCopy
|
|
|
|
- // is not an enum parameter, but an instance of ShallowCopyMode, which is a class.
|
|
|
|
- // This fancy trick was done in older to prevent automatic conversion between enum types
|
|
|
|
- // as done implicitly by C++.
|
|
|
|
-
|
|
|
|
|
|
+MultiChannelImageT<P> MultiChannelImage3DT<P>::operator[] (uint z)
|
|
|
|
+{
|
|
MultiChannelImageT<P> img;
|
|
MultiChannelImageT<P> img;
|
|
- for( int z = 0; z < zsize; z++ )
|
|
|
|
|
|
+ for( int c = 0; c < numChannels; c++ )
|
|
{
|
|
{
|
|
P * datatmp = data[c];
|
|
P * datatmp = data[c];
|
|
ImageT<P> tmp ( &datatmp[z*(xsize*ysize)], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::shallowCopy );
|
|
ImageT<P> tmp ( &datatmp[z*(xsize*ysize)], xsize, ysize, xsize*sizeof(P), GrayColorImageCommonImplementation::shallowCopy );
|
|
@@ -352,6 +345,7 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
|
|
{
|
|
{
|
|
assert( channel < numChannels );
|
|
assert( channel < numChannels );
|
|
|
|
|
|
|
|
+ // some sort of correction trick hardly understandable :-)
|
|
std::vector<double> meanVals;
|
|
std::vector<double> meanVals;
|
|
for( int z = 0; z < zsize; z++ )
|
|
for( int z = 0; z < zsize; z++ )
|
|
{
|
|
{
|
|
@@ -365,10 +359,12 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
|
|
}
|
|
}
|
|
sumVal /= (xsize*ysize);
|
|
sumVal /= (xsize*ysize);
|
|
meanVals.push_back( sumVal );
|
|
meanVals.push_back( sumVal );
|
|
|
|
+
|
|
}
|
|
}
|
|
|
|
|
|
P newMax = std::numeric_limits<P>::min();
|
|
P newMax = std::numeric_limits<P>::min();
|
|
- short int maxVal = 255;
|
|
|
|
|
|
+
|
|
|
|
+ const short int maxVal = 255;
|
|
for ( int z = 0; z < zsize; z++ )
|
|
for ( int z = 0; z < zsize; z++ )
|
|
{
|
|
{
|
|
for ( int y = 0; y < ysize; y++ )
|
|
for ( int y = 0; y < ysize; y++ )
|
|
@@ -391,90 +387,76 @@ void MultiChannelImage3DT<P>::correctShading( uint channel ) const
|
|
}
|
|
}
|
|
|
|
|
|
template<class P>
|
|
template<class P>
|
|
-Image MultiChannelImage3DT<P>::getChannel( int z, uint channel ) const
|
|
|
|
|
|
+void MultiChannelImage3DT<P>::equalizeHistogram( uint channel ) const
|
|
{
|
|
{
|
|
- assert( channel < numChannels );
|
|
|
|
|
|
+ assert(channel < numChannels );
|
|
|
|
|
|
- NICE::Image img;
|
|
|
|
- convertToGrey( img, z, channel, true );
|
|
|
|
|
|
+ for( int z = 0; z < zsize; z++ )
|
|
|
|
+ {
|
|
|
|
+ NICE::Image img = getChannel(z, channel );
|
|
|
|
+ NICE::Histogram hist(img,0,255,256);
|
|
|
|
|
|
- return img;
|
|
|
|
|
|
+ NICE::IntVector *histVec = NULL;
|
|
|
|
+ histVec = hist.cumulative();
|
|
|
|
+ for ( int i = 0; i < (int)histVec->size(); i++)
|
|
|
|
+ {
|
|
|
|
+ histVec->set(i, histVec->get(i) * 255 / (double)histVec->get(histVec->size()-1));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ for ( int y = 0; y < ysize; y++ )
|
|
|
|
+ {
|
|
|
|
+ for ( int x = 0; x < xsize; x++ )
|
|
|
|
+ {
|
|
|
|
+ data [channel][x + y*xsize + z*xsize*ysize] = histVec->get( img.getPixel(x,y) );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ delete histVec;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
template<class P>
|
|
template<class P>
|
|
-ImageT<P> MultiChannelImage3DT<P>::getChannelT( int z, uint channel ) const
|
|
|
|
|
|
+Image MultiChannelImage3DT<P>::getChannel( int z, uint channel ) const
|
|
{
|
|
{
|
|
assert( channel < numChannels );
|
|
assert( channel < numChannels );
|
|
|
|
|
|
- NICE::ImageT<P> img;
|
|
|
|
- convertToGrey( img, z, channel, false );
|
|
|
|
-
|
|
|
|
- P min, max;
|
|
|
|
- statistics ( min, max, channel );
|
|
|
|
- fprintf (stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", (double)max, (double)min );
|
|
|
|
|
|
+ NICE::Image img;
|
|
|
|
+ convertToGrey( img, z, channel, true );
|
|
|
|
|
|
return img;
|
|
return img;
|
|
}
|
|
}
|
|
|
|
|
|
-/** convert to ice image */
|
|
|
|
template<class P>
|
|
template<class P>
|
|
-void MultiChannelImage3DT<P>::convertToGrey( NICE::Image & img, int z, uint channel, bool normalize ) const
|
|
|
|
|
|
+ImageT<P> MultiChannelImage3DT<P>::getChannelT( int z, uint channel ) const
|
|
{
|
|
{
|
|
assert( channel < numChannels );
|
|
assert( channel < numChannels );
|
|
|
|
|
|
- P min, max;
|
|
|
|
|
|
+ // P min, max;
|
|
|
|
+ // statistics ( min, max, channel );
|
|
|
|
+ // fprintf (stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", (double)max, (double)min );
|
|
|
|
|
|
- if ( normalize ) {
|
|
|
|
- statistics( min, max, channel );
|
|
|
|
- fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
|
|
|
|
- }
|
|
|
|
|
|
+ NICE::ImageT<P> img(xsize,ysize);
|
|
|
|
|
|
- bool skip_assignment = false;
|
|
|
|
-
|
|
|
|
- img.resize( xsize, ysize );
|
|
|
|
-
|
|
|
|
- if ( normalize )
|
|
|
|
- if ( max - min < std::numeric_limits<double>::min() )
|
|
|
|
|
|
+ long k = 0;
|
|
|
|
+ for ( int y = 0; y < ysize; y++ )
|
|
|
|
+ for( int x = 0; x < xsize; x++, k++ )
|
|
{
|
|
{
|
|
- img.set( max );
|
|
|
|
- skip_assignment = true;
|
|
|
|
- fprintf( stderr, "MultiChannelImage3DT::showChannel: image is uniform! (%f)\n", ( double )max );
|
|
|
|
|
|
+ img.setPixel( x, y, data[channel][z*xsize*ysize + k] );
|
|
}
|
|
}
|
|
|
|
|
|
-
|
|
|
|
- if ( ! skip_assignment )
|
|
|
|
- {
|
|
|
|
- long k = 0;
|
|
|
|
-
|
|
|
|
- for ( int y = 0 ; y < ysize; y++ )
|
|
|
|
- {
|
|
|
|
- for ( int x = 0 ; x < xsize ; x++, k++ )
|
|
|
|
- {
|
|
|
|
- if ( normalize )
|
|
|
|
- {
|
|
|
|
- img.setPixel( x, y, ( int )(( data[channel][z*xsize*ysize + k] - min ) * 255 / ( max - min ) ) );
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- img.setPixel( x, y, ( int )( data[channel][z*xsize*ysize + k] ) );
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ return img;
|
|
}
|
|
}
|
|
|
|
|
|
-/** convert to ice image template */
|
|
|
|
|
|
+/** convert to ice image */
|
|
template<class P>
|
|
template<class P>
|
|
-void MultiChannelImage3DT<P>::convertToGrey( NICE::ImageT<P> & img, int z, uint channel, bool normalize ) const
|
|
|
|
|
|
+void MultiChannelImage3DT<P>::convertToGrey( NICE::Image & img, int z, uint channel, bool normalize ) const
|
|
{
|
|
{
|
|
assert( channel < numChannels );
|
|
assert( channel < numChannels );
|
|
|
|
|
|
P min, max;
|
|
P min, max;
|
|
|
|
|
|
- if ( normalize ) {
|
|
|
|
|
|
+ if ( normalize )
|
|
statistics( min, max, channel );
|
|
statistics( min, max, channel );
|
|
- fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
|
|
|
|
- }
|
|
|
|
|
|
|
|
bool skip_assignment = false;
|
|
bool skip_assignment = false;
|
|
|
|
|
|
@@ -483,9 +465,10 @@ void MultiChannelImage3DT<P>::convertToGrey( NICE::ImageT<P> & img, int z, uint
|
|
if ( normalize )
|
|
if ( normalize )
|
|
if ( max - min < std::numeric_limits<double>::min() )
|
|
if ( max - min < std::numeric_limits<double>::min() )
|
|
{
|
|
{
|
|
|
|
+ fprintf( stderr, "MultiChannelImage3DT<>::showChannel: max %f min %f\n", ( double )max, ( double )min );
|
|
img.set( max );
|
|
img.set( max );
|
|
skip_assignment = true;
|
|
skip_assignment = true;
|
|
- fprintf( stderr, "MultiChannelImage3DT::showChannel: image is uniform! (%f)\n", ( double )max );
|
|
|
|
|
|
+ fprintf( stderr, "MultiChannelImage3DT<>::showChannel: image is uniform! (%f)\n", ( double )max );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|