Ejemplo n.º 1
0
	qreal restrictedAreaRadius( const Slice &slice, const iCoord2D &pithCoord, const uint &nbPolygonPoints, const int &intensityThreshold )
	{
		Q_ASSERT_X( nbPolygonPoints>0 , "BillonTpl<T>::getRestrictedAreaMeansRadius", "nbPolygonPoints arguments equals to 0 => division by zero" );

		const int width = slice.n_cols;
		const int height = slice.n_rows;
		const qreal angleIncrement = TWO_PI/static_cast<qreal>(nbPolygonPoints);

		rCoord2D center, edge;
		rVec2D direction;
		qreal orientation, radius, currentNorm;

		radius = width;
		center.x = pithCoord.x;
		center.y = pithCoord.y;
		orientation = width;
		while (orientation < TWO_PI)
		{
			orientation += angleIncrement;
			direction.x = qCos(orientation);
			direction.y = qSin(orientation);
			edge = center + direction*20;
			while ( edge.x>0 && edge.y>0 && edge.x<width && edge.y<height && slice.at(edge.y,edge.x) > intensityThreshold )
			{
				edge += direction;
			}
			currentNorm = rVec2D(edge-center).norm();
			if ( currentNorm < radius ) radius = currentNorm;
		}
		return radius;
	}
Ejemplo n.º 2
0
	void writeInPgm3D( const Slice &slice, QDataStream &stream )
	{
		uint i, j;
		for ( j=0 ; j<slice.n_rows ; ++j )
		{
			for ( i=0 ; i<slice.n_cols ; ++i )
			{
				stream << static_cast<qint16>(slice.at(j,i));
			}
		}
	}
Ejemplo n.º 3
0
	void draw( QPainter &painter, const Slice &slice, const uiCoord2D &pithCoord, const int &intensityThreshold, const TKD::ProjectionType &view )
	{
		painter.save();
		painter.setPen(QColor(255,255,255,127));

		const uint width = painter.window().width();
		const uint height = painter.window().height();

		const qreal angularIncrement = TWO_PI/(qreal)(width);

		uint i, j, x, y;

		if ( view == TKD::Z_PROJECTION )
		{
			for ( j=0 ; j<height ; ++j )
			{
				for ( i=0 ; i<width ; ++i )
				{
					if ( slice.at(j,i) > intensityThreshold ) painter.drawPoint(i,j);
				}
			}
		}
		else if ( view == TKD::CARTESIAN_PROJECTION )
		{
			for ( j=0 ; j<height ; ++j )
			{
				for ( i=0 ; i<width ; ++i )
				{
					x = pithCoord.x + j * qCos(i*angularIncrement);
					y = pithCoord.y + j * qSin(i*angularIncrement);
					if ( slice.at(y,x) > intensityThreshold ) painter.drawPoint(i,j);
				}
			}
		}

		painter.restore();
	}
	void extractConnexComponents( Slice &resultSlice, const Slice & slice, const int & minimumSize, const int & threshold )
	{
		const uint width = slice.n_cols;
		const uint height = slice.n_rows;

		QMap<int, QList<iCoord2D> > connexComponentList;
		QMap<int, int> tableEquiv;
		QList<int> voisinage;
		uint j, i;
		int mini, nbLabel, label, currentEquiv;

		Slice labels(height, width);
		labels.fill(0);
		nbLabel = 0;
		//On parcourt une première fois la tranche
		for ( j=1 ; j<height ; ++j)
		{
			for ( i=1 ; i<width-1 ; ++i)
			{
				//Si on a un voxel
				if ( slice.at(j,i) > threshold )
				{
					//On sauvegarde la valeur des voisins non nuls
					voisinage.clear();
					//Voisinage de la face courante
					if (labels.at(j,i-1)) voisinage.append(labels.at(j,i-1));
					if (labels.at(j-1,i-1)) voisinage.append(labels.at(j-1,i-1));
					if (labels.at(j-1,i)) voisinage.append(labels.at(j-1,i));
					if (labels.at(j-1,i+1)) voisinage.append(labels.at(j-1,i+1));
					//Si ses voisins n'ont pas d'étiquette
					if ( voisinage.isEmpty() )
					{
						++nbLabel;
						labels.at(j,i) = nbLabel;
					}
					//Si ses voisins ont une étiquette
					else if ( voisinage.size() == 1 )
					{
						labels.at(j,i) = voisinage[0];
					}
					else
					{
						QList<int>::ConstIterator iterVoisin = voisinage.constBegin();
						mini = (*iterVoisin++);
						while ( iterVoisin != voisinage.constEnd() )
						{
							mini = qMin(mini,(*iterVoisin++));
						}
						labels.at(j,i) = mini;
						for ( iterVoisin = voisinage.constBegin() ; iterVoisin != voisinage.constEnd() ; ++iterVoisin )
						{
							if ( (*iterVoisin) > mini )
							{
								if ( tableEquiv.contains(*iterVoisin) )
								{
									currentEquiv = tableEquiv[*iterVoisin];
									if ( mini > currentEquiv )
									{
										tableEquiv[*iterVoisin] = mini;
										while (tableEquiv.contains(mini))
										{
											mini = tableEquiv[mini];
										}
										if ( currentEquiv < mini )
										{
											tableEquiv[mini] = currentEquiv;
											labels.at(j,i) = currentEquiv;
										}
										else if ( currentEquiv > mini )
										{
											tableEquiv[currentEquiv] = mini;
											labels.at(j,i) = mini;
										}
									}
									else if ( mini < currentEquiv )
									{
										tableEquiv[*iterVoisin] = currentEquiv;
										while (tableEquiv.contains(currentEquiv))
										{
											currentEquiv = tableEquiv[currentEquiv];
										}
										if ( currentEquiv > mini )
										{
											tableEquiv[currentEquiv] = mini;
											labels.at(j,i) = mini;
										}
										else if ( currentEquiv < mini )
										{
											tableEquiv[mini] = currentEquiv;
											labels.at(j,i) = currentEquiv;
										}
									}
								}
								else
								{
									tableEquiv[*iterVoisin] = mini;
								}
							}
						}
					}
				}
			}
		}

		//Résolution des chaines dans la table d'équivalence
		QMap<int, int>::ConstIterator iterTable;
		int value;
		for ( iterTable = tableEquiv.constBegin() ; iterTable != tableEquiv.constEnd() ; ++iterTable )
		{
			value = iterTable.value();
			while (tableEquiv.contains(value))
			{
				value = tableEquiv[value];
			}
			tableEquiv[iterTable.key()] = value;
		}
		for ( j=0 ; j<height ; ++j )
		{
			for ( i=0 ; i<width ; ++i )
			{
				label = labels.at(j,i);
				//Si on a un voxel
				if (label)
				{
					if (tableEquiv.contains(label))
					{
						labels.at(j,i) = tableEquiv[label];
						label = labels.at(j,i);
					}
					if (!connexComponentList.contains(label)) connexComponentList[label] = QList<iCoord2D>();
					connexComponentList[label].append(iCoord2D(i,j));
				}
			}
		}

		QMap<int, QList<iCoord2D> >::ConstIterator iterComponents;
		QList<iCoord2D>::ConstIterator iterCoords;
		int counter = 1;
		resultSlice.fill(0);
		for ( iterComponents = connexComponentList.constBegin() ; iterComponents != connexComponentList.constEnd() ; ++iterComponents )
		{
			if ( iterComponents.value().size() > minimumSize )
			{
				for ( iterCoords = iterComponents.value().constBegin() ; iterCoords != iterComponents.value().constEnd() ; ++ iterCoords )
				{
					resultSlice.at((*iterCoords).y,(*iterCoords).x) = counter;
				}
				++counter;
			}
		}
	}
Ejemplo n.º 5
0
	iCoord2D findNearestPointOfThePith( const Slice &slice, const iCoord2D &sliceCenter, const int &intensityThreshold )
	{
		// Find the pixel closest to the pith
		const int width = slice.n_cols;
		const int height = slice.n_rows;
		const int radiusMax = qMin( qMin(sliceCenter.x,width-sliceCenter.x), qMin(sliceCenter.y,height-sliceCenter.y) );

		iCoord2D position, circlePoint;
		bool edgeFind = false;
		int currentRadius, d;

		currentRadius = 1;
		// Using Andres circle algorithm
		while ( !edgeFind && currentRadius < radiusMax )
		{
			circlePoint.x = 0;
			circlePoint.y = currentRadius;
			d = currentRadius - 1;
			while ( circlePoint.y>=circlePoint.x && !edgeFind )
			{
				edgeFind = true;
				if ( slice.at( sliceCenter.y+circlePoint.y, sliceCenter.x+circlePoint.x ) > intensityThreshold )
				{
					position.x = sliceCenter.x+circlePoint.x;
					position.y = sliceCenter.y+circlePoint.y;
				}
				else if ( slice.at( sliceCenter.y+circlePoint.y, sliceCenter.x-circlePoint.x ) > intensityThreshold )
				{
					position.x = sliceCenter.x-circlePoint.x;
					position.y = sliceCenter.y+circlePoint.y;
				}
				else if ( slice.at( sliceCenter.y+circlePoint.x, sliceCenter.x+circlePoint.y ) > intensityThreshold )
				{
					position.x = sliceCenter.x+circlePoint.y;
					position.y = sliceCenter.y+circlePoint.x;
				}
				else if ( slice.at( sliceCenter.y+circlePoint.x, sliceCenter.x-circlePoint.y ) > intensityThreshold )
				{
					position.x = sliceCenter.x-circlePoint.y;
					position.y = sliceCenter.y+circlePoint.x;
				}
				else if ( slice.at( sliceCenter.y-circlePoint.y, sliceCenter.x+circlePoint.x ) > intensityThreshold )
				{
					position.x = sliceCenter.x+circlePoint.x;
					position.y = sliceCenter.y-circlePoint.y;
				}
				else if ( slice.at( sliceCenter.y-circlePoint.y, sliceCenter.x-circlePoint.x ) > intensityThreshold )
				{
					position.x = sliceCenter.x-circlePoint.x;
					position.y = sliceCenter.y-circlePoint.y;
				}
				else if ( slice.at( sliceCenter.y-circlePoint.x, sliceCenter.x+circlePoint.y ) > intensityThreshold )
				{
					position.x = sliceCenter.x+circlePoint.y;
					position.y = sliceCenter.y-circlePoint.x;
				}
				else if ( slice.at( sliceCenter.y-circlePoint.x, sliceCenter.x-circlePoint.y ) > intensityThreshold )
				{
					position.x = sliceCenter.x-circlePoint.y;
					position.y = sliceCenter.y-circlePoint.x;
				}
				else
				{
					edgeFind = false;
					if ( d >= 2*circlePoint.x )
					{
						d -= 2*circlePoint.x;
						circlePoint.x++;
					}
					else if ( d <= 2*(currentRadius-circlePoint.y) )
					{
						d += 2*circlePoint.y;
						circlePoint.y--;
					}
					else
					{
						d += 2*(circlePoint.y-circlePoint.x);
						circlePoint.y--;
						circlePoint.x++;
					}
				}
			}
			currentRadius++;
		}

		if ( edgeFind )
		{
			//qDebug() << "Pixel le plus proche de la moelle : ( " << position.x << ", " << position.y << " )";
			return position;
		}
		else
		{
			qDebug() << "Aucun pixel et donc aucune composante connexe";
			return iCoord2D(-1,-1);
		}
	}