コード例 #1
0
itk::Matrix< double , 3 , 3 > ComputeMatrixSquareRoot( itk::Matrix< double , 3 , 3 > matrix )
{
  itk::Matrix< double , 3 , 3 > sqrMatrix;

  vnl_matrix<double> M( 3, 3 );
  M = matrix.GetVnlMatrix();
  vnl_real_eigensystem eig( M );
  vnl_matrix<vcl_complex<double> > D( 3, 3 );
  vnl_matrix<vcl_complex<double> > vnl_sqrMatrix( 3, 3 );
  D.fill( 0.0 );
  for( int i = 0; i < 3; i++ )
    {
    D.put( i, i, vcl_pow( eig.D.get( i, i ), 0.5 ) );
    }
  vnl_sqrMatrix = eig.V * D * vnl_matrix_inverse<vcl_complex<double> >( eig.V );
  vnl_matrix<double> vnl_sqrMatrix_real( 3, 3 );
  vnl_sqrMatrix_real = vnl_real( vnl_sqrMatrix );
  for( int i = 0; i < 3; i++ )
    {
    for( int j = 0; j < 3; j++ )
      {
      sqrMatrix[i][j] = vnl_sqrMatrix_real.get( i, j );
      }
    }
  return sqrMatrix;
}
コード例 #2
0
std::vector<float> compute_ec_features( USImageType::Pointer input_image,  USImageType::Pointer inp_labeled, int number_of_rois, unsigned short thresh, int surr_dist, int inside_dist ){

	std::vector< float > qfied_num;
	std::vector< USImageType::PixelType > labelsList;
	std::vector< double > quantified_numbers_cell;

	typedef itk::ExtractImageFilter< USImageType, UShortImageType > LabelExtractType;
	typedef itk::ImageRegionConstIterator< UShortImageType > ConstIteratorType;
	typedef itk::ImageRegionIteratorWithIndex< USImageType > IteratorType;
	typedef itk::SignedDanielssonDistanceMapImageFilter<FloatImageType, FloatImageType > DTFilter;
	typedef itk::ImageRegionIteratorWithIndex< FloatImageType > IteratorTypeFloat;
	typedef itk::LabelGeometryImageFilter< USImageType > GeometryFilterType;
	typedef GeometryFilterType::LabelIndicesType labelindicestype;

	itk::SizeValueType sz_x, sz_y, sz_z;
	sz_x = input_image->GetLargestPossibleRegion().GetSize()[0];
	sz_y = input_image->GetLargestPossibleRegion().GetSize()[1];
	sz_z = input_image->GetLargestPossibleRegion().GetSize()[2];

	if( sz_x==1 || sz_y==1 || sz_z==1 ){
		LabelExtractType::Pointer deFilter = LabelExtractType::New();
		USImageType::RegionType dRegion = inp_labeled->GetLargestPossibleRegion();
		dRegion.SetSize(2,0);
		deFilter->SetExtractionRegion(dRegion);
		deFilter->SetInput( inp_labeled );
		deFilter->SetDirectionCollapseToIdentity();
		try{
			deFilter->Update();
		}
		catch( itk::ExceptionObject & excep ){
			std::cerr << "Exception caught !" << std::endl;
			std::cerr << excep << std::endl;
		}
		//Dialate input first
		WholeCellSeg *dialate_filter = new WholeCellSeg;
		dialate_filter->set_nuc_img( deFilter->GetOutput() );
		dialate_filter->set_radius( surr_dist );
		dialate_filter->RunSegmentation();
		UShortImageType::Pointer input_lab = dialate_filter->getSegPointer();

		USImageType::Pointer input_labeled = USImageType::New();
		USImageType::PointType origint;
		origint[0] = 0;
		origint[1] = 0;
		origint[2] = 0;
		input_labeled->SetOrigin( origint );
		USImageType::IndexType startt;
		startt[0] = 0;  // first index on X
		startt[1] = 0;  // first index on Y
		startt[2] = 0;  // first index on Z
		USImageType::SizeType  sizet;
		sizet[0] = inp_labeled->GetLargestPossibleRegion().GetSize()[0];  // size along X
		sizet[1] = inp_labeled->GetLargestPossibleRegion().GetSize()[1];  // size along Y
		sizet[2] = inp_labeled->GetLargestPossibleRegion().GetSize()[2];  // size along Z
		USImageType::RegionType regiont;
		regiont.SetSize( sizet );
		regiont.SetIndex( startt );
		input_labeled->SetRegions( regiont );
		input_labeled->Allocate();
		input_labeled->FillBuffer(0);
		input_labeled->Update();

		ConstIteratorType pix_buf1( input_lab, input_lab->GetRequestedRegion() );
		IteratorType iterator2 ( input_labeled, input_labeled->GetRequestedRegion() );
		iterator2.GoToBegin();
		for ( pix_buf1.GoToBegin(); !pix_buf1.IsAtEnd(); ++pix_buf1 ){
			iterator2.Set( pix_buf1.Get() );
			++iterator2;
		}

		std::vector< float > quantified_numbers;

		typedef itk::LabelGeometryImageFilter< USImageType > GeometryFilterType;
		typedef GeometryFilterType::LabelIndicesType labelindicestype;

		GeometryFilterType::Pointer geomfilt1 = GeometryFilterType::New();

		geomfilt1->SetInput( input_labeled );
		geomfilt1->SetCalculatePixelIndices( true );
		geomfilt1->Update();
		labelsList = geomfilt1->GetLabels();

		bool zp=false;
		for( USImageType::PixelType i=0; i < labelsList.size(); ++i ){
			if( labelsList[i] == 0 ){ zp=true; continue; }
			std::vector<float> quantified_numbers_cell;
			for( unsigned j=0; j<number_of_rois; ++j ) quantified_numbers_cell.push_back((float)0.0);
			double centroid_x = geomfilt1->GetCentroid(labelsList[i])[0];
			double centroid_y = geomfilt1->GetCentroid(labelsList[i])[1];
			labelindicestype indices1;
			indices1 = geomfilt1->GetPixelIndices(labelsList[i]);
			for( labelindicestype::iterator itPixind = indices1.begin(); itPixind!=indices1.end(); ++itPixind ){
				IteratorType iterator1 ( input_image, input_image->GetRequestedRegion() );
				iterator1.SetIndex( *itPixind );
				if( iterator1.Get() < thresh )
					continue;
				double x = iterator1.GetIndex()[0];
				double y = iterator1.GetIndex()[1];
				double angle = atan2((centroid_y-y),fabs(centroid_x-x));
				if( (centroid_x-x)>0 )
					angle += M_PI_2;
				else
					angle = M_PI+M_PI-(angle+M_PI_2);
				angle = ((number_of_rois-1)*angle)/(2*M_PI);
				double angle_fraction[1];
				unsigned angular_index;
				if( modf( angle, angle_fraction ) > 0.5 )
					angular_index = ceil( angle );
				else
					angular_index = floor( angle );
				
				quantified_numbers_cell[angular_index] += iterator1.Get();
			}
			for( unsigned j=0; j<number_of_rois; ++j ) quantified_numbers.push_back(quantified_numbers_cell[j]);
		}
		unsigned qnum_sz = zp? (labelsList.size()-1) : (labelsList.size());
		for( unsigned i=0; i<qnum_sz; ++i ){
			unsigned counter=0;
			for( unsigned j=0; j<number_of_rois; ++j ){
				if( quantified_numbers[(i*number_of_rois+j)] > (255.0*surr_dist) )
					++counter;
			}
			qfied_num.push_back(counter);
		}
	}
	else{
		GeometryFilterType::Pointer geomfilt1 = GeometryFilterType::New();
		geomfilt1->SetInput( inp_labeled );
		geomfilt1->SetCalculatePixelIndices( true );
		geomfilt1->Update();
		labelsList = geomfilt1->GetLabels();
		std::cout<<std::endl<<"The size is: "<<labelsList.size();
		if( labelsList.size() == 1 )
		{
			qfied_num.clear();
			return qfied_num;
		}
		bool zp=false; USPixelType zero;
		//Check if the background is also included
		for( USPixelType i=0; i<labelsList.size(); ++i ) if( labelsList[i] == 0 ){ zp=true; zero = i; }

		USImageType::SizeType  sizee;
		sizee[0] = inp_labeled->GetLargestPossibleRegion().GetSize()[0];  // size along X
		sizee[1] = inp_labeled->GetLargestPossibleRegion().GetSize()[1];  // size along Y
		sizee[2] = inp_labeled->GetLargestPossibleRegion().GetSize()[2];  // size along Z

		itk::SizeValueType roi_list_size = zp ?
					((itk::SizeValueType)number_of_rois*(labelsList.size()-1)*2) : 
					((itk::SizeValueType)number_of_rois*labelsList.size()*2);
		std::vector<double> quantified_numbers_cell((roi_list_size),0.0
			);
		std::cout<<"Bounding boxes computed"<<std::endl;

#ifdef _OPENMP
itk::MultiThreader::SetGlobalDefaultNumberOfThreads(1);
#pragma omp parallel for
#if _OPENMP < 200805L
		for( int i=0; i<labelsList.size(); ++i )
#else
		for( USImageType::PixelType i=0; i<labelsList.size(); ++i )
#endif
#else
		for( USImageType::PixelType i=0; i<labelsList.size(); ++i )
#endif
		{
			itk::SizeValueType ind;
			if( zp && (zero==i) ) continue;
			if( zp && (i>zero)  ) ind = i-1;
			else ind = i;
			//Get label indices
			labelindicestype indices1;
			double centroid_x,centroid_y,centroid_z;
			GeometryFilterType::BoundingBoxType boundbox;
			#pragma omp critical
			{
				indices1 = geomfilt1->GetPixelIndices(labelsList[i]);
				//Get Centroid
				centroid_x = geomfilt1->GetCentroid(labelsList[i])[0];
				centroid_y = geomfilt1->GetCentroid(labelsList[i])[1];
				centroid_z = geomfilt1->GetCentroid(labelsList[i])[2];
				//Create an image with bounding box + 2 * outside distance + 2
				//and get distance map for the label
				boundbox = geomfilt1->GetBoundingBox(labelsList[i]);
			}
			//Create vnl array 3xN( label indicies )
			vnl_matrix<double> B(3,indices1.size());

			FloatImageType::Pointer inp_lab = FloatImageType::New();
			FloatImageType::PointType origint; origint[0] = 0; origint[1] = 0; origint[2] = 0;
			inp_lab->SetOrigin( origint );
			FloatImageType::IndexType startt;
			startt[0] = 0;  // first index on X
			startt[1] = 0;  // first index on Y
			startt[2] = 0;  // first index on Z
			FloatImageType::SizeType  sizet;
			sizet[0] = boundbox[1]-boundbox[0]+2*surr_dist+2;  // size along X
			sizet[1] = boundbox[3]-boundbox[2]+2*surr_dist+2;  // size along Y
			sizet[2] = boundbox[5]-boundbox[4]+2*surr_dist+2;  // size along Z
			FloatImageType::RegionType regiont;
			regiont.SetSize( sizet );
			regiont.SetIndex( startt );
			inp_lab->SetRegions( regiont );
			inp_lab->Allocate();
			inp_lab->FillBuffer(0.0);
			inp_lab->Update();
			IteratorTypeFloat iterator444 ( inp_lab, inp_lab->GetRequestedRegion() );

			//Populate matrix with deviations from the centroid for principal axes and
			//at the same time set up distance-transform computation
			itk::SizeValueType ind1=0;
			for( labelindicestype::iterator itPixind = indices1.begin(); itPixind!=indices1.end(); ++itPixind ){
				IteratorType iterator3( input_image, input_image->GetRequestedRegion() );
				iterator3.SetIndex( *itPixind );
				B(0,(ind1)) = iterator3.GetIndex()[0]-centroid_x;
				B(1,(ind1)) = iterator3.GetIndex()[1]-centroid_y;
				B(2,(ind1)) = iterator3.GetIndex()[2]-centroid_z;
				FloatImageType::IndexType cur_in;
				cur_in[0] = iterator3.GetIndex()[0]-boundbox[0]+1+surr_dist;
				cur_in[1] = iterator3.GetIndex()[1]-boundbox[2]+1+surr_dist;
				cur_in[2] = iterator3.GetIndex()[2]-boundbox[4]+1+surr_dist;
				iterator444.SetIndex( cur_in );
				iterator444.Set( 255.0 );
				++ind1;
			}

			//Compute distance transform for the current object
			DTFilter::Pointer dt_obj= DTFilter::New() ;
			dt_obj->SetInput( inp_lab );
			dt_obj->SquaredDistanceOff();
			dt_obj->InsideIsPositiveOff();
			try{
				dt_obj->Update() ;
			} catch( itk::ExceptionObject & err ){
				std::cerr << "Error in Distance Transform: " << err << std::endl;
			}
			FloatImageType::Pointer dist_im = dt_obj->GetOutput();

			//Use KLT to compute pricipal axes
			vnl_matrix<double> B_transp((int)indices1.size(),3);
			B_transp = B.transpose();
			vnl_matrix<double>  COV(3,3);
			COV = B * B_transp;
			double norm = 1.0/(double)indices1.size();
			COV = COV * norm;
			//Eigen decomposition
			vnl_real_eigensystem Eyegun( COV );
			vnl_matrix<vcl_complex<double> > EVals = Eyegun.D;
			double Eval1 = vnl_real(EVals)(0,0); double Eval2 = vnl_real(EVals)(1,1); double Eval3 = vnl_real(EVals)(2,2);
			vnl_double_3x3 EVectMat = Eyegun.Vreal;
			double V1[3],V2[3],EP_norm[3];
			if( Eval1 >= Eval3 && Eval2 >= Eval3 ){
				if( Eval1 >= Eval2 ){
					V1[0] = EVectMat(0,0); V1[1] = EVectMat(1,0); V1[2] = EVectMat(2,0);
					V2[0] = EVectMat(0,1); V2[1] = EVectMat(1,1); V2[2] = EVectMat(2,1);
				} else {
					V2[0] = EVectMat(0,0); V2[1] = EVectMat(1,0); V2[2] = EVectMat(2,0);
					V1[0] = EVectMat(0,1); V1[1] = EVectMat(1,1); V1[2] = EVectMat(2,1);
				}
			} else if( Eval1 >= Eval2 && Eval3 >= Eval2 ) {
				if( Eval1 >= Eval3 ){
					V1[0] = EVectMat(0,0); V1[1] = EVectMat(1,0); V1[2] = EVectMat(2,0);
					V2[0] = EVectMat(0,2); V2[1] = EVectMat(1,2); V2[2] = EVectMat(2,2);
				} else {
					V2[0] = EVectMat(0,0); V2[1] = EVectMat(1,0); V2[2] = EVectMat(2,0);
					V1[0] = EVectMat(0,2); V1[1] = EVectMat(1,2); V1[2] = EVectMat(2,2);
				}
			} else {
				if( Eval2 >= Eval3 ){
					V1[0] = EVectMat(0,1); V1[1] = EVectMat(1,1); V1[2] = EVectMat(2,1);
					V2[0] = EVectMat(0,2); V2[1] = EVectMat(1,2); V2[2] = EVectMat(2,2);
				} else {
					V2[0] = EVectMat(0,1); V2[1] = EVectMat(1,1); V2[2] = EVectMat(2,1);
					V1[0] = EVectMat(0,2); V1[1] = EVectMat(1,2); V1[2] = EVectMat(2,2);
				}
			}
			double n_sum = sqrt( V1[0]*V1[0]+V1[1]*V1[1]+V1[2]*V1[2] );
			V1[0] /= n_sum; V1[1] /= n_sum; V1[2] /= n_sum;
			n_sum = sqrt( V2[0]*V2[0]+V2[1]*V2[1]+V2[2]*V2[2] );
			V2[0] /= n_sum; V2[1] /= n_sum; V2[2] /= n_sum;
			//Get the normal to the plane formed by the biggest two EVs
			EP_norm[0] = V1[1]*V2[2]-V1[2]*V2[1];
			EP_norm[1] = V1[2]*V2[0]-V1[0]*V2[2];
			EP_norm[2] = V1[0]*V2[1]-V1[1]*V2[0];
			//Reassign V2 so that it is orthogonal to both EP_norm and V1
			V2[0] = V1[1]*EP_norm[2]-V1[2]*EP_norm[1];
			V2[1] = V1[2]*EP_norm[0]-V1[0]*EP_norm[2];
			V2[2] = V1[0]*EP_norm[1]-V1[1]*EP_norm[0];
			//Now we have the point normal form; EP_norm is the normal and
			//centroid_x, centroid_y, centroid_z is the point
			//The equation to the plane is EP_norm[0](x-centroid_x)+EP_norm[1](y-centroid_y)+EP_norm[2](z-centroid_z)=0
			double dee = (centroid_x*EP_norm[0]+centroid_y*EP_norm[1]+centroid_z*EP_norm[2])*(-1.00);

			//Iterate through and assign values to each region
			typedef itk::ImageRegionConstIterator< FloatImageType > ConstIteratorTypeFloat;
			ConstIteratorTypeFloat pix_buf2( dist_im, dist_im->GetRequestedRegion() );
			IteratorType iterator44( input_image, input_image->GetRequestedRegion() );

			for ( pix_buf2.GoToBegin(); !pix_buf2.IsAtEnd(); ++pix_buf2 ){
				//Use pixels that are only within the defined radius from the nucleus
				double current_distance = pix_buf2.Get();
				if( (current_distance <= (double)surr_dist) && (current_distance>=(-1*inside_dist)) ){
					USImageType::IndexType cur_in;//,cur_in_cpy;
					double n_vec[3];
					cur_in[0] = pix_buf2.GetIndex()[0]+boundbox[0]-1-surr_dist;
					cur_in[1] = pix_buf2.GetIndex()[1]+boundbox[2]-1-surr_dist;
					cur_in[2] = pix_buf2.GetIndex()[2]+boundbox[4]-1-surr_dist;
					//cur_in_cpy[0] = cur_in[0]; cur_in_cpy[1] = cur_in[1]; cur_in_cpy[2] = cur_in[2];
					if( cur_in[0] < 0 || cur_in[1] < 0 || cur_in[2] < 0 ) continue;
					if( cur_in[0] >= sizee[0] || cur_in[1] >= sizee[1] || cur_in[2] >= sizee[2] ) continue;
					iterator44.SetIndex( cur_in );
					USImageType::PixelType pixel_intensity;
					pixel_intensity = iterator44.Get();
					if( pixel_intensity < thresh ) continue;

					//The projection of the point on the plane formed by the fist two major axes
					double xxx, yyy, zzz;
					xxx = cur_in[0] - EP_norm[0]*((EP_norm[0]*cur_in[0]+EP_norm[1]*cur_in[1]+EP_norm[2]*cur_in[2]+dee)
									/(EP_norm[0]*EP_norm[0]+EP_norm[1]*EP_norm[1]+EP_norm[2]*EP_norm[2]));
					yyy = cur_in[1] - EP_norm[1]*((EP_norm[0]*cur_in[0]+EP_norm[1]*cur_in[1]+EP_norm[2]*cur_in[2]+dee)
									/(EP_norm[0]*EP_norm[0]+EP_norm[1]*EP_norm[1]+EP_norm[2]*EP_norm[2]));
					zzz = cur_in[2] - EP_norm[2]*((EP_norm[0]*cur_in[0]+EP_norm[1]*cur_in[1]+EP_norm[2]*cur_in[2]+dee)
									/(EP_norm[0]*EP_norm[0]+EP_norm[1]*EP_norm[1]+EP_norm[2]*EP_norm[2]));
					//The vector from the centroid to the projected point
					n_vec[0] = centroid_x-xxx;
					n_vec[1] = centroid_y-yyy;
					n_vec[2] = centroid_z-zzz;
					n_sum = sqrt( n_vec[0]*n_vec[0] + n_vec[1]*n_vec[1] + n_vec[2]*n_vec[2] );
					n_vec[0] /= n_sum; n_vec[1] /= n_sum; n_vec[2] /= n_sum;
					//n_vec is the normalized vect in the direction of the projected point
					//V1 is the largest eigenvector
					//Get the dot and cross product between the two
					double doooot, crooos,fin_est_angle;
					doooot = n_vec[0]*V1[0]+n_vec[1]*V1[1]+n_vec[2]*V1[2];
					crooos = n_vec[0]*V2[0]+n_vec[1]*V2[1]+n_vec[2]*V2[2];

					fin_est_angle = atan2( crooos, doooot );
					USPixelType bin_num;
					//Compute bin num
					if( fin_est_angle<0 )
						fin_est_angle += (2*M_PI);
					bin_num = floor(fin_est_angle*number_of_rois/(2*M_PI));

					//Check which side of the plane the point lies on
					double v_norm = (cur_in[0]-centroid_x)*(cur_in[0]-centroid_x)
									+(cur_in[1]-centroid_y)*(cur_in[1]-centroid_y)
									+(cur_in[2]-centroid_z)*(cur_in[2]-centroid_z);
					v_norm = sqrt( v_norm );
					double doot   = (cur_in[0]-centroid_x)*EP_norm[0]/v_norm + (cur_in[1]-centroid_y)*EP_norm[1]/v_norm + (cur_in[2]-centroid_z)*EP_norm[2]/v_norm;

					if( doot<0 )
						bin_num += number_of_rois;
					quantified_numbers_cell.at((ind*(2*number_of_rois)+bin_num)) += pixel_intensity;
				}
			}
		}
		number_of_rois = number_of_rois*2;
		if( labelsList.size() == 1 )
		{
			qfied_num.clear();
			return qfied_num;
		}
		std::vector<double> quantified_numbers_cell_cpy(roi_list_size);
		std::copy(quantified_numbers_cell.begin(), quantified_numbers_cell.end(), quantified_numbers_cell_cpy.begin() );
		//Run k-means
		//Most of the code is adapted from mul/mbl/mbl_k_means.cxx
		std::sort(quantified_numbers_cell.begin(), quantified_numbers_cell.end());
	
		bool skipKmeans;
		double Positive_thresh;
		if( quantified_numbers_cell.at(0) == quantified_numbers_cell.at(quantified_numbers_cell.size()-1) )
			skipKmeans = true;

		if( !skipKmeans ){
			std::cout<<"Starting k-means\n";
			std::cout<<"First:"<<quantified_numbers_cell.at(0)<<" Last:"<<quantified_numbers_cell.at(quantified_numbers_cell.size()-1)<<std::endl;
			unsigned k = 2;
			//Vectors and matrices for k-means
			std::vector< USImageType::PixelType > partition( roi_list_size, 0 );
			std::vector< double > sums   ( k, 0.0 );
			std::vector< double > centers( k, 0.0 );
			std::vector< USImageType::PixelType > nNearest( k, 0 );

			//Use the elements that are evenly spaced to get the intial centers
			for( unsigned i=0; i<k; ++i ){
				double index = ((double)(i)*roi_list_size)/(k+1);
				centers.at(i) = quantified_numbers_cell.at((itk::SizeValueType)index);
				bool duplicated;
				std::cout<<"Initializing centers\n"<<std::flush;
				if(i){
					if( centers.at((i-1)) == centers.at(i) ){
						duplicated = true;
						itk::SizeValueType ind=i+1;
						while( centers.at((i-1))==quantified_numbers_cell.at(ind) )
							++ind;
						centers.at(i) = quantified_numbers_cell.at(ind);
						sums.at(i)    = quantified_numbers_cell.at(ind);
					}
				}
				if(!duplicated)
					sums.at(i) = quantified_numbers_cell.at((i+1)/(k+1));
				++nNearest[i];
			}

			bool changed = true;
			std::cout<<"Waiting for kmeans to converge\n"<<std::flush;
			while(changed){
				changed = false;
				for(itk::SizeValueType i=0; i<roi_list_size; ++i){
					unsigned bestCentre = 0;
					double bestDist = fabs((centers.at(0)-quantified_numbers_cell.at(i)));
					for(unsigned j=1; j<k; ++j){
						double dist = fabs((centers.at(j)-quantified_numbers_cell.at(i)));
						if( dist < bestDist ){
							bestDist = dist; bestCentre = j;
						}
					}
					sums[bestCentre] += quantified_numbers_cell.at(i);
					++ nNearest[bestCentre];
					if( bestCentre != partition.at(i) ){
						changed = true;
						partition.at(i) = bestCentre;
					}
				}
				for( unsigned j=0; j<k; ++j) centers.at(j)  = sums.at(j)/nNearest.at(j);
				for( unsigned j=0; j<k; ++j) sums.at(j)     = 0;
				for( unsigned j=0; j<k; ++j) nNearest.at(j) = 0;
			}
			for( unsigned i=0; i<k; ++i )
				std::cout<<"Center "<<i<<" "<<centers.at(i)<<"\n";

			Positive_thresh = ((centers.at(0)+centers.at(1))/2) < (255.0*thresh)?
						 ((centers.at(0)+centers.at(1))/2) : (255.0*thresh); //Arbitrary upper thresh
		}
		else
			Positive_thresh = 255.0*thresh;

		std::cout<<"Positive_thresh "<<Positive_thresh<<"\n";

		std::cout<<"Done k-means\n";
		itk::SizeValueType ind = 0;
		for( USPixelType i=0; i<labelsList.size(); ++i ){
			if( zp && (zero==i) ) continue;
			int num_positive_rois = 0;
			for( unsigned j=0; j<number_of_rois; ++j ){
				itk::SizeValueType index_of_roi = ind*number_of_rois+j;
				if( quantified_numbers_cell_cpy.at(index_of_roi)>Positive_thresh )
					++num_positive_rois;
			}
			qfied_num.push_back(num_positive_rois);
			++ind;
		}
	}
	std::cout<<"Done surroundedness\n"<<std::flush;
	return qfied_num;
}