/* ** Uses a levelset and size threshold to segment an image constrained by the ** zone mask. */ SHARED_EXPORT Object_Map *find_objects(Image *image, int vthresh, int sthresh) { static Object_Map mymap; static int obj_max = 0; static Contour **objects = NULL; static Paint_Brush zero = { 0., 0., 0. }; uint8 *array = image->array; int carea = image->width*image->height; { int p, n; n = 0; for (p = 0; p < carea; p++) if (array[p] >= vthresh) // start at a non-masked pixel { Contour *c = Trace_Region(image,p,GE,vthresh,1); // trace the contour around that pixel Draw_Contour_Interior(c,&zero,image); // mask out that countour if (Contour_Area(c) >= sthresh) // apply a size threshold to the region { if (n >= obj_max) { obj_max = 1.2*n+500; objects = (Contour **) Guarded_Realloc(objects,sizeof(Contour *)*obj_max,Program_Name()); } objects[n++] = c; } else { Free_Contour( c ); } } mymap.num_objects = n; mymap.objects = objects; } return (&mymap); }
int main(int argc, char *argv[]) { char *in, *out; Tiff_Reader *reader; Tiff_Writer *writer; Tiff_IFD *ifd; int flag64, first, source, target; int *colors, nchan; Process_Arguments(argc,argv,Spec,0); in = Get_String_Arg("in"); out = Get_String_Arg("out"); reader = Open_Tiff_Reader(in,NULL,&flag64,strcmp(in+(strlen(in)-4),".lsm") == 0); if (reader == NULL) { fprintf(stderr,"Error opening tif %s:\n %s\n",in,Tiff_Error_String()); exit (1); } writer = Open_Tiff_Writer(out,flag64,0); if (writer == NULL) { fprintf(stderr,"Error opening tif %s:\n %s\n",out,Tiff_Error_String()); exit (1); } nchan = 0; colors = NULL; target = 0; source = 0; first = 1; while ( ! End_Of_Tiff(reader)) { ifd = Read_Tiff_IFD(reader); if (ifd == NULL) { fprintf(stderr,"Error reading IFD:\n %s\n",Tiff_Error_String()); exit (1); } if (first) { first = 0; if (Is_Arg_Matched("-m")) { source = Get_Int_Arg("-m",1); target = Get_Int_Arg("-m",2); if (source < 0 || source > 1) { fprintf(stderr,"Source is not 0 or 1\n"); exit (1); } if (target < 0 || target > 2) { fprintf(stderr,"Target is not 0, 1, or 2\n"); exit (1); } } else if (Get_Tiff_Tag(ifd,TIFF_CZ_LSM_INFO,NULL,NULL) != NULL) { if (nchan == 0) { nchan = Count_LSM_Colors(ifd); colors = (int *) Guarded_Malloc(sizeof(int)*((size_t) nchan),Program_Name()); } Get_LSM_Colors(ifd,nchan,colors); // Figure out which channel is green for (source = 0; source < nchan; source++) // and map to green in the RGB if ((colors[source] & 0xff00) != 0) break; if (source >= nchan) source = 0; target = 1; } else { source = 0; target = 1; } } if (Convert_2_RGB(ifd,source,target) != NULL) { if (Write_Tiff_IFD(writer,ifd)) { fprintf(stderr,"Error writing IFD:\n %s\n",Tiff_Error_String()); exit (1); } } else { fprintf(stderr,"Error adding extra channel:\n %s\n",Tiff_Error_String()); exit (1); } Free_Tiff_IFD(ifd); } Free_Tiff_Writer(writer); exit (0); }
Clusters *Merge_Segments(Segmentation *segs, Overlaps *ovl) { Clusters *clust; int *fathers, *sets, *which; int nsegs, nsets; int j, k; nsegs = ovl->totsegs; which = (int *) Guarded_Malloc(sizeof(int)*(2*nsegs+1),Program_Name()); sets = which + nsegs; fathers = (int *) Guarded_Malloc(sizeof(int)*nsegs,Program_Name()); for (k = 0; k < nsegs; k++) fathers[k] = -1; for (k = 0; k < nsegs; k++) for (j = ovl->alist[k]; j < ovl->alist[k+1]; j++) UNION(fathers,k,ovl->heads[j]); nsets = 0; for (k = 0; k < nsegs; k++) if (fathers[k] < 0) { nsets += 1; fathers[k] = -nsets; } else fathers[k] = FIND(fathers,k); for (k = 0; k < nsegs; k++) if (fathers[k] > 0) fathers[k] = fathers[fathers[k]]; for (k = 0; k < nsegs; k++) fathers[k] = -(fathers[k]+1); for (k = 0; k <= nsets; k++) sets[k] = 0; for (k = 0; k < nsegs; k++) sets[fathers[k]+1] += 1; for (k = 2; k <= nsets; k++) sets[k] += sets[k-1]; for (k = 0; k < nsegs; k++) { which[sets[fathers[k]]] = k; sets[fathers[k]] += 1; } for (k = nsegs; k > 0; k--) sets[k] = sets[k-1]; sets[0] = 0; free(fathers); clust = (Clusters *) Guarded_Malloc(sizeof(Clusters),Program_Name()); clust->inum = nsets; clust->ilist = sets; clust->item = which; #ifdef VERBOSE printf("\nClusters:\n"); for (k = 0; k < nsets; k++) { printf(" Set %3d:",k); for (j = sets[k]; j < sets[k+1]; j++) { int c = ovl->chans[which[j]]; printf(" %c%d",Letter[c],(which[j]-segs[c].base)+1); } printf("\n"); fflush(stdout); } fflush(stdout); #endif return (clust); }
SHARED_EXPORT Seed_Vector *decompose_trace_x(Contour *trace, int width, int height, uint8 *value) { static Seed *seedlist = NULL; static int seedmax = 0; static Seed_Vector myseeds; static Seed *boo; int *yaster, ypairs; Raster *raster; int nseeds; int ntrk, mtrk, etrk; int r, x, x0; nseeds = 0; yaster = Yaster_Scan(trace,&ypairs,height); // reencode yaster as (x,y) points - in place raster = (Raster *) yaster; for (r = 0; r < ypairs; r++) { int mj = yaster[r]/height; // x int mn = yaster[r]%height; // y raster[r].major = mj; // x raster[r].minor = mn; // y } #ifdef SHOW_BRANCHES printf("\nTRACE:\n"); fflush(stdout); #endif ntrk = mtrk = etrk = 0; r = 0; while (r < ypairs) { x0 = x = raster[r].major; // the x value for this (vertical) raster #ifdef SHOW_TRACE printf(" %d:",x0); fflush(stdout); #endif ntrk = mtrk; mtrk = etrk; // advance over vertically aligned intervals in the raster while (x == x0) { raster[r].major = 0; // mark it #ifdef SHOW_TRACE // y0 y1 printf(" (%d,%d)",raster[r].minor,raster[r+1].minor-1); fflush(stdout); #endif r += 2; // move to next pair if (r >= ypairs) break; x = raster[r].major; } etrk = r; // remember the end of this sequence of intervals #ifdef SHOW_TRACE printf("\n"); fflush(stdout); #endif { int m, n; int mb, me; int nb, ne; int c, o; Seed *s; m = mtrk; n = ntrk; c = 0; while (n < mtrk) { if (m >= etrk) //if the end of this sequence of intervals has been passed... mb = me = ne; //...empty m interval located at end of n else { mb = raster[m].minor; //beginning of the m'th interval me = raster[m+1].minor; //end of the m'th interval } nb = raster[n].minor; //beginning of the n'th interval ne = raster[n+1].minor; //end of the n'th interval // init if (me > nb && ne > mb) //if the intervals have an intersection... { raster[m].major += 1; //...increment m's id c += 1; //...count } if (me < ne) //if m's end is before n's ... m += 2; //...increment to interval following m and move on else //else m and n intersect or m is past n { raster[n+1].major = -1; //...mark next if (c > 1) //if there was more than one intersection event... { // move o back till all intersection counts are accounted for // and add counts into interval labels o = m; while (1) { if (me > nb && ne > mb) // if m and n intersect ... { raster[o].major += 1; // ...increment label if (--c <= 0) break; // ...clear counts } o -= 2; // back up an interval mb = raster[o].minor; me = raster[o+1].minor; } } else if (c == 1) // if only one intersection count { if (ne > mb) { if ((n+2 >= mtrk || raster[n+2].minor >= me) && raster[m].major <= 1) raster[n+1].major = m; } else { if (raster[m-2].major <= 1) raster[n+1].major = m-2; } } #ifdef SHOW_BRANCHES if (raster[n+1].major < 0) printf("Track (%d,%d) %d expires\n", raster[n].minor,raster[n+1].minor-1,raster[n].major); #endif n += 2; c = 0; } } for (m = mtrk; m < etrk; m += 2) //iterate over sequence of vertically aligned intervals if (raster[m].major != 1) //if unlabelled { #ifdef SHOW_BRANCHES printf("Track (%d,%d) = %d starts\n", raster[m].minor,raster[m+1].minor-1,raster[m].major); #endif raster[m].major = 1; //...init label } for (n = ntrk; n < mtrk; n += 2) { c = raster[n+1].major; raster[n+1].major = x0-1; // set back to x0 if (c < 0) // if termination...compute seed on n'th { if (nseeds >= seedmax) { seedmax = 1.2*nseeds + 10; seedlist = (Seed *) Guarded_Realloc(seedlist,sizeof(Seed)*seedmax,Program_Name()); } s = compute_seed(raster,n,x0-1,width,value); if (s != NULL) seedlist[nseeds++] = *s; } else raster[c].major = raster[n].major+1; } } //end context } //end while { int m; Seed *s; for (m = mtrk; m < etrk; m += 2) { if (nseeds >= seedmax) { seedmax = 1.2*nseeds + 10; seedlist = (Seed *) Guarded_Realloc(seedlist,sizeof(Seed)*seedmax,Program_Name()); } s = compute_seed(raster,m,x0,width,value); if (s != NULL) seedlist[nseeds++] = *s; #ifdef SHOW_BRANCHES printf("Track (%d,%d) %d = 0 expires\n", raster[m].minor,raster[m+1].minor-1,raster[m].major); #endif } } myseeds.nseeds = nseeds; myseeds.seeds = seedlist; return (&myseeds); }
Overlaps *Find_Overlaps(Segmentation *segs) { Overlaps *ovl; int totsegs, *alist, *heads, *chans; int ecount, emax; uint8 **vals; Size_Type k; Indx_Type v, w, p; Region *rci; int c, d; int i, j; totsegs = segs[NumChans-1].base + segs[NumChans-1].nsegs; alist = (int *) Guarded_Malloc(sizeof(int)*(totsegs+1),Program_Name()); chans = (int *) Guarded_Malloc(sizeof(int)*totsegs,Program_Name()); emax = totsegs*NumChans; heads = (int *) Guarded_Malloc(sizeof(int)*emax,Program_Name()); for (k = 0; k <= totsegs; k++) alist[k] = 0; vals = (uint8 **) Guarded_Malloc(sizeof(uint8 *)*NumChans,Program_Name()); for (k = 0; k < NumChans; k++) vals[k] = AUINT8(segs[k].label); ecount = 0; for (c = 0; c < NumChans-1; c++) { printf("channel=%d numSegs=%d\n", c, segs[c].nsegs); for (i = 0; i < segs[c].nsegs; i++) { rci = segs[c].segs[i]; alist[segs[c].base+i] = ecount; chans[segs[c].base+i] = c; for (k = 0; k < rci->rastlen; k += 2) { v = rci->raster[k]; w = rci->raster[k+1]; for (p = v; p <= w; p++) for (d = c+1; d < NumChans; d++) { // printf("vals d=%d p=%d =%d\n", d, p, vals[d][p]); if (vals[d][p] > 0) { j = segs[d].base+(vals[d][p]-1); alist[j] += 1; if (alist[j] == MIN_OVERLAP) { if (ecount >= emax) { emax = 1.2*emax + 100; heads = (int *) Guarded_Realloc(heads,sizeof(int)*emax,Program_Name()); } heads[ecount++] = j; } } } } for (j = segs[c+1].base; j < totsegs; j++) alist[j] = 0; } } for (i = 0; i <= segs[c].nsegs; i++) { alist[segs[c].base+i] = ecount; chans[segs[c].base+i] = c; } free(vals); ovl = (Overlaps *) Guarded_Malloc(sizeof(Overlaps),Program_Name()); ovl->totsegs = totsegs; ovl->alist = alist; ovl->heads = heads; ovl->chans = chans; #ifdef VERBOSE { int k, h, c, i, d; printf("\nOverlaps:\n"); for (k = 0; k < ovl->totsegs; k++) { c = chans[k]; d = (k-segs[c].base)+1; if (d < 10) printf(" "); else if (d < 100) printf(" "); printf(" %c%d:",Letter[c],(k-segs[c].base)+1); for (h = alist[k]; h < alist[k+1]; h++) { i = heads[h]; c = chans[i]; printf(" %c%d",Letter[c],(i-segs[c].base)+1); } printf("\n"); fflush(stdout); } fflush(stdout); } #endif return (ovl); }
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 loadRaw2Stack(char * filename, unsigned char ** img, long ** sz, int datatype) //this is the function of 4-byte raw format. { /* This function reads 2-4D image stack from raw data generated by the program "saveStack2Raw.m". */ /* The input parameters img, sz, and datatype should be empty, especially the pointers "img" and "sz". */ int berror = 0; FILE * fid = fopen(filename, "rb"); if (!fid) { printf("Fail to open file for reading.\n"); berror = 1; return berror; } fseek (fid, 0, SEEK_END); long fileSize = ftell(fid); rewind(fid); /* Read header */ char formatkey[] = "raw_image_stack_by_hpeng"; long lenkey = strlen(formatkey); if (fileSize<lenkey+2+4*4+1) // datatype has 2 bytes, and sz has 4*4 bytes and endian flag has 1 byte. { printf("The size of your input file is too small and is not correct, -- it is too small to contain the legal header.\n"); printf("The fseek-ftell produces a file size = %ld.", fileSize); berror = 1; return berror; } char * keyread = (char*)Guarded_Malloc((lenkey+1)*sizeof(char), Program_Name()); if (!keyread) { printf("Fail to allocate memory.\n"); berror = 1; return berror; } long nread = fread(keyread, 1, lenkey, fid); if (nread!=lenkey) { printf("File unrecognized or corrupted file.\n"); berror = 1; return berror; } keyread[lenkey] = '\0'; long i; if (strcmp(formatkey, keyread)) /* is non-zero then the two strings are different */ { printf("Unrecognized file format.\n"); if (keyread) {free(keyread); keyread=0;} berror = 1; return berror; } char endianCodeData; fread(&endianCodeData, 1, 1, fid); if (endianCodeData!='B' && endianCodeData!='L') { printf("This program only supports big- or little- endian but not other format. Check your data endian.\n"); berror = 1; if (keyread) {free(keyread); keyread=0;} return berror; } char endianCodeMachine; endianCodeMachine = checkMachineEndian(); if (endianCodeMachine!='B' && endianCodeMachine!='L') { printf("This program only supports big- or little- endian but not other format. Check your data endian.\n"); berror = 1; if (keyread) {free(keyread); keyread=0;} return berror; } int b_swap = (endianCodeMachine==endianCodeData)?0:1; printf("machine endian=[%c] data endian=[%c] b_swap=%d\n", endianCodeMachine, endianCodeData, b_swap); short int dcode = 0; fread(&dcode, 2, 1, fid); /* because I have already checked the file size to be bigger than the header, no need to check the number of actual bytes read. */ if (b_swap) swap2bytes((void *)&dcode); switch (dcode) { case 1: datatype = 1; /* temporarily I use the same number, which indicates the number of bytes for each data point (pixel). This can be extended in the future. */ break; case 2: datatype = 2; break; case 4: datatype = 4; break; default: printf("Unrecognized data type code [%d]. The file type is incorrect or this code is not supported in this version.\n", dcode); if (keyread) {free(keyread); keyread=0;} berror = 1; return berror; } long unitSize = datatype; // temporarily I use the same number, which indicates the number of bytes for each data point (pixel). This can be extended in the future. printf("loadRaw2Stack unitSize=%d\n", unitSize); unsigned int mysz[4]; mysz[0]=mysz[1]=mysz[2]=mysz[3]=0; int tmpn=fread(mysz, 4, 4, fid); // because I have already checked the file size to be bigger than the header, no need to check the number of actual bytes read. if (tmpn!=4) { printf("This program only reads [%d] units.\n", tmpn); berror=1; return berror; } if (b_swap) { for (i=0;i<4;i++) { //swap2bytes((void *)(mysz+i)); printf("mysz raw read unit[%ld]: [%d] ", i, mysz[i]); swap4bytes((void *)(mysz+i)); printf("swap unit: [%d][%0x] \n", mysz[i], mysz[i]); } } if (*sz) {free(*sz); *sz=0;} *sz=(long*)Guarded_Malloc(4*sizeof(long), Program_Name()); if (!(*sz)) { printf("Fail to allocate memory.\n"); if (keyread) {free(keyread); keyread=0;} berror = 1; return berror; } long totalUnit = 1; for (i=0;i<4;i++) { (*sz)[i] = (long)mysz[i]; totalUnit *= (*sz)[i]; } //mexPrintf("The input file has a size [%ld bytes], different from what specified in the header [%ld bytes]. Exit.\n", fileSize, totalUnit*unitSize+4*4+2+1+lenkey); //mexPrintf("The read sizes are: %ld %ld %ld %ld\n", sz[0], sz[1], sz[2], sz[3]); if ((totalUnit*unitSize+4*4+2+1+lenkey) != fileSize) { printf("The input file has a size [%ld bytes], different from what specified in the header [%ld bytes]. Exit.\n", fileSize, totalUnit*unitSize+4*4+2+1+lenkey); printf("The read sizes are: %ld %ld %ld %ld\n", (*sz)[0], (*sz)[1], (*sz)[2], (*sz)[3]); printf("The read sizes are: %d %d %d %d\n", mysz[0], mysz[1], mysz[2], mysz[3]); if (keyread) {free(keyread); keyread=0;} if (*sz) {free(*sz); *sz=0;} berror = 1; return berror; } if (*img) {free(*img); *img=0;} long totalBytes = unitSize*totalUnit; *img = (unsigned char *)Guarded_Malloc(totalBytes*sizeof(unsigned char), Program_Name()); if (*img==0 || *img==NULL) { fprintf(stderr, "Fail to allocate memory in loadRaw2Stack().\n"); if (keyread) {free(keyread); keyread=0;} if (*sz) {free(*sz); *sz=0;} berror = 1; return berror; } long remainingBytes = totalBytes; long nBytes2G = 1024L*1024L*1024L*2L; long cntBuf = 0; while (remainingBytes>0) { long curReadBytes = (remainingBytes<nBytes2G) ? remainingBytes : nBytes2G; long curReadUnits = curReadBytes/unitSize; nread = fread(*img+cntBuf*nBytes2G, unitSize, curReadUnits, fid); if (nread!=curReadUnits) { printf("Something wrong in file reading. The program reads [%ld data points] but the file says there should be [%ld data points].\n", nread, totalUnit); if (keyread) {free(keyread); keyread=0;} if (*sz) {free(*sz); *sz=0;} if (*img) {free(*img); *img=0;} berror = 1; return berror; } remainingBytes -= nBytes2G; cntBuf++; } // swap the data bytes if necessary if (b_swap==1) { if (unitSize==2) { for (i=0;i<totalUnit; i++) { swap2bytes((void *)(*img+i*unitSize)); } } else if (unitSize==4) { for (i=0;i<totalUnit; i++) { swap4bytes((void *)(*img+i*unitSize)); } } } // clean and return if (keyread) {free(keyread); keyread = 0;} fclose(fid); //bug fix on 060412 double min=0.0, max=0.0; if (datatype==1) { findMinMax8bit(&min, &max, *img, totalUnit); } else if (datatype==2) { findMinMax16bit(&min, &max, *img, totalUnit); } else if (datatype==4) { findMinMaxFloat(&min, &max, *img, totalUnit); } printf("loadRaw2Stack() Min=%f Max=%f\n", min, max); return berror; }
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); }
int Read_All_Channels(string name, int maxchans) { Tiff *tif; int depth, height, width, chans; int i; if(strcmp(getSuffix(name), "tif")==0 || strcmp(getSuffix(name), "lsm")==0) { tif = Open_Tiff(name,"r"); if (tif == NULL) { fprintf(stderr,"Cannot open file %s for reading\n",name); exit (1); } Get_IFD_Shape(tif,&width,&height,&chans); printf("width=%d height=%d chans=%d\n", width, height, chans); if (chans < 2) { fprintf(stderr,"LSM %s does not at least 2 channels\n",name); exit (1); } depth = 0; while ( ! Tiff_EOF(tif)) { int w, h, c; Get_IFD_Shape(tif,&w,&h,&c); if (w == width && h == height && c == chans) { for (i = 0; i < chans; i++) if (Get_IFD_Channel_Type(tif,i) != UINT16_TYPE) { fprintf(stderr,"Channel %d of %s is not 16-bit)\n",i,name); exit (1); } depth += 1; } Advance_Tiff(tif); } Rewind_Tiff(tif); if (NumChans + chans > maxchans) { maxchans = 1.2*(NumChans+chans) + 20; Images = (Array **) Guarded_Realloc(Images,sizeof(Array *)*maxchans,Program_Name()); } for (i = NumChans; i < NumChans + chans; i++) Images[i] = Make_Array_With_Shape(PLAIN_KIND,UINT16_TYPE,Coord3(depth,height,width)); depth = 0; while ( ! Tiff_EOF(tif)) { int w, h, c; Get_IFD_Shape(tif,&w,&h,&c); if (w == width && h == height && c == chans) { for (i = 0; i < chans; i++) { Array_Bundle plane = *(Images[NumChans+i]); Get_IFD_Channel(tif,i,Get_Array_Plane(&plane,depth)); } depth += 1; } Advance_Tiff(tif); } Close_Tiff(tif); NumChans += chans; return (maxchans); } else if (strcmp(getSuffix(name), "raw")==0 || strcmp(getSuffix(name), "v3draw")==0) { unsigned char* img; long* sz; img=0; sz=0; int rawLoadResult=loadRaw2Stack(name, &img, &sz, 2); if (rawLoadResult!=0) { fprintf(stderr, "Load of raw file failed\n"); exit(1); } if (sizeof(unsigned short)!=2) { fprintf(stderr, "Read_All_Channels() making false assumption that unsigned short is size=2\n"); exit(1); } unsigned short* rawp=(unsigned short*)img; width=sz[0]; height=sz[1]; depth=sz[2]; chans=sz[3]; printf("width=%d height=%d depth=%d chans=%d\n", width, height, depth, chans); if (chans < 2) { fprintf(stderr,"File %s does not contain at least 2 channels\n",name); exit (1); } if (NumChans + chans > maxchans) { maxchans = 1.2*(NumChans+chans) + 20; Images = (Array **) Guarded_Realloc(Images,sizeof(Array *)*maxchans,Program_Name()); } for (i = NumChans; i < NumChans + chans; i++) { Images[i] = Make_Array_With_Shape(PLAIN_KIND,UINT16_TYPE,Coord3(depth,height,width)); { int rx,ry,rz; uint16 *v; Indx_Type p; v = AUINT16(Images[i]); p = 0; long oc=(i-NumChans)*depth*height*width; for (rz=0;rz<depth;rz++) { long oz = rz*height*width; for (ry=0;ry<height;ry++) { long oy = ry*width; for (rx=0;rx<width;rx++) { long offset=oc + oz + oy + rx; unsigned short uv = *(rawp + offset); v[p++] = uv; } } } } } NumChans += chans; return (maxchans); } else { fprintf(stderr, "Do not recognize file suffix %s\n", getSuffix(name)); exit(1); } }