예제 #1
0
 void showDialog() {
   int width = imp.getWidth();
   int height = imp.getHeight();
   Calibration cal = imp.getCalibration();
   int places;
   if (cal.scaled()) {
     pixelWidth = cal.pixelWidth;
     pixelHeight = cal.pixelHeight;
     units = cal.getUnits();
     places = 2;
   } else {
     pixelWidth = 1.0;
     pixelHeight = 1.0;
     units = "pixels";
     places = 0;
   }
   if (areaPerPoint == 0.0)
     areaPerPoint =
         (width * cal.pixelWidth * height * cal.pixelHeight) / 81.0; // default to 9x9 grid
   ImageWindow win = imp.getWindow();
   GenericDialog gd = new GenericDialog("Grid...");
   gd.addChoice("Grid Type:", types, type);
   gd.addNumericField("Area per Point:", areaPerPoint, places, 6, units + "^2");
   gd.addChoice("Color:", colors, color);
   gd.addCheckbox("Random Offset", randomOffset);
   gd.addDialogListener(this);
   gd.showDialog();
   if (gd.wasCanceled()) showGrid(null);
 }
예제 #2
0
  public boolean beadCalibration3d() {
    imp = IJ.getImage();
    if (imp == null) {
      IJ.noImage();
      return false;
    } else if (imp.getStackSize() == 1) {
      IJ.error("Stack required");
      return false;
    } else if (imp.getType() != ImagePlus.GRAY8 && imp.getType() != ImagePlus.GRAY16) {
      // In order to support 32bit images, pict[] must be changed to float[], and  getPixel(x, y);
      // requires a Float.intBitsToFloat() conversion
      IJ.error("8 or 16 bit greyscale image required");
      return false;
    }
    width = imp.getWidth();
    height = imp.getHeight();
    nslices = imp.getStackSize();
    imtitle = imp.getTitle();

    models[0] = "*None*";
    models[1] = "line";
    models[2] = "2nd degree polynomial";
    models[3] = "3rd degree polynomial";
    models[4] = "4th degree polynomial";

    GenericDialog gd = new GenericDialog("3D PALM calibration");
    gd.addNumericField("Maximum FWHM (in px)", prefs.get("QuickPALM.3Dcal_fwhm", 20), 0);
    gd.addNumericField(
        "Particle local threshold (% maximum intensity)", prefs.get("QuickPALM.pthrsh", 20), 0);
    gd.addNumericField("Z-spacing (nm)", prefs.get("QuickPALM.z-step", 10), 2);
    gd.addNumericField("Calibration Z-smoothing (radius)", prefs.get("QuickPALM.window", 1), 0);
    gd.addChoice("Model", models, prefs.get("QuickPALM.model", models[3]));
    gd.addCheckbox(
        "Show divergence of bead positions against model",
        prefs.get("QuickPALM.3Dcal_showDivergence", false));
    gd.addCheckbox("Show extra particle info", prefs.get("QuickPALM.3Dcal_showExtraInfo", false));
    gd.addMessage("\n\nDon't forget to save the table in the end...");
    gd.showDialog();
    if (gd.wasCanceled()) return false;
    fwhm = gd.getNextNumber();
    prefs.set("QuickPALM.QuickPALM.3Dcal_fwhm", fwhm);
    pthrsh = gd.getNextNumber() / 100;
    prefs.set("QuickPALM.pthrsh", pthrsh * 100);
    cal_z = gd.getNextNumber();
    prefs.set("QuickPALM.z-step", cal_z);
    window = (int) gd.getNextNumber();
    prefs.set("QuickPALM.window", window);
    model = gd.getNextChoice();
    prefs.set("QuickPALM.model", model);
    part_divergence = gd.getNextBoolean();
    prefs.set("QuickPALM.3Dcal_showDivergence", part_divergence);
    part_extrainfo = gd.getNextBoolean();
    prefs.set("QuickPALM.3Dcal_showExtraInfo", part_extrainfo);
    return true;
  }
예제 #3
0
  public void run(String arg) {
    int[] wList = WindowManager.getIDList();
    if (wList == null) {
      IJ.error("No images are open.");
      return;
    }

    double thalf = 0.5;
    boolean keep;

    GenericDialog gd = new GenericDialog("Bleach correction");

    gd.addNumericField("t½:", thalf, 1);
    gd.addCheckbox("Keep source stack:", true);
    gd.showDialog();
    if (gd.wasCanceled()) return;

    long start = System.currentTimeMillis();
    thalf = gd.getNextNumber();
    keep = gd.getNextBoolean();
    if (keep) IJ.run("Duplicate...", "title='Bleach corrected' duplicate");
    ImagePlus imp1 = WindowManager.getCurrentImage();
    int d1 = imp1.getStackSize();
    double v1, v2;
    int width = imp1.getWidth();
    int height = imp1.getHeight();
    ImageProcessor ip1, ip2, ip3;

    int slices = imp1.getStackSize();
    ImageStack stack1 = imp1.getStack();
    ImageStack stack2 = imp1.getStack();
    int currentSlice = imp1.getCurrentSlice();

    for (int n = 1; n <= slices; n++) {
      ip1 = stack1.getProcessor(n);
      ip3 = stack1.getProcessor(1);
      ip2 = stack2.getProcessor(n);
      for (int x = 0; x < width; x++) {
        for (int y = 0; y < height; y++) {
          v1 = ip1.getPixelValue(x, y);
          v2 = ip3.getPixelValue(x, y);

          // =B8/(EXP(-C$7*A8))
          v1 = (v1 / Math.exp(-n * thalf));
          ip2.putPixelValue(x, y, v1);
        }
      }
      IJ.showProgress((double) n / slices);
      IJ.showStatus(n + "/" + slices);
    }

    // stack2.show();
    imp1.updateAndDraw();
  }
예제 #4
0
 /**
  * Called by the PlugInFilterRunner after setup. Asks the user in case of a stack and prepares a
  * separate ouptut stack if required
  */
 public int showDialog(ImagePlus imp, String command, PlugInFilterRunner pfr) {
   this.pfr = pfr;
   int width = imp.getWidth();
   int height = imp.getHeight();
   // ask whether to process all slices of stack & prepare stack
   // (if required) for writing into it in parallel threads
   flags = IJ.setupDialog(imp, flags);
   if ((flags & DOES_STACKS) != 0 && outImageType != BYTE_OVERWRITE) {
     outStack = new ImageStack(width, height, imp.getStackSize());
     maxFinder.setNPasses(imp.getStackSize());
   }
   return flags;
 } // public int showDialog
예제 #5
0
 void drawLines() {
   GeneralPath path = new GeneralPath();
   int width = imp.getWidth();
   int height = imp.getHeight();
   for (int i = 0; i < linesV; i++) {
     float xoff = (float) (xstart + i * tileWidth);
     path.moveTo(xoff, 0f);
     path.lineTo(xoff, height);
   }
   for (int i = 0; i < linesH; i++) {
     float yoff = (float) (ystart + i * tileHeight);
     path.moveTo(0f, yoff);
     path.lineTo(width, yoff);
   }
   showGrid(path);
 }
예제 #6
0
  public boolean dialogItemChanged(GenericDialog gd, AWTEvent e) {
    int width = imp.getWidth();
    int height = imp.getHeight();
    type = gd.getNextChoice();
    areaPerPoint = gd.getNextNumber();
    color = gd.getNextChoice();
    randomOffset = gd.getNextBoolean();

    double minArea = (width * height) / 50000.0;
    if (type.equals(types[1]) && minArea < 144.0) minArea = 144.0;
    else if (minArea < 16) minArea = 16.0;
    if (areaPerPoint / (pixelWidth * pixelHeight) < minArea) {
      String err = "\"Area per Point\" too small";
      if (gd.wasOKed()) IJ.error("Grid", err);
      else IJ.showStatus(err);
      return true;
    }
    double tileSize = Math.sqrt(areaPerPoint);
    tileWidth = tileSize / pixelWidth;
    tileHeight = tileSize / pixelHeight;
    if (randomOffset) {
      xstart = (int) (random.nextDouble() * tileWidth);
      ystart = (int) (random.nextDouble() * tileHeight);
    } else {
      xstart = (int) (tileWidth / 2.0 + 0.5);
      ystart = (int) (tileHeight / 2.0 + 0.5);
    }
    linesV = (int) ((width - xstart) / tileWidth) + 1;
    linesH = (int) ((height - ystart) / tileHeight) + 1;
    if (gd.invalidNumber()) return true;
    if (type.equals(types[0])) drawLines();
    else if (type.equals(types[1])) drawCrosses();
    else if (type.equals(types[2])) drawPoints();
    else showGrid(null);
    return true;
  }
예제 #7
0
	public void run(String arg) {

  int[] wList = WindowManager.getIDList();
        if (wList==null) {
            IJ.error("No images are open.");
            return;
        }
	double kernel=3;
	double kernelsum = 0;
	double kernelvarsum =0;
	double kernalvar = 0;
	double sigmawidth = 2;
	int kernelindex, minpixnumber;
	String[] kernelsize =  { "3�,"5�, "7�, "9�};

	GenericDialog gd = new GenericDialog("Sigma Filter");
	gd.addChoice("Kernel size", kernelsize, kernelsize[0]);
	gd.addNumericField("Sigma width",sigmawidth , 2);
	gd.addNumericField("Minimum number of pixels", 1, 0);

	gd.addCheckbox("Keep source:",true);
	gd.addCheckbox("Do all stack:",true);
	gd.addCheckbox("Modified Lee's FIlter:",true);
	       	
	gd.showDialog();
       	if (gd.wasCanceled()) return ;
	kernelindex =  gd.getNextChoiceIndex();
          	sigmawidth = gd.getNextNumber();
          	minpixnumber = ((int)gd.getNextNumber());
          	boolean keep = gd.getNextBoolean();
	boolean doallstack = gd.getNextBoolean();
	boolean modified = gd.getNextBoolean();
	if (kernelindex==0) kernel = 3;
	if (kernelindex==1) kernel = 5;
	if (kernelindex==2) kernel = 7;
	if (kernelindex==3) kernel = 9;
    	long start = System.currentTimeMillis();
	
if (minpixnumber> (kernel*kernel)){
	      IJ.showMessage("Sigma filter", "There must be more pixels in the kernel than+\n" + "the minimum number to be included");
            return;
        }
	double v, midintensity;
	int   x, y, ix, iy;
	double sum = 0;
	double backupsum =0;
	int count = 0;
	int n = 0;
	if (keep) {IJ.run("Select All"); IJ.run("Duplicate...", "title='Sigma filtered' duplicate");}

	int radius = (int)(kernel-1)/2;
	ImagePlus imp = WindowManager.getCurrentImage();
	ImageStack stack1 = imp.getStack();
	int width = imp.getWidth();
	int height = imp.getHeight();
	int nslices = stack1.getSize();
	int cslice = imp.getCurrentSlice();
	double status = width*height*nslices;
	
	ImageProcessor  ip = imp.getProcessor();
	int sstart = 1;
	if (!doallstack) {sstart = cslice; nslices=sstart;status = status/nslices;};

 for (int i=sstart; i<=nslices; i++) {
                imp.setSlice(i);
                    
for (x=radius;x<width+radius;x++)	{
		for (y=radius;y<height+radius;y++)	{
			
			midintensity = ip.getPixelValue(x,y);
			count = 0;
			sum = 0;
			kernelsum =0;
			kernalvar =0;
			kernelvarsum =0;
			backupsum = 0;

		//calculate mean of kernel value
			for (ix=0;ix<kernel;ix++)	{
					for (iy=0;iy<kernel;iy++)	{
							v = ip.getPixelValue(x+ix-radius,y+iy-radius);
							kernelsum = kernelsum+v;
								}
						}
			double sigmacalcmean = (kernelsum/(kernel*kernel));

		//calculate variance of kernel
			for (ix=0;ix<kernel;ix++)	{
					for (iy=0;iy<kernel;iy++)	{
							v = ip.getPixelValue(x+ix-radius,y+iy-radius);
							kernalvar = (v-sigmacalcmean)*(v-sigmacalcmean);
							kernelvarsum = kernelvarsum + kernalvar;
								}
						}
			//double variance = kernelvarsum/kernel;
			double sigmacalcvar = kernelvarsum/((kernel*kernel)-1);

			//calcuate sigma range = sqrt(variance/(mean^2)) � sigmawidth
			double sigmarange  = sigmawidth*(Math.sqrt((sigmacalcvar) /(sigmacalcmean*sigmacalcmean)));
			//calulate sigma top value and bottom value
			double sigmatop = midintensity*(1+sigmarange);
			double sigmabottom = midintensity*(1-sigmarange);
			//calculate mean of values that differ are in sigma range.
			for (ix=0;ix<kernel;ix++)	{
					for (iy=0;iy<kernel;iy++)	{
							v = ip.getPixelValue(x+ix-radius,y+iy-radius);
							if ((v>=sigmabottom)&&(v<=sigmatop)){
								sum = sum+v;
								count = count+1;   }
								backupsum = v+ backupsum;
										}		
						}
//if there are too few pixels in the kernal that are within sigma range, the 
//mean of the entire kernal is taken. My modification of Lee's filter is to exclude the central value 
//from the calculation of the mean as I assume it to be spuriously high or low 
			if (!(count>(minpixnumber)))
				{sum = (backupsum-midintensity);
				count = (int)((kernel*kernel)-1);
				if (!modified)
					{sum = (backupsum);
					count  = (int)(kernel*kernel);}
				}
			
			double val =  (sum/count);
			ip.putPixelValue(x,y, val);
			n = n+1;
	double percentage = (((double)n/status)*100);
			 IJ.showStatus(IJ.d2s(percentage,0) +"% done");		
			
}

	//		IJ.showProgress(i, status);
					}}
			imp.updateAndDraw();
 			IJ.showStatus(IJ.d2s((System.currentTimeMillis()-start)/1000.0, 2)+" seconds");        }      
예제 #8
0
  void Otsu(ImagePlus imp, int radius, double par1, double par2, boolean doIwhite) {
    // Otsu's threshold algorithm
    // C++ code by Jordan Bevik <*****@*****.**>
    // ported to ImageJ plugin by G.Landini. Same algorithm as in Auto_Threshold, this time on local
    // circular regions
    int[] data;
    int w = imp.getWidth();
    int h = imp.getHeight();
    int position;
    int radiusx2 = radius * 2;
    ImageProcessor ip = imp.getProcessor();
    byte[] pixels = (byte[]) ip.getPixels();
    byte[] pixelsOut =
        new byte
            [pixels.length]; // need this to avoid changing the image data (and further histograms)
    byte object;
    byte backg;

    if (doIwhite) {
      object = (byte) 0xff;
      backg = (byte) 0;
    } else {
      object = (byte) 0;
      backg = (byte) 0xff;
    }

    int k, kStar; // k = the current threshold; kStar = optimal threshold
    int N1, N; // N1 = # points with intensity <=k; N = total number of points
    double BCV, BCVmax; // The current Between Class Variance and maximum BCV
    double num, denom; // temporary bookeeping
    int Sk; // The total intensity for all histogram points <=k
    int S,
        L =
            256; // The total intensity of the image. Need to hange here if modifying for >8 bits
                 // images
    int roiy;

    Roi roi = new OvalRoi(0, 0, radiusx2, radiusx2);
    // ip.setRoi(roi);
    for (int y = 0; y < h; y++) {
      IJ.showProgress(
          (double) (y) / (h - 1)); // this method is slow, so let's show the progress bar
      roiy = y - radius;
      for (int x = 0; x < w; x++) {
        roi.setLocation(x - radius, roiy);
        ip.setRoi(roi);
        // ip.setRoi(new OvalRoi(x-radius, roiy, radiusx2, radiusx2));
        position = x + y * w;
        data = ip.getHistogram();

        // Initialize values:
        S = N = 0;
        for (k = 0; k < L; k++) {
          S += k * data[k]; // Total histogram intensity
          N += data[k]; // Total number of data points
        }

        Sk = 0;
        N1 = data[0]; // The entry for zero intensity
        BCV = 0;
        BCVmax = 0;
        kStar = 0;

        // Look at each possible threshold value,
        // calculate the between-class variance, and decide if it's a max
        for (k = 1; k < L - 1; k++) { // No need to check endpoints k = 0 or k = L-1
          Sk += k * data[k];
          N1 += data[k];

          // The float casting here is to avoid compiler warning about loss of precision and
          // will prevent overflow in the case of large saturated images
          denom = (double) (N1) * (N - N1); // Maximum value of denom is (N^2)/4 =  approx. 3E10

          if (denom != 0) {
            // Float here is to avoid loss of precision when dividing
            num = ((double) N1 / N) * S - Sk; // Maximum value of num =  255*N = approx 8E7
            BCV = (num * num) / denom;
          } else BCV = 0;

          if (BCV >= BCVmax) { // Assign the best threshold found so far
            BCVmax = BCV;
            kStar = k;
          }
        }
        // kStar += 1;	// Use QTI convention that intensity -> 1 if intensity >= k
        // (the algorithm was developed for I-> 1 if I <= k.)
        // return kStar;
        pixelsOut[position] = ((int) (pixels[position] & 0xff) > kStar) ? object : backg;
      }
    }
    for (position = 0; position < w * h; position++)
      pixels[position] = pixelsOut[position]; // update with thresholded pixels
  }
예제 #9
0
  public void Calc_5Fr(ImagePlus imp1, ImagePlus imp2) {
    if (imp1.getType() != imp2.getType()) {
      error();
      return;
    }
    if (imp1.getType() == 0) { // getType returns 0 for 8-bit, 1 for 16-bit
      bitDepth = "8-bit";
      Prefs.set("ps.bitDepth", bitDepth);
    } else {
      bitDepth = "16-bit";
      Prefs.set("ps.bitDepth", bitDepth);
    }
    int width = imp1.getWidth();
    int height = imp1.getHeight();
    if (width != imp2.getWidth() || height != imp2.getHeight()) {
      error();
      return;
    }

    ImageStack stack1 = imp1.getStack();
    //		if (bgStackTitle != "NoBg") ImageStack stack2 = imp2.getStack();
    ImageStack stack2 = imp2.getStack();

    ImageProcessor ip = imp1.getProcessor();
    int dimension = width * height;
    byte[] pixB;
    short[] pixS;
    float[][] pixF = new float[5][dimension];
    float[][] pixFBg = new float[5][dimension];

    float a;
    float b;
    float den;
    float aSmp;
    float bSmp;
    float denSmp;
    float aBg;
    float bBg;
    float denBg;
    float retF;
    float azimF;

    byte[] retB = new byte[dimension];
    short[] retS = new short[dimension];
    byte[] azimB = new byte[dimension];
    short[] azimS = new short[dimension];
    // Derived Variables:
    float swingAngle = 2f * (float) Math.PI * swing;
    float tanSwingAngleDiv2 = (float) Math.tan(swingAngle / 2.f);
    float tanSwingAngleDiv2DivSqrt2 = (float) (Math.tan(swingAngle / 2.f) / Math.sqrt(2));
    float wavelengthDiv2Pi = wavelength / (2f * (float) Math.PI);

    // get the pixels of each slice in the stack and convert to float
    for (int i = 0; i < 5; i++) {
      if (bitDepth == "8-bit") {
        pixB = (byte[]) stack1.getPixels(i + 3);
        for (int j = 0; j < dimension; j++) pixF[i][j] = 0xff & pixB[j];
        if (bgStackTitle != "NoBg") {
          pixB = (byte[]) stack2.getPixels(i + 3);
          for (int j = 0; j < dimension; j++) pixFBg[i][j] = 0xff & pixB[j];
        }
      } else {
        pixS = (short[]) stack1.getPixels(i + 3);
        for (int j = 0; j < dimension; j++) pixF[i][j] = (float) pixS[j];
        if (bgStackTitle != "NoBg") {
          pixS = (short[]) stack2.getPixels(i + 3);
          for (int j = 0; j < dimension; j++) pixFBg[i][j] = (float) pixS[j];
        }
      }
    }

    // Algorithm
    // terms a and b
    for (int j = 0; j < dimension; j++) {
      denSmp = (pixF[1][j] + pixF[2][j] + pixF[3][j] + pixF[4][j] - 4 * pixF[0][j]) / 2;
      denBg = denSmp;
      a = (pixF[4][j] - pixF[1][j]);
      aSmp = a;
      aBg = a;
      b = (pixF[2][j] - pixF[3][j]);
      bSmp = b;
      bBg = b;
      if (bgStackTitle != "NoBg") {
        denBg = (pixFBg[1][j] + pixFBg[2][j] + pixFBg[3][j] + pixFBg[4][j] - 4 * pixFBg[0][j]) / 2;
        aBg = pixFBg[4][j] - pixFBg[1][j];
        bBg = pixFBg[2][j] - pixFBg[3][j];
      }
      // Special case of sample retardance half wave, denSmp = 0
      if (denSmp == 0) {
        retF = (float) wavelength / 4;
        azimF =
            (float) (a == 0 & b == 0 ? 0 : (azimRef + 90 + 90 * Math.atan2(a, b) / Math.PI) % 180);
      } else {
        // Retardance, the background correction can be improved by separately considering sample
        // retardance values larger than a quarter wave
        if (bgStackTitle != "NoBg") {
          a = aSmp / denSmp - aBg / denBg;
          b = bSmp / denSmp - bBg / denBg;
        } else {
          a = aSmp / denSmp;
          b = bSmp / denSmp;
        }
        retF = (float) Math.atan(tanSwingAngleDiv2 * Math.sqrt(a * a + b * b));
        if (denSmp < 0) retF = (float) Math.PI - retF;
        retF = retF * wavelengthDiv2Pi; // convert to nm
        if (retF > retCeiling) retF = retCeiling;

        // Orientation
        if ((bgStackTitle == "NoBg") || ((bgStackTitle != "NoBg") && (Math.abs(denSmp) < 1))) {
          a = aSmp;
          b = bSmp;
        }
        azimF =
            (float) (a == 0 & b == 0 ? 0 : (azimRef + 90 + 90 * Math.atan2(a, b) / Math.PI) % 180);
      }
      if (bitDepth == "8-bit") retB[j] = (byte) (((int) (255 * retF / retCeiling)) & 0xff);
      else retS[j] = (short) (4095 * retF / retCeiling);
      if (mirror == "Yes") azimF = 180 - azimF;
      if (bitDepth == "8-bit") azimB[j] = (byte) (((int) azimF) & 0xff);
      else azimS[j] = (short) (azimF * 10f);
    }
    // show the resulting images in slice 1 and 2
    imp1.setSlice(3);
    if (bitDepth == "8-bit") {
      stack1.setPixels(retB, 1);
      stack1.setPixels(azimB, 2);
    } else {
      stack1.setPixels(retS, 1);
      stack1.setPixels(azimS, 2);
    }
    imp1.setSlice(1);
    IJ.selectWindow(imp1.getTitle());

    Prefs.set("ps.sampleStackTitle", sampleStackTitle);
    Prefs.set("ps.bgStackTitle", bgStackTitle);
    Prefs.set("ps.mirror", mirror);
    Prefs.set("ps.wavelength", wavelength);
    Prefs.set("ps.swing", swing);
    Prefs.set("ps.retCeiling", retCeiling);
    Prefs.set("ps.azimRef", azimRef);
    Prefs.savePreferences();
  }
예제 #10
0
  public void run(String arg) {
    ImagePlus imp = WindowManager.getCurrentImage();
    Calibration cal = imp.getCalibration();
    GenericDialog gd = new GenericDialog("Options");
    int subsize = 32;
    gd.addNumericField("Subregion Size (pixels)?", subsize, 0);
    int stepsize = 16;
    gd.addNumericField("Step Size?", stepsize, 0);
    int shift = 3;
    gd.addNumericField("STICS temporal Shift?", shift, 0);
    float xoffset = 0.0f;
    gd.addNumericField("X_Offset", xoffset, 5, 15, null);
    float yoffset = 0.0f;
    gd.addNumericField("Y_Offset", yoffset, 5, 15, null);
    float multiplier = 8.0f;
    gd.addNumericField("Velocity Multiplier", multiplier, 5, 15, null);
    float ftime = 1.0f;
    gd.addNumericField("Frame_Time(min)", ftime, 5, 15, null);
    float scaling = (float) cal.pixelWidth;
    gd.addNumericField("Pixel_Size(um)", scaling, 5, 15, null);
    boolean norm = true;
    gd.addCheckbox("Normalize_Vector_lengths?", norm);
    boolean centered = true;
    gd.addCheckbox("Center_Vectors?", centered);
    float magthresh = 0.0f;
    gd.addNumericField("Magnitude_Threshhold?", magthresh, 5, 15, null);
    int rlength = 10;
    gd.addNumericField("Running_avg_length", rlength, 0);
    int inc = 5;
    gd.addNumericField("Start_frame_increment", inc, 0);
    gd.showDialog();
    if (gd.wasCanceled()) {
      return;
    }
    subsize = (int) gd.getNextNumber();
    stepsize = (int) gd.getNextNumber();
    shift = (int) gd.getNextNumber();
    xoffset = (float) gd.getNextNumber();
    yoffset = (float) gd.getNextNumber();
    multiplier = (float) gd.getNextNumber();
    ftime = (float) gd.getNextNumber();
    scaling = (float) gd.getNextNumber();
    norm = gd.getNextBoolean();
    centered = gd.getNextBoolean();
    magthresh = (float) gd.getNextNumber();
    rlength = (int) gd.getNextNumber();
    inc = (int) gd.getNextNumber();

    int width = imp.getWidth();
    int xregions = 1 + (int) (((float) width - (float) subsize) / (float) stepsize);
    int newwidth = xregions * subsize;
    int height = imp.getHeight();
    int yregions = 1 + (int) (((float) height - (float) subsize) / (float) stepsize);
    int newheight = yregions * subsize;
    ImageStack stack = imp.getStack();
    int slices = imp.getNSlices();
    int channels = imp.getNChannels();
    int frames = imp.getNFrames();
    if (frames == 1) {
      frames = slices;
      slices = 1;
    }

    Roi roi = imp.getRoi();
    if (roi == null) {
      roi = new Roi(0, 0, width, height);
    }

    STICS_map map = new STICS_map(subsize, stepsize);
    Object[] tseries = jutils.get3DTSeries(stack, 0, 0, frames, slices, channels);
    map.update_STICS_map(tseries, width, height, 0, rlength, roi.getPolygon(), shift);
    FloatProcessor fp =
        map.get_map(scaling, ftime, stepsize, centered, norm, multiplier, stepsize, magthresh);
    ImageStack vector_stack = new ImageStack(fp.getWidth(), fp.getHeight());
    vector_stack.addSlice("", fp);
    float[][] vel = map.get_scaled_velocities(scaling, ftime, stepsize);
    ImageStack velstack = new ImageStack(map.xregions, map.yregions);
    velstack.addSlice("", vel[0]);
    velstack.addSlice("", vel[1]);
    int velframes = 2;
    IJ.showStatus("frame " + 0 + " calculated");
    for (int i = inc; i < (frames - rlength); i += inc) {
      map.update_STICS_map(tseries, width, height, i, rlength, roi.getPolygon(), shift);
      FloatProcessor fp2 =
          map.get_map(scaling, ftime, stepsize, centered, norm, multiplier, stepsize, magthresh);
      vector_stack.addSlice("", fp2);
      vel = map.get_scaled_velocities(scaling, ftime, stepsize);
      velstack.addSlice("", vel[0]);
      velstack.addSlice("", vel[1]);
      velframes += 2;
      IJ.showStatus("frame " + i + " calculated");
    }
    (new ImagePlus("STICS Vectors", vector_stack)).show();
    ImagePlus imp3 = new ImagePlus("Velocities", velstack);
    imp3.setOpenAsHyperStack(true);
    imp3.setDimensions(2, 1, velframes / 2);
    new CompositeImage(imp3, CompositeImage.COLOR).show();
  }