bool SelectionVOI::isPointInside( const float xPos, const float yPos, const float zPos ) const { DatasetManager *pDM( DatasetManager::getInstance() ); unsigned int xVoxelCoord( static_cast< unsigned int >( ( xPos / pDM->getVoxelX() ) ) ); unsigned int yVoxelCoord( static_cast< unsigned int >( ( yPos / pDM->getVoxelY() ) ) ); unsigned int zVoxelCoord( static_cast< unsigned int >( ( zPos / pDM->getVoxelZ() ) ) ); unsigned int dataCoord( zVoxelCoord * m_nbCols * m_nbRows + yVoxelCoord * m_nbCols + xVoxelCoord ); return m_includedVoxels.at( dataCoord ); }
bool SelectionVOI::isPointInside( const float xPos, const float yPos, const float zPos ) const { // According to the nifti standard, a voxel index is mapped to the coordinate of the // center of that voxel in real space. // Therefore, points considered in a voxel (x, y, z) range from // (x - 0.5dx, y - 0.5dy, z - 0.5dz) to (x + 0.5dx, y + 0.5dy, z + 0.5dz). // That is why we need to shift the coordinates before computing the coordinate. DatasetManager *pDM( DatasetManager::getInstance() ); unsigned int xVoxelCoord( static_cast< unsigned int >( ( xPos / pDM->getVoxelX() ) + 0.5 ) ); unsigned int yVoxelCoord( static_cast< unsigned int >( ( yPos / pDM->getVoxelY() ) + 0.5 ) ); unsigned int zVoxelCoord( static_cast< unsigned int >( ( zPos / pDM->getVoxelZ() ) + 0.5 ) ); unsigned int dataCoord( zVoxelCoord * m_nbCols * m_nbRows + yVoxelCoord * m_nbCols + xVoxelCoord ); return m_includedVoxels.at( dataCoord ); }
SelectionVOI::SelectionVOI( /*DatasetHelper *pDH, */Anatomy *pSourceAnatomy, const float threshold, const ThresholdingOperationType opType ) : SelectionObject( Vector(0.0, 0.0, 0.0), Vector(0.0, 0.0, 0.0) ), m_voiSize( 0 ) { m_nbRows = pSourceAnatomy->getRows(); m_nbCols = pSourceAnatomy->getColumns(); m_nbFrames = pSourceAnatomy->getFrames(); vector< float > * const pAnatDataset = pSourceAnatomy->getFloatDataset(); m_includedVoxels.assign( pAnatDataset->size(), false ); if( opType == THRESHOLD_EQUAL ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::equal_to< float >(), threshold ) ); } else if( opType == THRESHOLD_GREATER ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::greater< float >(), threshold ) ); } else if( opType == THRESHOLD_GREATER_EQUAL ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::greater_equal< float >(), threshold ) ); } else if( opType == THRESHOLD_SMALLER ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::less< float >(), threshold ) ); } else if( opType == THRESHOLD_SMALLER_EQUAL ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::less_equal< float >(), threshold ) ); } //m_isosurface = new CIsoSurface( m_datasetHelper, pSourceAnatomy ); m_pIsoSurface = new CBoolIsoSurface( m_includedVoxels ); //m_isosurface->setThreshold( threshold ); //m_isosurface->GenerateWithThreshold(); m_pIsoSurface->GenerateSurface(); wxString mystring(wxT("[VOI] - ") + pSourceAnatomy->getName()); m_name = mystring; m_objectType = VOI_TYPE; //m_sourceAnatomy = i_anatomy;*/ // TODO selection HERE was going to compute the value of the // m_center and m_size params. unsigned int xIdxMin( m_nbCols ); unsigned int yIdxMin( m_nbRows ); unsigned int zIdxMin( m_nbFrames ); unsigned int xIdxMax( 0 ); unsigned int yIdxMax( 0 ); unsigned int zIdxMax( 0 ); unsigned int dataIdx( 0 ); for( unsigned int zPos( 0 ); zPos < m_nbFrames; ++zPos ) { for( unsigned int yPos( 0 ); yPos < m_nbRows; ++yPos ) { for( unsigned int xPos( 0 ); xPos < m_nbCols; ++xPos, ++dataIdx ) { if( m_includedVoxels[dataIdx] ) { xIdxMin = std::min( xIdxMin, xPos ); yIdxMin = std::min( yIdxMin, yPos ); zIdxMin = std::min( zIdxMin, zPos ); xIdxMax = std::max( xIdxMax, xPos ); yIdxMax = std::max( yIdxMax, yPos ); zIdxMax = std::max( zIdxMax, zPos ); } } } } // Convert to space coordinates DatasetManager *pDM( DatasetManager::getInstance() ); float spaceXMin( xIdxMin * pDM->getVoxelX() ); float spaceYMin( yIdxMin * pDM->getVoxelY() ); float spaceZMin( zIdxMin * pDM->getVoxelZ() ); // For the max value, since we want to grab all of the voxel, // and the idx * the size of the voxel gives the begininng of the voxel // in space, we adjust with the +1, then the - 0.1 * voxelSize to // make sure not to fall in an inexisting coordinate. float spaceXMax( ( xIdxMax + 1 ) * pDM->getVoxelX() - 0.1 * pDM->getVoxelX() ); float spaceYMax( ( yIdxMax + 1 ) * pDM->getVoxelY() - 0.1 * pDM->getVoxelY() ); float spaceZMax( ( zIdxMax + 1 ) * pDM->getVoxelZ() - 0.1 * pDM->getVoxelZ() ); //float spaceXMax( ( xIdxMax ) * pDH->m_xVoxel ); //float spaceYMax( ( yIdxMax ) * pDH->m_yVoxel ); //float spaceZMax( ( zIdxMax ) * pDH->m_zVoxel ); setCenter( ( spaceXMax + spaceXMin ) / 2.0f, ( spaceYMax + spaceYMin ) / 2.0f, ( spaceZMax + spaceZMin ) / 2.0f ); setSize( spaceXMax - spaceXMin, spaceYMax - spaceYMin, spaceZMax - spaceZMin ); m_voiSize = std::count( m_includedVoxels.begin(), m_includedVoxels.end(), true ); }
void SelectionVOI::buildSurface( Anatomy *pSourceAnatomy ) { m_nbRows = pSourceAnatomy->getRows(); m_nbCols = pSourceAnatomy->getColumns(); m_nbFrames = pSourceAnatomy->getFrames(); vector< float > * const pAnatDataset = pSourceAnatomy->getFloatDataset(); m_includedVoxels.assign( pAnatDataset->size(), false ); if( m_thresType == THRESHOLD_EQUAL ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::equal_to< float >(), m_generationThreshold ) ); } else if( m_thresType == THRESHOLD_GREATER ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::greater< float >(), m_generationThreshold ) ); } else if( m_thresType == THRESHOLD_GREATER_EQUAL ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::greater_equal< float >(), m_generationThreshold ) ); } else if( m_thresType == THRESHOLD_SMALLER ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::less< float >(), m_generationThreshold ) ); } else if( m_thresType == THRESHOLD_SMALLER_EQUAL ) { std::transform( pAnatDataset->begin(), pAnatDataset->end(), m_includedVoxels.begin(), bind2nd( std::less_equal< float >(), m_generationThreshold ) ); } m_pIsoSurface = new CBoolIsoSurface( m_includedVoxels ); m_pIsoSurface->GenerateSurface(); // Compute the size and position of the bounding box of the VOI. unsigned int xIdxMin( m_nbCols ); unsigned int yIdxMin( m_nbRows ); unsigned int zIdxMin( m_nbFrames ); unsigned int xIdxMax( 0 ); unsigned int yIdxMax( 0 ); unsigned int zIdxMax( 0 ); unsigned int dataIdx( 0 ); for( unsigned int zPos( 0 ); zPos < m_nbFrames; ++zPos ) { for( unsigned int yPos( 0 ); yPos < m_nbRows; ++yPos ) { for( unsigned int xPos( 0 ); xPos < m_nbCols; ++xPos, ++dataIdx ) { if( m_includedVoxels[dataIdx] ) { xIdxMin = std::min( xIdxMin, xPos ); yIdxMin = std::min( yIdxMin, yPos ); zIdxMin = std::min( zIdxMin, zPos ); xIdxMax = std::max( xIdxMax, xPos ); yIdxMax = std::max( yIdxMax, yPos ); zIdxMax = std::max( zIdxMax, zPos ); } } } } // Convert to space coordinates DatasetManager *pDM( DatasetManager::getInstance() ); float spaceXMin( xIdxMin * pDM->getVoxelX() ); float spaceYMin( yIdxMin * pDM->getVoxelY() ); float spaceZMin( zIdxMin * pDM->getVoxelZ() ); // For the max value, since we want to grab all of the voxel, // and the idx * the size of the voxel gives the begininng of the voxel // in space, we adjust with the +1, then the - 0.1 * voxelSize to // make sure not to fall in an inexisting coordinate. float spaceXMax( ( xIdxMax + 1 ) * pDM->getVoxelX() - 0.1 * pDM->getVoxelX() ); float spaceYMax( ( yIdxMax + 1 ) * pDM->getVoxelY() - 0.1 * pDM->getVoxelY() ); float spaceZMax( ( zIdxMax + 1 ) * pDM->getVoxelZ() - 0.1 * pDM->getVoxelZ() ); setCenter( ( spaceXMax + spaceXMin ) / 2.0f, ( spaceYMax + spaceYMin ) / 2.0f, ( spaceZMax + spaceZMin ) / 2.0f ); setSize( spaceXMax - spaceXMin, spaceYMax - spaceYMin, spaceZMax - spaceZMin ); m_voiSize = std::count( m_includedVoxels.begin(), m_includedVoxels.end(), true ); }
std::vector< Vector > CIsoSurfaceBase::getSurfaceVoxelPositions() { // TODO selection iso check this out if ( m_threshold == 0.0 || m_threshold == 1.0 ) { m_svPositions.clear(); return m_svPositions; } if ( !m_positionsCalculated ) { DatasetManager *pDM( DatasetManager::getInstance() ); Vector v( 0, 0, 0 ); size_t nSize = pDM->getColumns() * pDM->getRows() * pDM->getFrames(); std::vector< Vector > accu( nSize, v ); std::vector< int > hits( nSize, 0 ); std::vector< Vector > vertices = m_tMesh->getVerts(); m_svPositions.clear(); for ( size_t i = 0; i < vertices.size(); ++i ) { v = vertices[i]; int index = (int) v.x + (int) v.y * pDM->getColumns() + (int) v.z * pDM->getColumns() * pDM->getRows(); if ( !( index < 0 || index > pDM->getColumns() * pDM->getRows() * pDM->getFrames()) ) { accu[index].x += v.x; accu[index].y += v.y; accu[index].z += v.z; hits[index] += 1; } } int pointsInVoxels = 0; int voxelsHit = 1; for ( size_t i = 0; i < nSize; ++i ) { if ( hits[i] > 0 ) { ++voxelsHit; pointsInVoxels += hits[i]; } } pointsInVoxels /= voxelsHit; int threshold = pointsInVoxels / 2; for ( size_t i = 0; i < nSize; ++i ) { if ( hits[i] > threshold ) { accu[i].x /= hits[i]; accu[i].y /= hits[i]; accu[i].z /= hits[i]; if ( (int) accu[i].x ) { accu[i].x = wxMin( pDM->getColumns(), wxMax ( accu[i].x, 0 ) ); accu[i].y = wxMin( pDM->getRows(), wxMax ( accu[i].y, 0 ) ); accu[i].z = wxMin( pDM->getFrames(), wxMax ( accu[i].z, 0 ) ); Vector v( accu[i].x, accu[i].y, accu[i].z ); m_svPositions.push_back( v ); } } } m_positionsCalculated = true; } return m_svPositions; }