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; }
void Segment_Channel(Array *input, Segmentation *seg) { double mean, sdev; int threshc, threshe, sizemin; Array *labels; Histogram *hist = Histogram_Array(input,0x100,VALU(1),VALU(0)); mean = Histogram_Mean(hist); sdev = Histogram_Sigma(hist); threshc = mean + Get_Double_Arg("-c")*sdev; threshe = mean + Get_Double_Arg("-e")*sdev; sizemin = Get_Int_Arg("-s"); #ifdef PROGRESS printf("\nChannel Segmentation:\n"); printf(" Mean = %.2f Std.Dev = %.2f\n",mean,sdev); printf(" Thresh-c = %d Thresh-e = %d Size-s = %d\n",threshc,threshe,sizemin); #ifdef DEBUG Print_Histogram(hist,stdout,4,BIN_COUNT|CUMULATIVE_COUNT|CLIP_HGRAM,0); #endif fflush(stdout); #endif Free_Histogram(hist); labels = Make_Array(PLAIN_KIND,UINT8_TYPE,3,input->dims); Array_Op_Scalar(labels,SET_OP,UVAL,VALU(0)); SEG_threshc = threshc; SEG_threshe = threshe; SEG_sizemin = sizemin; SEG_values = AUINT16(input); SEG_labels = AUINT8(labels); SEG_count = 0; SEG_coretouch = 0; SEG_id = 0; // Mark connected-components of pixels >= threshc that have not less than sizemin pixels Flood_All(input,0,ISCON2N,NULL,InCore,NULL,CountCore,NULL,GoodCore,NULL,MarkAsIn); // Mark all connected components of pixels >= threshe that contain a good core as above Flood_All(input,0,ISCON2N,NULL,InExtend,NULL,TouchCore,NULL,GoodExtend,NULL,SetLabel); // Capture each labeled region in "labels" with a Region { int i, nsegs; Indx_Type p; uint8 *val; Region **segs; seg->label = labels; seg->nsegs = nsegs = SEG_id; seg->segs = segs = (Region **) Guarded_Malloc(sizeof(Region *)*nsegs,Program_Name()); seg->mean = mean; seg->ethresh = threshe; seg->cthresh = threshc; for (i = 0; i < nsegs; i++) segs[i] = NULL; val = AUINT8(labels); for (p = 0; p < labels->size; p++) { i = val[p]; if (i > 0 && segs[i-1] == NULL) segs[i-1] = Record_Basic(labels,0,ISCON2N,p,1,EQ_COMP,VALU(i)); } } }
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); }