#include "bbUtilitiesRegionGrowing.h" #include "bbUtilitiesPackage.h" namespace bbUtilities { BBTK_ADD_BLACK_BOX_TO_PACKAGE(Utilities,RegionGrowing) //BBTK_USER_BLACK_BOX_IMPLEMENTATION(RegionGrowing,bbtk::AtomicBlackBox); BBTK_BLACK_BOX_IMPLEMENTATION(RegionGrowing,bbtk::AtomicBlackBox); void RegionGrowing::Process() { initialImage=bbGetInputInImage(); upper=(unsigned short)bbGetInputUpper(); lower =(unsigned short)bbGetInputLower(); std::vector inputPoint = bbGetInputSeedPoint(); int size =inputPoint.size(); //valida el tamano del vector de entrada if(inputPoint.size()==3) seedPoint=inputPoint; //instacia la imagen de salida if(filteredImage == NULL) filteredImage = vtkImageData::New(); //configura la imagen de salida double* spc = initialImage->GetSpacing(); initialImage->GetExtent(ext); filteredImage->SetSpacing(spc[0], spc[1], spc[2]); filteredImage->SetScalarTypeToInt(); filteredImage->SetNumberOfScalarComponents(1); filteredImage->SetExtent(ext); filteredImage->AllocateScalars(); //recorrido de inicializacion de la imagen de salida for(int i=ext[0]; i<=ext[1]; i++) { for(int j=ext[2]; j<=ext[3]; j++) { for(int k=ext[4]; k<=ext[5]; k++) { int * imagptr= ( int*)filteredImage->GetScalarPointer(i,j,k); *imagptr=NO_VISITADO; } } } //aplica el algoritmo de conectividad int seedXpoint = seedPoint[0]; int seedYpoint = seedPoint[1]; int seedZpoint = seedPoint[2]; connectivity(seedXpoint, seedYpoint, seedZpoint); //barrido para dar un valor de gris a los puntos for(int i=ext[0]; i<=ext[1]; i++) { for(int j=ext[2]; j<=ext[3]; j++) { for(int k=ext[4]; k<=ext[5]; k++) { int * imagptr= (int*)filteredImage->GetScalarPointer(i,j,k); int grey=*imagptr; if(grey == INVALIDO) { *imagptr=0; } else if (grey == VALIDO) { *imagptr=60000; } else if (grey == NO_VISITADO) { *imagptr=0; } } } } //carga la salida bbSetOutputOutImage(filteredImage); } //------------------------------------------------ void RegionGrowing::bbUserSetDefaultValues() { upper=20000; lower=0; bbSetInputInImage(NULL); bbSetOutputOutImage(NULL); bbSetInputUpper(upper); bbSetInputLower(lower); seedPoint.push_back(0); seedPoint.push_back(0); seedPoint.push_back(0); bbSetInputSeedPoint(seedPoint); initialImage=NULL; filteredImage=NULL; voxels=0; } void RegionGrowing::bbUserInitializeProcessing() { } void RegionGrowing::bbUserFinalizeProcessing() { } void RegionGrowing:: connectivity (int x, int y, int z) { //inicializa la estructura MetzData* metzData= new MetzData(x,y,z); //captura el valor de gris de la semilla unsigned short * imagptr= (unsigned short*)initialImage->GetScalarPointer(x,y,z); unsigned short greyLevel =(unsigned short)*imagptr; //comprueba que la semilla este entre los umbrales if ( (greyLevel >= lower) && (greyLevel<= upper)) { mark(x,y,z,VALIDO); //ingresa el voxel en la estructura de la segunda iteracion currentVector.push_back(metzData); int i = 1; while(currentVector.size() > 0) { for(int j=0; j < currentVector.size();j++ ) { MetzData* point = currentVector.at(j); int px=point->getX(); int py=point->getY(); int pz=point->getZ(); addNeighborsToVector(point->getX(),point->getY(),point->getZ(),&nextVector,-1); } currentVector.clear(); currentVector = nextVector; nextVector.clear(); i++; } std::cout << "total iteraciones " << i << std::endl; } else { mark(x,y,z,INVALIDO); } } void RegionGrowing::addNeighborsToVector(int x, int y, int z, std::vector* v, int it) { unsigned short * imagptr; unsigned short greyLeveli; int* filtptr; int greyLevelf; for(int i=x-1; i<=x+1; i++) { for(int j=y-1; j<=y+1; j++) { for(int k=z-1; k<=z+1; k++) { //comprobacion de las dimensiones if( i >=ext[0] && i <= ext[1] && j >=ext[2] && j <= ext[3] && k >=ext[4] && k <= ext[5] && (i!=x || j!=y || k!=z) ) { filtptr= (int*) filteredImage->GetScalarPointer(i,j,k); greyLevelf=(int)*filtptr; //revisa si no se han visitado los voxels if(greyLevelf == NO_VISITADO ) { imagptr= (unsigned short*)initialImage->GetScalarPointer(i,j,k); greyLeveli =(unsigned short)*imagptr; if(greyLeveli >= lower && greyLeveli <= upper) { mark(i,j,k,VALIDO); //lo marca MetzData* point = new MetzData(i,j,k); v->push_back(point); //y lo ingresa al vector } else { mark(i,j,k,INVALIDO); } } else { //std::cout << "VISITADO" << std::endl; } } } } } } //devuelve el numero mde voxeles validos en un radio determinado //a partir del punto semilla int RegionGrowing::countValidPoints (int x, int y, int z) { int voxels=0; for(int p = x-RADIO; p < x+RADIO; p++) { for(int q = y-RADIO; q < y+RADIO; q++) { for(int r = z-RADIO; r < z+RADIO; r++) { //revisa que esten dentro de la imagen if(p >=ext[0] && p <= ext[1] && q >=ext[2] && q <= ext[3] && r >=ext[4] && r <= ext[5]) { if(pow(p-x,2)+pow(q-y,2)+pow(r-z,2)<=pow(RADIO, 2)) { int * imagptr= (int*)filteredImage->GetScalarPointer(p,q,r); int grey=*imagptr; if(grey == VALIDO) { voxels++; } } } } } } return voxels; } void RegionGrowing::invalidateSegment(int x, int y ,int z) { for(int p = x-RADIO; p < x+RADIO; p++) { for(int q = y-RADIO; q < y+RADIO; q++) { for(int r = z-RADIO; r < z+RADIO; r++) { if(pow(p-x,2)+pow(q-y,2)+pow(r-z,2)GetScalarPointer(p,q,r); int grey=*imagptr; mark(p,q,r,INVALIDO); } } } } } void RegionGrowing::cleanVector(std::vector* v) { for(int i= 0 ; i < v->size(); i++) { MetzData* point = v->at(i); delete point; } v->clear(); } //marca el voxel void RegionGrowing::mark(int x,int y,int z, int it) { int * imagptr= (int*) filteredImage->GetScalarPointer(x,y,z); *imagptr = it; } //revisa si el voxel no ha sido visitado bool RegionGrowing::isMarked(int x,int y,int z) { int * imagptr= (int*)filteredImage->GetScalarPointer(x,y,z); int greyLevel =(int)*imagptr; if(greyLevel == VALIDO || greyLevel == INVALIDO) { return true; } imagptr = NULL; return false; } } // EO namespace bbUtilities