void ExtendedProjectionAlgorithm::SurfaceProjection_8bit (Array * heightMap) {
    
    Array * maxim = MaxProjection_8bit((*image_), imageParameter_);
    Array * index = MaxIndices_8bit((*image_), imageParameter_, maxim);
    
    imageParameter_.radius = imageParameter_.radius/2;
    (*image_).UpdateGrid(2);
    
    Array * refinedLevel = DecomposeImage(heightMap);
    Array * level = SelectPlanes_Variance_UsingHeightMap((*image_), imageParameter_, extendedImageParameter_, refinedLevel);
    Array * filteredLevel = LocalMedianFilter((*image_), imageParameter_, level, 1, (*image_).GetDepth()/10);
    
    Array * corners = InterpolateCorners((*image_), imageParameter_, filteredLevel);
    ResultArrays result = InterpolatePlanes_8bit((*image_), imageParameter_, maxim, corners);
    
    heightMaps_.push_back(filteredLevel);
    interpolatedHeightMaps_.push_back(result.interpolatedHeightMap);
    projections_.push_back(result.projection);
    imageParameter_.layer = 1;
    

    Free_Array(refinedLevel);
    Free_Array(level);
    Free_Array(corners);
  }
Пример #2
0
void Output_Clusters(Segmentation *segs, Overlaps *ovl, Clusters *clust)
{ Array       *stack, *proj;
  int          i, j, k;

#ifdef PROGRESS
  printf("\nGenerating %d color cluster stacks\n",clust->inum);
  fflush(stdout);
#endif

  stack = Make_Array(RGB_KIND,UINT16_TYPE,3,Images[0]->dims);
  proj  = Make_Array(RGB_KIND,UINT16_TYPE,2,Images[0]->dims);

  for (i = 0; i < clust->inum; i++)
    { Array_Op_Scalar(stack,SET_OP,UVAL,VALU(0));

      for (j = clust->ilist[i]; j < clust->ilist[i+1]; j++)
        { Array_Bundle plane;
          int item = clust->item[j];
          int chan = ovl->chans[item];
          int seg  = item - segs[chan].base;
          for (k = 0; k < NumChans; k++)
            { plane = *stack;
              Draw_Region_Image(Get_Array_Plane(&plane,k%3),
                                Images[k],segs[chan].segs[seg]);
            }
        }

      if (!Is_Arg_Matched("-pj"))
        { sprintf(NameBuf,"%s/%s.clust%d.tif",RezFolder,CoreName,i);
          Write_Image(NameBuf,stack,LZW_PRESS);
        }

#ifdef PROGRESS
      printf("*"); fflush(stdout);
#endif

      Z_Projection(stack,proj);
      sprintf(NameBuf,"%s/%s.PR.clust%d.tif",RezFolder,CoreName,i);
      Write_Image(NameBuf,proj,LZW_PRESS);
    }

  Free_Array(proj);
  Free_Array(stack);

#ifdef PROGRESS
  printf("\n"); fflush(stdout);
#endif
}
Пример #3
0
int main(int argc, char* argv[])
{ Range params[3] = { {0.0, 1.0,  0.2},
                      {0.5, 6.5,  0.4},
                      {-M_PI/4.0, M_PI/4.0, M_PI/36.0} };
  Array *bank = Build_Line_Detectors( params[0], params[1], params[2],
                                      7, 2*7+3 );
  { float *p,*d,sum=0.0; 
    d = (float*) bank->data;
    p = d + bank->strides_px[0];
    while( p-- > d )
      sum += *p;
    printf("sum: %g\n",sum);
    if( sum > 0.01 )
      printf("Mean is not zero:  The image is probably too small to support the detector\n");
  }

  { Stack stk, *t;
    stk.kind = 4;
    stk.width  = bank->shape[0];
    stk.height = bank->shape[1];
    stk.depth  = bank->strides_px[0] / bank->strides_px[3];
    stk.array  = (uint8*) bank->data;

    Scale_Stack_To_Range( &stk, 0, 0, 255 );
    t = Translate_Stack( &stk, GREY8 , 0 );
    Write_Stack( "bank.tif", t );

    Free_Stack(t);
  }
  Free_Array( bank );
  return 0;
}
Пример #4
0
void Output_False_Color_Stack(int nsegs, Region **regs, char *name, int which)
{ Array       *stack;
  int          i;
  Color_Bundle color;

#ifdef PROGRESS
  printf("  Generating faux color stack of %s.%s%d.tif\n",CoreName,name,which); fflush(stdout);
  fflush(stdout);
#endif
  
  stack = Make_Array(RGB_KIND,UINT16_TYPE,3,Images[0]->dims);
  Array_Op_Scalar(stack,SET_OP,UVAL,VALU(0));

  color.op = SET_PIX;
  for (i = 0; i < nsegs; i++)
    { color.red   = VALU(rand()%256); 
      color.green = VALU(rand()%256); 
      color.blue  = VALU(rand()%256); 
      Draw_Region(stack,&color,regs[i]);
    }

  sprintf(NameBuf,"%s/%s.%s%d.tif",RezFolder,CoreName,name,which);
  Write_Image(NameBuf,stack,LZW_PRESS);

  Free_Array(stack);
}
Пример #5
0
  Array * Filtering_Confidence (RasterizedImage & img, ParaSet & imgPara, Array * original, int filterRadii [], double threshold, Array * confidence) {
    Array * median = Copy_Array(original);
    
    // iterate through the list of radii and filter the image
    for (int i=0; i < sizeof(filterRadii)/sizeof(*filterRadii); i++) {
      Free_Array(median);
      median = LocalMedianFilter_Confidence(img, imgPara, original, filterRadii[i], threshold, confidence);
      Free_Array(original);
      original = Copy_Array(median);
    }
    
#ifdef DEVELOP
    ShowArray(img, imgPara, "median.tif",median);
#endif
    if (imgPara.verbose){
      std::cout << "Planes filtered" << std::endl;
    }
    
    return median;
  }
Пример #6
0
void main()
{
   // 初始化动态数组
   Dynamic_Array *arr = Init_Array();


   // 插入数据
   for (int i=0; i<10; i++) {
       PushBack_Array(arr, i);
   }

   // 打印
   Print_Array(arr);

   printf("Array capacity = %d \n", arr->capacity);
   printf("Array size= %d \n", arr->size);


   // 动态扩容
   PushBack_Array(arr, 10);
   PushBack_Array(arr, 11);

   // 打印
   Print_Array(arr);

   printf("Array capacity = %d \n", arr->capacity);
   printf("Array size= %d \n", arr->size);


   // 根据位置删除
   RemoveByPos_Array(arr, 8);
   Print_Array(arr);

   // 根据值删除
   RemoveByValue_Array(arr, 7);
   Print_Array(arr);

   // 根据值查找位置
   int pos = Find_Array(arr, 6);
   printf("pos = %d\n", pos);


   // 释放内存(销毁)
   Free_Array(arr);
}
Пример #7
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);
  }
Пример #8
0
  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;
  }
Пример #9
0
int main(int argc, char* argv[])
{ Range params[3] = { {0.0, 1.0,  0.1},
                      {0.5, 4.5,  0.5},
                      {-M_PI/4.0, M_PI/4.0, M_PI/72.0} };
  Array *bank = Build_Harmonic_Line_Detectors( 
                    params[0], 
                    params[1], 
                    params[2], 
                    7, 
                    2*7+3);
  { float *p,*d,sum=0.0; 
    d = (float*) bank->data;
    p = d + bank->strides_px[0];
    while( p-- > d )
      sum += ( *p - round(*p) )*10.0;;
    printf("sum: %g\n",sum);
    if( sum > 0.01 )
      printf("Mean is not zero:  The image is probably too small to support the detector\n");
  }

  { Stack stk, *lbl, *t;
    float *d;
    int i;
    d = (float*) bank->data;
    stk.kind = 4;
    stk.width  = bank->shape[0];
    stk.height = bank->shape[1];
    stk.depth  = bank->strides_px[0] / bank->strides_px[3];
    stk.array  = (uint8*) bank->data;

    lbl = Make_Stack(stk.kind, stk.width, stk.height, stk.depth);
    { int j,labels[NLABELS] = {2,3/*,5,7*/};
      d = (float*) bank->data;
      i =  bank->strides_px[0];
      while( i-- )
      { float v = d[i];
        int   l = lround(v);
        int cnt = 0;
        ( (float*) stk.array )[i] = (v-l)*10.0;
        ( (float*) lbl->array )[i] = 0;
        for(j=0;j<NLABELS;j++)
          if( l > 0.0 )
            if( ((int)l) % labels[j] == 0 )
            { ( (float*) lbl->array )[i] += (j+1);
                cnt++;
            }
          if(cnt)
            ( (float*) lbl->array )[i] /= cnt;
      }
    }


    Scale_Stack_To_Range( &stk, 0, 0, 255 );
    Scale_Stack_To_Range( lbl, 0, 0, 255 );
    t = Translate_Stack( &stk, GREY8 , 0 );
    Free_Stack(t);
    Write_Stack( "evaltest5_weights.tif", t );
    t = Translate_Stack( lbl, GREY8 , 0 );
    Write_Stack( "evaltest5_labels.tif", t );
    Free_Stack(t);
    Free_Stack(lbl);
  }
  Free_Array( bank );
  return 0;
}
Пример #10
0
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);
}
 ExtendedProjectionAlgorithm::~ExtendedProjectionAlgorithm () {
   Free_Array(image_->GetImage());
 }
Пример #12
0
 /*
  Method that presents the image arr with a grid overlap
  
  @param image:   input image stack
  @param imgPara: input parameter
  @param name:    name of the output file
  @param arr:     image which should be plotted
  */
 void ShowArray(RasterizedImage & img, ParaSet & imgPara, char * name, Array * arr)
 {
   Dimn_Type x, y, z;
   Array    * a, * b;
 
   if (imgPara.grid == false){
     Write_Image((char *) name, arr, DONT_PRESS);
     return;
   }
 
   // Conversion of the image arr into an RGB-Kind image
   if (arr->type != UINT8_TYPE){
     b = Copy_Array(arr);
     Scale_Array_To_Range(b,ValU(0),ValU(255));
     Convert_Array_Inplace(b,b->kind,UINT8_TYPE,8,0);
   } else {
     b = arr;
   }
 
   if (b->kind != RGB_KIND){
     if (b == arr){
       a = Convert_Array(b,RGB_KIND,b->type,b->scale,0);
     } else {
       a = Convert_Array_Inplace(b,RGB_KIND,b->type,b->scale,0);
     }
   } else {
     a = b;
   }
 
   // Plotting of the image grid
   if (a->ndims == 4)
     for (z = 0; z < img.GetDepth(); z++){
       for (y = 0; y < img.GetGridY(); y++) {
         if (y % 50 == 0 && y != 0){
           Draw_Line(a,&YELLOW,Coord3(z,y*imgPara.radius,0),Coord3(z,y*imgPara.radius,img.GetGridX()*imgPara.radius-1));
         } else if (y % 10 == 0 && y != 0){
           Draw_Line(a,&PURPLE,Coord3(z,y*imgPara.radius,0),Coord3(z,y*imgPara.radius,img.GetGridX()*imgPara.radius-1));
         } else {
           Draw_Line(a,&CYAN,Coord3(z,y*imgPara.radius,0),Coord3(z,y*imgPara.radius,img.GetGridX()*imgPara.radius-1));
         }
         for (x = 0; x < img.GetGridX(); x++){
           if (x % 50 == 0 && x != 0){
             Draw_Line(a,&YELLOW,Coord3(z,0,x*imgPara.radius),Coord3(z,img.GetGridY()*imgPara.radius-1,x*imgPara.radius));
           } else if (x % 10 == 0 && x != 0){
             Draw_Line(a,&PURPLE,Coord3(z,0,x*imgPara.radius),Coord3(z,img.GetGridY()*imgPara.radius-1,x*imgPara.radius));
           } else {
             Draw_Line(a,&CYAN,Coord3(z,0,x*imgPara.radius),Coord3(z,img.GetGridY()*imgPara.radius-1,x*imgPara.radius));
           }
         }
       }
     }
   else{
     for (y = 0; y < img.GetGridY(); y++){
       if (y % 50 == 0 && y != 0){
         Draw_Line(a,&YELLOW,Coord2(y*imgPara.radius,0),Coord2(y*imgPara.radius,img.GetGridX()*imgPara.radius-1));
       } else if (y % 10 == 0 && y != 0){
         Draw_Line(a,&PURPLE,Coord2(y*imgPara.radius,0),Coord2(y*imgPara.radius,img.GetGridX()*imgPara.radius-1));
       } else{
         Draw_Line(a,&CYAN,Coord2(y*imgPara.radius,0),Coord2(y*imgPara.radius,img.GetGridX()*imgPara.radius-1));
       }
       for (x = 0; x < img.GetGridX(); x++){
         if (x % 50 == 0 && x != 0){
           Draw_Line(a,&YELLOW,Coord2(0,x*imgPara.radius),Coord2(img.GetGridY()*imgPara.radius-1,x*imgPara.radius));
         } else if (x % 10 == 0 && x != 0){
           Draw_Line(a,&PURPLE,Coord2(0,x*imgPara.radius),Coord2(img.GetGridY()*imgPara.radius-1,x*imgPara.radius));
         } else{
           Draw_Line(a,&CYAN,Coord2(0,x*imgPara.radius),Coord2(img.GetGridY()*imgPara.radius-1,x*imgPara.radius));
         }
       }
     }
   }
   
   Write_Image(name, a, DONT_PRESS);
   
   if (arr != a)
     Free_Array(a);
 }