Biomedical Image Analysis Library
The Biomedical Image Analysis Library is a poweful tool for developers, physicians, researchers, engineers, and so on.
segmentationtool.cpp
Go to the documentation of this file.
1 #include "Adjacency.hpp"
2 #include "AdjacencyIterator.hpp"
3 #include "AdjacencyRound.hpp"
4 #include "ColorRGB.hpp"
5 #include "DrawLine.hpp"
6 #include "File.hpp"
7 #include "FileImage.hpp"
8 #include "Geometrics.hpp"
10 #include "MultiImage.hpp"
11 #include "RealColor.hpp"
12 #include "SegmentationGeoStar.hpp"
13 #include "guiimage.h"
14 #include "segmentationtool.h"
15 #include <QDebug>
16 #include <QMessageBox>
17 #include <QPointF>
18 #include <algorithm>
19 
20 double SegmentationTool::getAlpha( ) const {
21  return( alpha );
22 }
23 
24 void SegmentationTool::setAlpha( double value ) {
25  alpha = value;
26 }
27 
28 double SegmentationTool::getBeta( ) const {
29  return( beta );
30 }
31 
32 void SegmentationTool::setBeta( double value ) {
33  beta = value;
34 }
35 
37  return( drawType );
38 }
39 
41  seedsVisible = vis;
42  emit guiImage->imageUpdated( );
43 }
44 
46  maskVisible = vis;
47  emit guiImage->imageUpdated( );
48 }
49 
51  return( seedsVisible );
52 }
53 
55  return( maskVisible );
56 }
57 
58 void SegmentationTool::setThickness( int value ) {
59  thickness = value;
60  COMMENT( "thickness set to" << thickness, 2 );
61 }
62 
64  guiImage->getDim( ) ) {
65  drawType = 1;
66  drawing = false;
67  setObjectName( "SegmentationTool" );
68  setHasLabel( true );
69  alpha = 0;
70  beta = 0.5;
71  thickness = 0;
72  seedsVisible = true;
73  maskVisible = true;
74 }
75 
77  return( SegmentationTool::Type );
78 }
79 
80 void SegmentationTool::mouseClicked( QPointF pt, Qt::MouseButtons buttons, size_t axis ) {
81  timer.start( );
82  drawing = true;
83  seedsVisible = true;
84  if( ( drawType == 1 ) || ( drawType == 2 ) ) {
85  switch( buttons ) {
86  case Qt::LeftButton:
87  drawType = 1;
88  break;
89  case Qt::RightButton:
90  drawType = 2;
91  break;
92  }
93  }
94  const Bial::FastTransform &transf = guiImage->getTransform( axis );
95  lastPoint = transf( pt.x( ), pt.y( ), ( double ) guiImage->currentSlice( axis ) );
96 }
97 
98 void SegmentationTool::mouseMoved( QPointF pt, size_t axis ) {
99  if( drawing ) {
100  const Bial::FastTransform &transf = guiImage->getTransform( axis );
101  Bial::Point3D current = transf( pt.x( ), pt.y( ), ( double ) guiImage->currentSlice( axis ) );
102  if( lastPoint == current ) {
103  return;
104  }
105  drawSeed( lastPoint, current );
106  lastPoint = current;
107  if( timer.elapsed( ) > 30 ) {
108  emit guiImage->imageUpdated( );
109  timer.start( );
110  }
111  }
112 }
113 
114 void SegmentationTool::mouseReleased( QPointF pt, Qt::MouseButtons buttons, size_t axis ) {
115  drawing = false;
116  if( drawing ) {
117  const Bial::FastTransform &transf = guiImage->getTransform( axis );
118  Bial::Point3D current = transf( pt.x( ), pt.y( ), ( double ) guiImage->currentSlice( axis ) );
119  drawSeed( lastPoint, current );
120  }
121  emit guiImage->imageUpdated( );
122  Q_UNUSED( buttons );
123  Q_UNUSED( axis );
124  Q_UNUSED( pt );
125 }
126 
127 void SegmentationTool::mouseDragged( QPointF pt, Qt::MouseButtons buttons, size_t axis ) {
128  Q_UNUSED( buttons );
129  Q_UNUSED( axis );
130  Q_UNUSED( pt );
131  /* nothing happens */
132 }
133 
134 void SegmentationTool::sliceChanged( size_t axis, size_t slice ) {
135  Q_UNUSED( slice );
136  needUpdate[ axis ] = true;
137 }
138 
140  /* std::cout << last << current << std::endl; */
141  Bial::Vector< float > vLast;
142  Bial::Vector< float > vCurrent;
143  size_t dims = guiImage->getDims( );
144  if( dims == 3 ) {
145  vLast = { { ( float ) last[ 0 ], ( float ) last[ 1 ], ( float ) last[ 2 ] } };
146  vCurrent = { { ( float ) current[ 0 ], ( float ) current[ 1 ], ( float ) current[ 2 ] } };
147  }
148  else {
149  vLast = { { ( float ) last[ 0 ], ( float ) last[ 1 ] } };
150  vCurrent = { { ( float ) current[ 0 ], ( float ) current[ 1 ] } };
151  }
152  Bial::Line imgLine( vLast, vCurrent, Bial::Color( 255, 255, 255, 255 ) );
153  imgLine.Draw( seeds );
154  Bial::Adjacency adj = Bial::AdjacencyType::HyperSpheric( thickness, dims );
155  size_t size = seeds.size( );
156  for( size_t px = 0; px < size; px++ ) {
157  if( seeds[ px ] == 255 ) {
158  Bial::AdjacencyIterator it( adj, seeds, px );
159  for( it.begin( ); *it < seeds.size( ); ++it ) {
160  seeds[ *it ] = drawType;
161  }
162  }
163  }
164  for( size_t i = 0; i < needUpdate.size( ); ++i ) {
165  needUpdate[ i ] = true;
166  }
167 }
168 
170  drawType = type;
171 }
172 
174  for( size_t i = 0; i < seeds.Size( ); ++i ) {
175  seeds[ i ] = 0;
176  }
177  for( size_t i = 0; i < needUpdate.size( ); ++i ) {
178  needUpdate[ i ] = true;
179  }
180  emit guiImage->imageUpdated( );
181 }
182 
184  Bial::Vector< size_t > obj_seed;
185  Bial::Vector< size_t > bkg_seed;
186  maskVisible = true;
187  for( size_t i = 0; i < seeds.size( ); ++i ) {
188  if( seeds[ i ] == 1 ) {
189  obj_seed.push_back( i );
190  }
191  else if( seeds[ i ] == 2 ) {
192  bkg_seed.push_back( i );
193  }
194  }
195  Bial::Image< int > img;
196  if( ( !obj_seed.empty( ) ) && ( !bkg_seed.empty( ) ) ) {
197  switch( guiImage->getImageType( ) ) {
199  img = guiImage->getIntImage( );
200  break;
202  img = guiImage->getFltImage( );
203  break;
205  img = Bial::ColorSpace::ARGBtoGraybyLuminosity< int >( guiImage->getClrImage( ) );
206  break;
208  img = Bial::ColorSpace::ARGBtoGraybyLuminosity< int >( guiImage->getRclImage( ) );
209  break;
210  default:
211  std::string msg( BIAL_ERROR( "Getting image from non initialized multi-image." ) );
212  throw( std::runtime_error( msg ) );
213  }
214  Bial::Image< int > res( Bial::Segmentation::OrientedGeodesicStar( img, obj_seed, bkg_seed, alpha, beta ) );
215  mask = Bial::Gradient::Morphological( res );
216  emit guiImage->imageUpdated( );
217  return( res );
218  }
219  else {
220  throw std::runtime_error( "Seeds Missing" );
221  }
222 }
223 
224 QPixmap SegmentationTool::getLabel( size_t axis ) {
225  const size_t xsz = guiImage->width( axis );
226  const size_t ysz = guiImage->heigth( axis );
227  if( !seedsVisible && !maskVisible ) {
228  return( QPixmap( ) );
229  }
230  if( !needUpdate[ axis ] ) {
231  return( pixmaps[ axis ] );
232  }
233  const Bial::FastTransform &transf = guiImage->getTransform( axis );
234  QImage res( xsz, ysz, QImage::Format_ARGB32 );
235  if( !seedsVisible ) {
236  res.fill( qRgba( 0, 0, 0, 0 ) );
237  }
238  else {
239 #pragma omp parallel for firstprivate(axis, xsz, ysz)
240  for( size_t y = 0; y < ysz; ++y ) {
241  QRgb *scanLine = ( QRgb* ) res.scanLine( y );
242  for( size_t x = 0; x < xsz; ++x ) {
243  Bial::Point3D pos = transf( x, y, guiImage->currentSlice( axis ) );
244  char pixel = seeds( pos.x, pos.y, pos.z );
245  if( pixel == 1 ) {
246  scanLine[ x ] = qRgb( 0, 255, 0 );
247  }
248  else if( pixel == 2 ) {
249  scanLine[ x ] = qRgb( 0, 0, 255 );
250  }
251  else {
252  scanLine[ x ] = qRgba( 0, 0, 0, 0 );
253  }
254  }
255  }
256  }
257  if( maskVisible && ( mask.size( ) == seeds.size( ) ) ) {
258 #pragma omp parallel for firstprivate(axis, xsz, ysz)
259  for( size_t y = 0; y < ysz; ++y ) {
260  QRgb *scanLine = ( QRgb* ) res.scanLine( y );
261  for( size_t x = 0; x < xsz; ++x ) {
262  Bial::Point3D pos = transf( x, y, guiImage->currentSlice( axis ) );
263  if( mask( pos.x, pos.y, pos.z ) ) {
264  scanLine[ x ] = qRgb( 255, 0, 0 );
265  }
266  }
267  }
268  }
269  pixmaps[ axis ] = QPixmap::fromImage( res );
270  return( pixmaps[ axis ] );
271 }
void begin()
Sets position to first valid index.
double z
Point position in z.
Definition: Geometrics.hpp:227
Image< D > Morphological(const Image< D > &image)
Computes the gradient image (dilation - erosion) using spherical adjacency relation of one pixel of r...
void setBeta(double value)
void mouseDragged(QPointF pt, Qt::MouseButtons buttons, size_t axis)
size_t Size() const
Returns the image size.
int getDrawType() const
GuiImage * guiImage
Definition: tool.h:13
void mouseMoved(QPointF pt, size_t axis)
void push_back(const D &val)
Inserts element in the end of the vector.
Definition: Vector.hpp:2394
Definition: tool.h:10
void setSeedsVisibility(bool vis)
void setDrawType(int type)
#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.
Definition: Common.hpp:161
Image< D > OrientedGeodesicStar(const Image< D > &image, const Vector< size_t > &obj_seeds, const Vector< size_t > &bkg_seeds, double alpha=0.0, double beta=0.5)
Returns the label from oriented geodesic segmentation algorithm. Use positive alpha values for light ...
double getBeta() const
ImageViewer * viewer
Definition: tool.h:14
Bial::MultiImageType getImageType() const
getImageType returns image type among int, float, Color and RealColor.
Definition: guiimage.cpp:354
The GuiImage class is a bridge to the Bial::Image data structure to the QImage data structure...
Definition: guiimage.h:20
size_t heigth(size_t view)
heigth is the view heigth.
Definition: guiimage.cpp:322
The Point3D class is a Geometric representation of a point in 3D space. A point is a zero­dimension...
Definition: Geometrics.hpp:218
void setAlpha(double value)
void sliceChanged(size_t axis, size_t slice)
static size_t size
Definition: enough.c:173
Adjacency iterator.
Bial::Image< int > segmentationOGS(double alpha, double beta)
bool getMaskVisible() const
double y
Point position in y.
Definition: Geometrics.hpp:225
void mouseReleased(QPointF pt, Qt::MouseButtons buttons, size_t axis)
size_t width(size_t view)
width is the view width.
Definition: guiimage.cpp:318
Bial::FastTransform getTransform(size_t axis)
getTransform returns the transform matrix of the views.
Definition: guiimage.cpp:350
bool getSeedsVisible() const
Adjacency HyperSpheric(float radius=1.0, size_t dims=4)
Create and return a hyper-spheric adjacency relation of radius &#39;radius&#39; and with dim dimensions...
void setThickness(int value)
SegmentationTool(GuiImage *guiImage, ImageViewer *viewer)
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
Definition: guiimage.cpp:358
void setHasLabel(bool sHasLabel)
Definition: tool.cpp:7
void Draw(Image< D > &img) const
Draws 2D or 3D line in input image.
size_t size() const
Returns the image size. Same as Size( ), just for compatibility with std containers.
bool empty() const noexcept
Tests if vector is empty.
Definition: Vector.hpp:1853
void drawSeed(Bial::Point3D last, Bial::Point3D actual)
size_t currentSlice(size_t view)
currentSlice is the view&#39;s current slice.
Definition: guiimage.cpp:447
Adjacency relation and forward iteratior related to a matrix.
Definition: Adjacency.hpp:27
QPixmap getLabel(size_t axis)
Bial::Image< Bial::Color > & getClrImage() const
Definition: guiimage.cpp:366
double getAlpha() const
void mouseClicked(QPointF pt, Qt::MouseButtons buttons, size_t axis)
Bial::Image< float > & getFltImage() const
Definition: guiimage.cpp:362
Bial::Image< Bial::RealColor > & getRclImage() const
Definition: guiimage.cpp:370
void setMaskVisibility(bool vis)
size_t getDims() const
getDims
Definition: guiimage.cpp:374