Exemple #1
0
 Array * LocalMedianFilter(RasterizedImage & img, ParaSet & imgPara, Array * original, int filterRadius, double threshold ){
   
   uint32 *orig    = AUINT32(original);
   Array  *median = Make_Array_With_Shape(PLAIN_KIND, UINT32_TYPE, Coord2(original->dims[1], original->dims[0]));
   uint32 *med    = AUINT32(median);
   
   Use_Extend_Boundary();
   
   Frame * f = Make_Frame(original,Coord2(2*filterRadius+1,2*filterRadius+1),Coord2(filterRadius, filterRadius));
   Histogram * h = Make_Histogram(UVAL,img.GetDepth(),ValU(1),ValU(0));
   
   
   Place_Frame(f,0);
   for (Indx_Type p = 0; p < median->size; p++){
     Empty_Histogram(h);
     Histagain_Array(h,f,0);
     h->counts[orig[p]]--;              // excludes the height of p in the calculation of the median
     
     if (abs(static_cast<int>(orig[p]) - Percentile2Bin(h,.5)) > threshold) {      // replaces a pixel only if the different between the pixel value and the median is greater than the threshold
       med[p] = Percentile2Bin(h,.5);
     } else {
       med[p] = orig[p];
     }
     Move_Frame_Forward(f);
   }
   
   Kill_Histogram(h);
   Kill_Frame(f);
   
   if (imgPara.verbose){
     std::cout << "Planes filtered" << std::endl;
   }
   
   return median;
 }
Exemple #2
0
 /*
  Median filter that only modifies a pixel when it significantly differs from the median of its 8-connected neighborhood that is weighted by the variance
  
  @param img:        input image
  @param imgPara:    struct with parameters
  @param original:   current height map
  @param filterRadius:     radius to define the 8-connected neighborhood
  @param threshold:  threshold to identify pixels that need to be modified
  */
 Array * LocalMedianFilter_InclVar(RasterizedImage & img, ParaSet & imgPara, Array * original, int filterRadius, double threshold){
   
   uint32 *orig    = AUINT32(original);
   Array  *median = Make_Array_With_Shape(PLAIN_KIND, UINT32_TYPE, Coord2(original->dims[1], original->dims[0]));
   uint32 *med    = AUINT32(median);
   
   Use_Extend_Boundary();
   
   Frame * f = Make_Frame(original,Coord2(2*filterRadius+1,2*filterRadius+1),Coord2(filterRadius, filterRadius));
   
   // Frame to compute the variance in intensity of the current grid element
   Frame * varF = Make_Frame(img.GetImage(),Coord3(1, imgPara.radius,imgPara.radius),Coord3(0, 0, 0));
   Histogram * varH = Make_Histogram(UVAL,256,ValU(1),ValU(0));
   
   uint32 * data;
   
   Place_Frame(f,0);
   Place_Frame(varF, 0);
   
   
   for (Dimn_Type y = 0; y <= img.GetHeight()-imgPara.radius; y += imgPara.radius){
     for (Dimn_Type x = 0; x <= img.GetWidth()-imgPara.radius; x += imgPara.radius){
       
       Indx_Type pHM = (y/imgPara.radius) * original->dims[0] + (x/imgPara.radius);
       Place_Frame(f, pHM);
       data = (uint32 *) Frame_Values(f);
       std::vector<double> depths;
       double sum = 0;
       double n = 0;
       
       for (int i = 0; i < AForm_Size(f); i++) {
         Indx_Type p = Coord2IdxA(img.GetImage(), Coord3(data[i],y, x));
         Place_Frame(varF, p);
         Histagain_Array(varH,varF,0);
         
         sum += Histogram_Variance(varH) * data[i];
         n += Histogram_Variance(varH);
         for (int j=0; j< floor(Histogram_Variance(varH)/10); j++) {   // weight the current height with the variance
           depths.push_back(data[i]);
         }
       }
       double weightedMedian = VectorMedian(depths);
       
       if (abs(orig[pHM] - weightedMedian) > threshold ) {
         med[pHM] = floor(weightedMedian);
       } else {
         med[pHM] = orig[pHM];
       }
       
     }
   }
   
   Kill_Histogram(varH);
   Kill_Frame(varF);
   Kill_Frame(f);
   
   return median;
 }
  double ComputeSmoothness(Array * heightMap) {
    
    Array  * distances = Make_Array_With_Shape(PLAIN_KIND,UINT32_TYPE,Coord2(heightMap->dims[1], heightMap->dims[0]));
    uint32 * distVals   = AUINT32(distances);
    uint32 * hmVals = AUINT32(heightMap);
    
    Use_Reflective_Boundary();
    
    HeightMapRange range = GetLevelRange(heightMap);
    
    // frame defines the local neighborhood
    Frame * f = Make_Frame(heightMap,Coord2(3,3),Coord2(1,1));
    Histogram * h = Make_Histogram(UVAL,range.maxLayer,ValU(1),ValU(0));
    Place_Frame(f,0);
    
    
    for (Indx_Type i=0; i< heightMap->size; i++) {
      
      Empty_Histogram(h);
      Histagain_Array(h, f, 0);
      
      int middleBin = Value2Bin(h, ValU(hmVals[i]));    // To determine the median value of the pixel's neighborhood, we exlude the current pixel i from the histogram
      h->counts[middleBin]--;
      
      distVals[i] = std::abs(static_cast<double>(hmVals[i]) - static_cast<double>(Percentile2Bin(h, 0.5)));
    }
    
#ifdef DEVELOP
    Write_Image("HeightMapSmoothness", distances, DONT_PRESS);
#endif
    
    Empty_Histogram(h);
    Histagain_Array(h, distances, 0);
    
    double meanDistance = Histogram_Mean(h);
    std::cout << "Smoothness:\n   Mean distance: " << meanDistance << "\n   Sd: " << Histogram_Sigma(h) << std::endl;
    
    Free_Histogram(h);
    Free_Frame(f);
    Free_Array(distances);
    
    return meanDistance;
  }
Exemple #4
0
  Array * MedianFilter(RasterizedImage & img, ParaSet & imgPara, Array *original, int filterRadius){
    
    // output image
    Array  *median = Make_Array_With_Shape(PLAIN_KIND,UINT32_TYPE,Coord2(original->dims[1], original->dims[0]));
    uint32 *med    = AUINT32(median);
    uint32 *orig    = AUINT32(original);
    
#ifdef DEVELOP
    Array  *variance = Make_Array_With_Shape(PLAIN_KIND,UINT32_TYPE,Coord2(original->dims[1], original->dims[0]));
    uint32 *var      = AUINT32(variance);
#endif
    
    Use_Reflective_Boundary();
    
    // frames defines the local neighborhood
    Frame * f = Make_Frame(original,Coord2(2*filterRadius+1,2*filterRadius+1),Coord2(filterRadius,filterRadius));
    Histogram * h = Make_Histogram(UVAL,img.GetDepth(),ValU(1),ValU(0));
    Place_Frame(f,0);
    
    for (Indx_Type p = 0; p < median->size; p++){
      Empty_Histogram(h);
      Histagain_Array(h,f,0);
      h->counts[orig[p]]--;              // excludes the height of p in the calculation of the median
      med[p] = Percentile2Bin(h,.5);    // median is given at 50th percentile
#ifdef DEVELOP
      var[p] = 10*Histogram_Sigma(h);
#endif
      Move_Frame_Forward(f);
    }
    
    Kill_Histogram(h);
    Kill_Frame(f);
    
#ifdef DEVELOP
    ShowArray(img, imgPara, "median.tif", median);
    ShowArray(img, imgPara, "variance.tif", variance);
    Free_Array(variance);
#endif
    
    if (imgPara.verbose){
      std::cout << "Planes filtered" << std::endl;
    }
    
    return (median);
  }
int main(int argc, char *argv[])
{ FILE *output;

  Process_Arguments(argc,argv,Spec,0);

#ifdef PROGRESS
  printf("\nParameters: c=%g e=%g s=%d\n",
         Get_Double_Arg("-c"),Get_Double_Arg("-e"),Get_Int_Arg("-s"));
  printf("SubFolder:  %s\n",Get_String_Arg("folder"));
  printf("CoreName:   %s\n",Get_String_Arg("core"));
  fflush(stdout);
#endif

  RezFolder = strdup(Get_String_Arg("folder"));
  if (RezFolder[strlen(RezFolder)-1] == '/')
    RezFolder[strlen(RezFolder)-1] = '\0';

  if (mkdir(RezFolder,S_IRWXU|S_IRWXG|S_IRWXO))
    { if (errno != EEXIST)
        { fprintf(stderr,"Error trying to create directory %s: %s\n",RezFolder,strerror(errno)); 
          exit (1);
        }
    }

  CoreName = strdup(Get_String_Arg("core"));

  sprintf(NameBuf,"%s.neu",CoreName);
  output = fopen(NameBuf,"w");
  fprintf(output,"NEUSEP: Version 0.9\n");

  { Histogram *hist;
    int        curchan;
    int        maxchans;
    int        i, n;

    n = Get_Repeat_Count("inputs");
    fwrite(&n,sizeof(int),1,output);

    hist = Make_Histogram(UVAL,0x10000,VALU(1),VALU(0));

    maxchans = 0;
    for (i = 0; i < n; i++)
      { 
	curchan  = NumChans;
        maxchans = Read_All_Channels(Get_String_Arg("inputs",i),maxchans);
	int channelsInCurrentFile=NumChans-curchan;


        { Size_Type sum, max;
          Indx_Type p;
          int       j, wch;
          uint16   *val;

          max = -1;
          for (j = curchan; j < NumChans; j++)
            { val = AUINT16(Images[j]);
              sum = 0;
              for (p = 0; p < Images[j]->size; p++)
                sum += val[p];
              if (sum > max)
                { max = sum;
                  wch = j;
                }
            }

          fprintf(output,"%s\n",Get_String_Arg("inputs",i));
          j = wch-curchan;
          fwrite(&j,sizeof(int),1,output);

#ifdef PROGRESS
          printf("\n  Eliminating channel %d from %s\n",j+1,Get_String_Arg("inputs",i));
          fflush(stdout);
#endif

	  {
	    // Section to write out the reference channel
	    printf("\n Considering reference channel output, channelsInCurrentFile=%d\n", channelsInCurrentFile);
	    fflush(stdout);
	    if (channelsInCurrentFile>2) { // should work with both lsm pair with channels=3, or raw file with channels=4
	      sprintf(NameBuf,"%s/Reference.tif",RezFolder,CoreName,i);
	      Write_Image(NameBuf,Images[wch],LZW_PRESS);
	    }

	  }

          Free_Array(Images[wch]);
          NumChans -= 1;
          for (j = wch; j < NumChans; j++)
            Images[j] = Images[j+1];
        }

        { int        j, ceil;
          Indx_Type  p;
          uint16    *val;

          for (j = curchan; j < NumChans; j++)
            {
              Histagain_Array(hist,Images[j],0);

              ceil = Percentile2Bin(hist,1e-5);

	      if (ceil==0) {
		fprintf(stderr, "Channel must have non-zero values for this program to function\n");
		exit(1);
	      } 

#ifdef PROGRESS
              printf("  Clipping channel %d at ceil = %d\n",j,ceil); fflush(stdout);
              fflush(stdout);
#endif
    
              val  = AUINT16(Images[j]);
              for (p = 0; p < Images[j]->size; p++)
                { 
		  if (val[p] > ceil)
		    val[p] = ceil;
		  val[p] = (val[p]*4095)/ceil;
		  }
	      //              Convert_Array_Inplace(Images[j],PLAIN_KIND,UINT8_TYPE,8,0);
            }
    
        }
      }

    Free_Histogram(hist);

    printf("Starting ConsolidatedSignal.tif section\n");
    fflush(stdout);

    // NA addition: write tif with re-scaled intensities to serve as basis for mask file
    {
      Array *signalStack;
      signalStack = Make_Array(RGB_KIND,UINT8_TYPE,3,Images[0]->dims);
      uint8 *sp=AUINT8(signalStack);
      int m;
      Indx_Type signalIndex;
      signalIndex=0;
      for (m=0;m<NumChans;m++) {
	sprintf(NameBuf, "%s/Signal_%d.tif", RezFolder, m);
	printf("Writing 16-bit channel file %s...", NameBuf);
	Write_Image(NameBuf, Images[m], LZW_PRESS);
	printf("done\n");
	uint16 *ip=AUINT16(Images[m]);
	Indx_Type  channelIndex;
	for (channelIndex=0;channelIndex<Images[m]->size;channelIndex++) {
	  int value=ip[channelIndex]/16;
	  if (value>255) {
	    value=255;
	  }
	  sp[signalIndex++]=value; // convert 12-bit to 8-bit
	}
      }
      sprintf(NameBuf,"%s/ConsolidatedSignal.tif", RezFolder);
      printf("Writing 8-bit consolidated signal file %s...", NameBuf);
      Write_Image(NameBuf,signalStack,LZW_PRESS);
      printf("done");
      //Free_Array(signalStack); - this is causing a bug
    }

    printf("Finished ConsolidatedSignal.tif section\n");
    fflush(stdout);

  }

  { int           i;
    Segmentation *segs;
    Overlaps     *ovl;
    Clusters     *clust;
    int           numneur;
    Region      **neurons;

    segs = (Segmentation *) Guarded_Malloc(sizeof(Segmentation)*NumChans,Program_Name());

    for (i = 0; i < NumChans; i++)
      { Segment_Channel(Images[i],segs+i);
        if (i == 0)
          segs[i].base = 0;
        else
          segs[i].base = segs[i-1].base + segs[i-1].nsegs;
	printf("channel=%d segmentBase=%d\n", i, segs[i].base);
      }

    ovl     = Find_Overlaps(segs);
    clust   = Merge_Segments(segs,ovl);
    neurons = Segment_Clusters(segs,ovl,clust,&numneur);

    if (Is_Arg_Matched("-gp"))
      Output_Clusters(segs,ovl,clust);
    if (Is_Arg_Matched("-nr"))
      Output_Neurons(numneur,neurons,1);

    // Added for NA
    Output_Consolidated_Mask(numneur,neurons,1);

    fwrite(&numneur,sizeof(int),1,output);
    for (i = 0; i < numneur; i++)
      Write_Region(neurons[i],output);

#ifdef PROGRESS
    printf("\nProduced %d neurons/fragments in %s.neu\n",numneur,CoreName);
    fflush(stdout);
#endif

    printf("DEBUG: starting cleanup\n");
    fflush(stdout);

    for (i = 0; i < numneur; i++) {
      printf("DEBUG: calling Kill_Region on neuron=%d\n", i);
      fflush(stdout);
      Kill_Region(neurons[i]);
    }
    printf("DEBUG: calling Kill_Clusters\n");
    fflush(stdout);
    Kill_Clusters(clust);
    printf("DEBUG: calling Kill_Overlaps\n");
    fflush(stdout);
    //Kill_Overlaps(ovl); - causing a bug
    printf("DEBUG: starting Kill_Segmentation loop\n");
    fflush(stdout);
    for (i = 0; i < NumChans; i++) {
      printf("DEBUG: Kill_Segmentation on index=%d\n", i);
      fflush(stdout);
      Kill_Segmentation(segs+i);
    }
    printf("DEBUG: calling free() on segs\n");
    fflush(stdout);
    free(segs);
  }

  printf("DEBUG: starting filestream cleanup\n");
  fflush(stdout);

  { int i;

    fclose(output);
    free(CoreName);
    free(RezFolder);
    for (i = 0; i < NumChans; i++)
      Kill_Array(Images[i]);
    free(Images);
  }

#ifdef VERBOSE
  printf("\nDid I free all arrays?:\n"); 
  Print_Inuse_List(stdout,4);
#endif

  exit (0);
}