18 fname.toStdString( ) ) ), m_fileName(
20 qDebug( ) <<
"guiimage.";
23 transform.resize( 4 );
27 m_equalizeHistogram =
false;
29 m_currentSlice.insert( 0, 4, 0 );
30 COMMENT(
"Getting maximum intensity and histogram.", 2 );
35 m_fmax = m_max = img.
Maximum( );
41 m_max = m_fmax = img.
Maximum( );
59 m_max = m_fmax = rcl[ 2 ];
63 std::string msg(
BIAL_ERROR(
"Accessing non-initialized multi-image." ) );
64 throw( std::runtime_error( msg ) );
66 COMMENT(
"Adjusting slice to appear on canvas.", 2 );
68 COMMENT(
"NIfTI image detected.", 2 );
72 COMMENT(
"Generating Axial affine transform.", 2 );
74 transform[ 0 ].Scale( 1, -1, -1 );
78 COMMENT(
"Generating Coronal affine transform.", 2 );
80 transform[ 1 ].Scale( -1, 1, 1 );
84 COMMENT(
"Generating Sagittal affine transform.", 2 );
91 COMMENT(
"Generating Axial affine transform.", 2 );
96 COMMENT(
"Generating Coronal affine transform.", 2 );
101 COMMENT(
"Generating Sagittal affine transform.", 2 );
103 updateBoundings( 2 );
106 cachedPixmaps.resize( 3 );
107 needUpdate.insert( 0, 3,
true );
108 for(
int view = 0; view < m_currentSlice.size( ); ++view ) {
111 m_currentToolPos = -1;
114 COMMENT(
"PPM image detected.", 2 );
118 cachedPixmaps.resize( 4 );
119 needUpdate.insert( 0, 4,
true );
122 COMMENT(
"Gray image detected.", 2 );
126 cachedPixmaps.resize( 1 );
127 needUpdate.push_back(
true );
129 COMMENT(
"Computing equalization transform.", 2 );
133 equalization.resize( levi.
size( ) );
134 for(
size_t val = 0; val < levi.
size( ); ++val ) {
135 equalization[ val ] = std::round( levi[ val ] );
137 COMMENT(
"Computing equalized histogram.", 2 );
139 for(
size_t val = 0; val < equalized.
size( ); ++val ) {
140 equalized[ equalization[ val ] ] = histogram[ val ];
143 depth( 0 ) <<
")", 0 );
151 if(
tools.isEmpty( ) ) {
154 if( m_currentToolPos >= (
size_t )
tools.size( ) ) {
155 m_currentToolPos = 0;
157 return(
tools.at( m_currentToolPos ) );
161 return( m_modality );
165 return( m_fileName );
177 COMMENT(
"GET SLICE: image = " << m_fileName.toStdString( ) <<
", axis = " << view <<
", slice = " << slice, 2 );
178 if( needUpdate[ view ] ) {
179 if( slice >=
depth( view ) ) {
180 throw( std::out_of_range(
181 BIAL_ERROR( QString(
"Slice is out of range. Expected < %1" ).arg(
depth( view ) ).toStdString( ) ) ) );
183 const size_t xsize =
width( view );
184 const size_t ysize =
heigth( view );
185 QImage res( xsize, ysize, QImage::Format_ARGB32 );
186 double factor = 255.0 / ( double ) m_fmax;
188 switch( image.
Type( ) ) {
190 COMMENT(
"Generating BW view.", 2 );
192 #pragma omp parallel for default(none) shared(transf, img, res) firstprivate(slice, factor) 193 for(
size_t y = 0; y < ysize; ++y ) {
194 QRgb *scanLine = ( QRgb* ) res.scanLine( y );
195 for(
size_t x = 0; x < xsize; ++x ) {
198 transf( x, y, slice, &xx, &yy, &zz );
199 pixel = img( xx, yy, zz );
200 if( m_equalizeHistogram ) {
201 pixel = equalization[ pixel ];
204 scanLine[ x ] = qRgb( pixel, pixel, pixel );
210 COMMENT(
"Generating BW float view.", 2 );
212 #pragma omp parallel for default(none) shared(transf, img, res) firstprivate(slice, factor) 213 for(
size_t y = 0; y < ysize; ++y ) {
214 QRgb *scanLine = ( QRgb* ) res.scanLine( y );
215 for(
size_t x = 0; x < xsize; ++x ) {
218 transf( x, y, slice, &xx, &yy, &zz );
219 pixel =
static_cast< int >( img( xx, yy, zz ) );
220 if( m_equalizeHistogram ) {
221 pixel = equalization[ pixel ];
224 scanLine[ x ] = qRgb( pixel, pixel, pixel );
230 if( needUpdate[ 0 ] ) {
231 COMMENT(
"Generating RGB view.", 2 );
233 #pragma omp parallel for default(none) shared(transf, img, res) firstprivate(slice, factor) 234 for(
size_t y = 0; y < ysize; ++y ) {
235 QRgb *scanLine = ( QRgb* ) res.scanLine( y );
236 for(
size_t x = 0; x < xsize; ++x ) {
238 transf( x, y, slice, &xx, &yy, &zz );
239 size_t pos = img.
Position( xx, yy );
240 int r = img[ pos ][ 1 ];
241 int g = img[ pos ][ 2 ];
242 int b = img[ pos ][ 3 ];
243 if( m_equalizeHistogram ) {
244 r = equalization[ r ];
245 g = equalization[ g ];
246 b = equalization[ b ];
248 scanLine[ x ] = qRgb( r * factor, g * factor, b * factor );
251 cachedPixmaps[ 0 ] = QPixmap::fromImage( res );
252 needUpdate[ 0 ] =
false;
255 res = cachedPixmaps[ 0 ].toImage( );
256 int r( view == 1 ), g( view == 2 ), b( view == 3 );
257 for(
size_t y = 0; y < ysize; ++y ) {
258 QRgb *scanLine = ( QRgb* ) res.scanLine( y );
259 for(
size_t x = 0; x < xsize; ++x ) {
260 QRgb clr = scanLine[ x ];
261 scanLine[ x ] = qRgb( qRed( clr ) * r, qGreen( clr ) * g, qBlue( clr ) * b );
268 if( needUpdate[ 0 ] ) {
269 COMMENT(
"Generating RGB view.", 2 );
271 #pragma omp parallel for default(none) shared(transf, img, res) firstprivate(slice, factor) 272 for(
size_t y = 0; y < ysize; ++y ) {
273 QRgb *scanLine = ( QRgb* ) res.scanLine( y );
274 for(
size_t x = 0; x < xsize; ++x ) {
276 transf( x, y, slice, &xx, &yy, &zz );
277 size_t pos = img.
Position( xx, yy );
278 int r = img[ pos ][ 1 ];
279 int g = img[ pos ][ 2 ];
280 int b = img[ pos ][ 3 ];
281 if( m_equalizeHistogram ) {
282 r = equalization[ r ];
283 g = equalization[ g ];
284 b = equalization[ b ];
286 scanLine[ x ] = qRgb( r * factor, g * factor, b * factor );
289 cachedPixmaps[ 0 ] = QPixmap::fromImage( res );
290 needUpdate[ 0 ] =
false;
293 res = cachedPixmaps[ 0 ].toImage( );
294 int r( view == 1 ), g( view == 2 ), b( view == 3 );
295 for(
size_t y = 0; y < ysize; ++y ) {
296 QRgb *scanLine = ( QRgb* ) res.scanLine( y );
297 for(
size_t x = 0; x < xsize; ++x ) {
298 QRgb clr = scanLine[ x ];
299 scanLine[ x ] = qRgb( qRed( clr ) * r, qGreen( clr ) * g, qBlue( clr ) * b );
306 std::string msg(
BIAL_ERROR(
"Accessing non-initialized multi-image." ) );
307 throw( std::runtime_error( msg ) );
309 if( needUpdate[ view ] ) {
310 cachedPixmaps[ view ] = QPixmap::fromImage( res );
311 needUpdate[ view ] =
false;
315 return( cachedPixmaps[ view ] );
319 return( abs( round( bounding.at( view ).pMax.x ) ) );
323 return( abs( round( bounding.at( view ).pMax.y ) ) );
327 return( abs( round( bounding.at( view ).pMax.z ) ) );
331 size_t sz = m_currentSlice.size( );
333 if( ( m_currentSlice[ view ] != slice ) && ( slice <
depth( view ) ) ) {
334 m_currentSlice[ view ] = slice;
335 needUpdate[ view ] =
true;
340 throw std::out_of_range(
BIAL_ERROR(
"Axis out of range." ) );
346 transform[ view ]( point, &point );
351 return( transform.at( axis ) );
355 return( image.
Type( ) );
375 switch( image.
Type( ) ) {
385 std::string msg(
BIAL_ERROR(
"Getting dimensions from non-initialized multi-image." ) );
386 throw( std::runtime_error( msg ) );
391 switch( image.
Type( ) ) {
401 std::string msg(
BIAL_ERROR(
"Getting dimensions from non-initialized multi-image." ) );
402 throw( std::runtime_error( msg ) );
409 transform[ view ] = transf * transform[ view ].Inverse( );
410 updateBoundings( view );
411 needUpdate[ view ] =
true;
417 transf.
Scale( -1, 1, 1 );
418 transform[ view ] = transf * transform[ view ].Inverse( );
419 updateBoundings( view );
420 needUpdate[ view ] =
true;
426 transf.
Scale( 1, -1, 1 );
427 transform[ view ] = transf * transform[ view ].Inverse( );
428 updateBoundings( view );
429 needUpdate[ view ] =
true;
434 for(
int axis = 0; axis < needUpdate.size( ); ++axis ) {
448 return( m_currentSlice[ view ] );
452 return( m_equalizeHistogram );
456 m_equalizeHistogram = equalizeHistogram;
457 for(
int axis = 0; axis < needUpdate.size( ); ++axis ) {
458 needUpdate[ axis ] =
true;
464 if( m_equalizeHistogram ) {
472 switch( image.
Type( ) ) {
475 if( img.
Dims( ) == 2 ) {
482 color = img( x, y, z );
489 if( img.
Dims( ) == 2 ) {
496 color = img( x, y, z );
504 color = img( x, y ) ( 0 );
511 color = img( x, y ) ( 0 );
516 std::string msg(
BIAL_ERROR(
"Accessing non-initialized multi-image." ) );
517 throw( std::runtime_error( msg ) );
519 if( m_equalizeHistogram ) {
520 return( equalization[ color ] );
526 return( m_currentToolPos );
530 if( currentToolPos < static_cast< size_t >(
tools.size( ) ) ) {
535 void GuiImage::updateBoundings(
size_t axis ) {
539 transform[ axis ]( start, &start );
540 transform[ axis ](
end, &
end );
542 transform[ axis ] = transform[ axis ].Inverse( );
543 transform[ axis ].Translate( bounding[ axis ].pMin.x, bounding[ axis ].pMin.y, bounding[ axis ].pMin.z );
544 bounding[ axis ] = bounding[ axis ].Normalized( );
bool ValidCoordinate(const Vector< size_t > &pxl) const
Verifies if a given pixel coordinate is in image domain.
int max()
max is the maximum integer intensity of the input image. Used for int and Color images.
AdjacencyIterator end(const Adjacency &adj, const Vector< D > &vct, size_t pixel_index)
Returns an iterator to position after the end of elements.
size_t Dims() const
Returns the number of dimensions of the image.
Tool * currentTool()
currentTool returns the current Tool.
virtual ~GuiImage()
Destructor.
const Bial::Signal & getHistogram() const
getHistogram returns the image histogram.
void rotateAll90()
rotateAll90 rotates all views in 90 degrees.
#define BIAL_ERROR(exp)
Use BIAL_ERROR to compose runtime error messages. Note that ERROR generates a string, instead of a stream, because it is better to throw an exception, rather than exiting the program. This way, the exception may be threated by a higher level program, like an user IDE.
Signal handeling declaration.
const MultiImageType & Type() const
Returns a reference the current image type.
void flipH(size_t view)
flipH mirrors the current view on X axis.
Bial::MultiImageType getImageType() const
getImageType returns image type among int, float, Color and RealColor.
size_t heigth(size_t view)
heigth is the view heigth.
size_t currentToolPos() const
GuiImage(QString fName, QObject *parent=0)
GuiImage is the GuiImage class constructor.
bool getEqualizeHistogram() const
getEqualizeHistogram returns a boolean value that says if the image must be equalized or not...
The Point3D class is a Geometric representation of a point in 3D space. A point is a zerodimension...
Bial::Point3D getPosition(QPointF pos, size_t view)
getPosition transforms the scene position to the input image coordinates.
Bial::Vector< size_t > getDim() const
getDim
size_t size() const
Returns the number of bins.
Image< RealColor > & RclImage() const
Returns a reference to the RealColor image.
Image< Color > & ClrImage() const
Returns a reference to the Color image.
void Equalize(Signal &sgn)
Equalizes input signal.
Image< int > & IntImage() const
Returns a reference to the integer image.
size_t depth(size_t view)
depth is the number of slices of the view.
Modality modality()
modality is the image modality getter.
void setCurrentToolPos(const size_t ¤tToolPos)
Image< float > & FltImage() const
Returns a reference to the float image.
void flipV(size_t view)
flipV mirrors the current view on Y axis.
QPixmap getSlice(size_t view)
getSlice calculates and returns a QImage with the current slice of the view.
size_t width(size_t view)
width is the view width.
D Maximum() const
Returns the maximum value in Image.
void setCurrentSlice(size_t view, size_t slice)
currentSlice sets the view's current slice.
Bial::FastTransform getTransform(size_t axis)
getTransform returns the transform matrix of the views.
float fmax()
fmax is the maximum float intensity of the input image. Used for float and RealColor images...
QPointF getIntersection(size_t view)
FastTransform & Rotate(double degrees, int dms)
Vector< size_t > Dim() const
Returns a Vector with image dimensions.
Class RealColor is used to handle multi-channels in pixels with floating point values.
QString fileName()
fileName is the image absolute path getter.
void imageUpdated()
imageUpdated is called each time a internal property is updated, after that the image views are updat...
Bial::Image< int > & getIntImage() const
get*Image
The BBox class is a Bounding Box with 8 vertices, and can be represented by 2 points (6coordinates)...
int getPixel(int x, int y, int z=0)
getPixel returns the pixel intensity of the image at the given position.
void rotate90(size_t view)
rotate90 rotates a view in 90 degrees.
size_t currentSlice(size_t view)
currentSlice is the view's current slice.
QVector< Tool * > tools
tools is a vector containing the image tools.
Bial::Image< Bial::Color > & getClrImage() const
FastTransform & Scale(int sx, int sy, int sz=1.f)
void setEqualizeHistogram(bool equalizeHistogram)
setEqualizeHistogram updates a boolean value that says if the image must be equalized or not...
Signal ZeroStartHistogram(const C< D > &data, double data_step=1.0)
Static constructor.
size_t Position(size_t p_0, size_t p_1) const
Returns the position corresponding to the input coordinates in this image.
MultiImageType
The MultiImageType class is used to identify which image type is open in MultiImage.
Bial::Image< float > & getFltImage() const
Bial::Image< Bial::RealColor > & getRclImage() const
size_t getDims() const
getDims