예제 #1
0
 /** Frees memory by deleting a few slices from the end of the stack. */
 public void trim() {
   int n = (int) Math.round(Math.log(nSlices) + 1.0);
   for (int i = 0; i < n; i++) {
     deleteLastSlice();
     System.gc();
   }
 }
예제 #2
0
 void createEllipse(ImagePlus imp) {
   IJ.showStatus("Fitting ellipse");
   Roi roi = imp.getRoi();
   if (roi == null) {
     noRoi("Fit Ellipse");
     return;
   }
   if (roi.isLine()) {
     IJ.error("Fit Ellipse", "\"Fit Ellipse\" does not work with line selections");
     return;
   }
   ImageProcessor ip = imp.getProcessor();
   ip.setRoi(roi);
   int options = Measurements.CENTROID + Measurements.ELLIPSE;
   ImageStatistics stats = ImageStatistics.getStatistics(ip, options, null);
   double dx = stats.major * Math.cos(stats.angle / 180.0 * Math.PI) / 2.0;
   double dy = -stats.major * Math.sin(stats.angle / 180.0 * Math.PI) / 2.0;
   double x1 = stats.xCentroid - dx;
   double x2 = stats.xCentroid + dx;
   double y1 = stats.yCentroid - dy;
   double y2 = stats.yCentroid + dy;
   double aspectRatio = stats.minor / stats.major;
   imp.killRoi();
   imp.setRoi(new EllipseRoi(x1, y1, x2, y2, aspectRatio));
 }
예제 #3
0
  public void fitSpline(int evaluationPoints) {
    if (xpf == null) {
      xpf = toFloat(xp);
      ypf = toFloat(yp);
      subPixel = true;
    }
    if (xSpline == null || splinePoints != evaluationPoints) {
      splinePoints = evaluationPoints;
      xSpline = new float[splinePoints];
      ySpline = new float[splinePoints];
    }
    int nNodes = nPoints;
    if (type == POLYGON) {
      nNodes++;
      if (nNodes >= xpf.length) enlargeArrays();
      xpf[nNodes - 1] = xpf[0];
      ypf[nNodes - 1] = ypf[0];
    }
    float[] xindex = new float[nNodes];
    for (int i = 0; i < nNodes; i++) xindex[i] = i;
    SplineFitter sfx = new SplineFitter(xindex, xpf, nNodes);
    SplineFitter sfy = new SplineFitter(xindex, ypf, nNodes);

    // Evaluate the splines at all points
    double scale = (double) (nNodes - 1) / (splinePoints - 1);
    float xs = 0f, ys = 0f;
    float xmin = Float.MAX_VALUE, xmax = -xmin, ymin = xmin, ymax = xmax;
    for (int i = 0; i < splinePoints; i++) {
      double xvalue = i * scale;
      xs = (float) sfx.evalSpline(xindex, xpf, nNodes, xvalue);
      if (xs < xmin) xmin = xs;
      if (xs > xmax) xmax = xs;
      xSpline[i] = xs;
      ys = (float) sfy.evalSpline(xindex, ypf, nNodes, xvalue);
      if (ys < ymin) ymin = ys;
      if (ys > ymax) ymax = ys;
      ySpline[i] = ys;
    }
    int ixmin = (int) Math.floor(xmin + 0.5f);
    int ixmax = (int) Math.floor(xmax + 0.5f);
    int iymin = (int) Math.floor(ymin + 0.5f);
    int iymax = (int) Math.floor(ymax + 0.5f);
    if (ixmin != 0) {
      for (int i = 0; i < nPoints; i++) xpf[i] -= ixmin;
      for (int i = 0; i < splinePoints; i++) xSpline[i] -= ixmin;
    }
    if (iymin != 0) {
      for (int i = 0; i < nPoints; i++) ypf[i] -= iymin;
      for (int i = 0; i < splinePoints; i++) ySpline[i] -= iymin;
    }
    x += ixmin;
    y += iymin;
    width = ixmax - ixmin;
    height = iymax - iymin;
    bounds = null;
    cachedMask = null;
    // update protected xp and yp arrays for backward compatibility
    xp = toInt(xpf, xp, nPoints);
    yp = toInt(ypf, yp, nPoints);
  }
예제 #4
0
 private void getintbright() {
   weights = new float[ncurves][xpts][ypts];
   for (int i = 0; i < ncurves; i++) {
     nmeas[i] = 0;
     for (int j = 0; j < xpts; j++) {
       for (int k = 0; k < ypts; k++) {
         nmeas[i] += (int) pch[i][j][k];
       }
     }
     double tempavg = 0.0;
     double tempavg2 = 0.0;
     double temp2avg = 0.0;
     double temp2avg2 = 0.0;
     double tempccavg = 0.0;
     for (int j = 0; j < xpts; j++) {
       for (int k = 0; k < ypts; k++) {
         double normed = (double) pch[i][j][k] / (double) nmeas[i];
         if (pch[i][j][k] > 0.0f) {
           weights[i][j][k] = (float) ((double) nmeas[i] / (normed * (1.0f - normed)));
         } else {
           weights[i][j][k] = 1.0f;
         }
         tempavg += normed * (double) j;
         tempavg2 += normed * (double) j * (double) j;
         temp2avg += normed * (double) k;
         temp2avg2 += normed * (double) k * (double) k;
         tempccavg += normed * (double) k * (double) j;
       }
     }
     tempccavg -= tempavg * temp2avg;
     brightcc[i] = tempccavg / Math.sqrt(tempavg * temp2avg);
     tempavg2 -= tempavg * tempavg;
     tempavg2 /= tempavg;
     bright1[i] = (tempavg2 - 1.0);
     temp2avg2 -= temp2avg * temp2avg;
     temp2avg2 /= temp2avg;
     bright2[i] = (temp2avg2 - 1.0);
     intensity1[i] = tempavg;
     intensity2[i] = temp2avg;
     if (psfflag == 0) {
       bright1[i] /= 0.3536;
       bright2[i] /= 0.3536;
       brightcc[i] /= 0.3536;
     } else {
       if (psfflag == 1) {
         bright1[i] /= 0.078;
         bright2[i] /= 0.078;
         brightcc[i] /= 0.078;
       } else {
         bright1[i] /= 0.5;
         bright2[i] /= 0.5;
         brightcc[i] /= 0.5;
       }
     }
     number1[i] = intensity1[i] / bright1[i];
     number2[i] = intensity2[i] / bright2[i];
     brightmincc[i] = (bright1[i] * beta) * Math.sqrt(intensity1[i] / intensity2[i]);
   }
 }
예제 #5
0
 /**
  * Zooms out by making the source rectangle (srcRect) larger and centering it on (x,y). If we
  * can't make it larger, then make the window smaller.
  */
 public void zoomOut(int x, int y) {
   if (magnification <= 0.03125) return;
   double oldMag = magnification;
   double newMag = getLowerZoomLevel(magnification);
   double srcRatio = (double) srcRect.width / srcRect.height;
   double imageRatio = (double) imageWidth / imageHeight;
   double initialMag = imp.getWindow().getInitialMagnification();
   if (Math.abs(srcRatio - imageRatio) > 0.05) {
     double scale = oldMag / newMag;
     int newSrcWidth = (int) Math.round(srcRect.width * scale);
     int newSrcHeight = (int) Math.round(srcRect.height * scale);
     if (newSrcWidth > imageWidth) newSrcWidth = imageWidth;
     if (newSrcHeight > imageHeight) newSrcHeight = imageHeight;
     int newSrcX = srcRect.x - (newSrcWidth - srcRect.width) / 2;
     int newSrcY = srcRect.y - (newSrcHeight - srcRect.height) / 2;
     if (newSrcX < 0) newSrcX = 0;
     if (newSrcY < 0) newSrcY = 0;
     srcRect = new Rectangle(newSrcX, newSrcY, newSrcWidth, newSrcHeight);
     // IJ.log(newMag+" "+srcRect+" "+dstWidth+" "+dstHeight);
     int newDstWidth = (int) (srcRect.width * newMag);
     int newDstHeight = (int) (srcRect.height * newMag);
     setMagnification(newMag);
     setMaxBounds();
     // IJ.log(newDstWidth+" "+dstWidth+" "+newDstHeight+" "+dstHeight);
     if (newDstWidth < dstWidth || newDstHeight < dstHeight) {
       // IJ.log("pack");
       setDrawingSize(newDstWidth, newDstHeight);
       imp.getWindow().pack();
     } else repaint();
     return;
   }
   if (imageWidth * newMag > dstWidth) {
     int w = (int) Math.round(dstWidth / newMag);
     if (w * newMag < dstWidth) w++;
     int h = (int) Math.round(dstHeight / newMag);
     if (h * newMag < dstHeight) h++;
     x = offScreenX(x);
     y = offScreenY(y);
     Rectangle r = new Rectangle(x - w / 2, y - h / 2, w, h);
     if (r.x < 0) r.x = 0;
     if (r.y < 0) r.y = 0;
     if (r.x + w > imageWidth) r.x = imageWidth - w;
     if (r.y + h > imageHeight) r.y = imageHeight - h;
     srcRect = r;
   } else {
     srcRect = new Rectangle(0, 0, imageWidth, imageHeight);
     setDrawingSize((int) (imageWidth * newMag), (int) (imageHeight * newMag));
     // setDrawingSize(dstWidth/2, dstHeight/2);
     imp.getWindow().pack();
   }
   // IJ.write(newMag + " " + srcRect.x+" "+srcRect.y+" "+srcRect.width+" "+srcRect.height+"
   // "+dstWidth + " " + dstHeight);
   setMagnification(newMag);
   // IJ.write(srcRect.x + " " + srcRect.width + " " + dstWidth);
   setMaxBounds();
   repaint();
 }
예제 #6
0
 double rodbard(double x) {
   // y = c*((a-x/(x-d))^(1/b)
   // a=3.9, b=.88, c=712, d=44
   double ex;
   if (x == 0.0) ex = 5.0;
   else ex = Math.exp(Math.log(x / 700.0) * 0.88);
   double y = 3.9 - 44.0;
   y = y / (1.0 + ex);
   return y + 44.0;
 }
예제 #7
0
 /* Creates a spline fitted polygon with one pixel segment lengths
 that can be retrieved using the getFloatPolygon() method. */
 public void fitSplineForStraightening() {
   fitSpline((int) getUncalibratedLength() * 2);
   if (splinePoints == 0) return;
   float[] xpoints = new float[splinePoints * 2];
   float[] ypoints = new float[splinePoints * 2];
   xpoints[0] = xSpline[0];
   ypoints[0] = ySpline[0];
   int n = 1, n2;
   double inc = 0.01;
   double distance = 0.0, distance2 = 0.0, dx = 0.0, dy = 0.0, xinc, yinc;
   double x, y, lastx, lasty, x1, y1, x2 = xSpline[0], y2 = ySpline[0];
   for (int i = 1; i < splinePoints; i++) {
     x1 = x2;
     y1 = y2;
     x = x1;
     y = y1;
     x2 = xSpline[i];
     y2 = ySpline[i];
     dx = x2 - x1;
     dy = y2 - y1;
     distance = Math.sqrt(dx * dx + dy * dy);
     xinc = dx * inc / distance;
     yinc = dy * inc / distance;
     lastx = xpoints[n - 1];
     lasty = ypoints[n - 1];
     // n2 = (int)(dx/xinc);
     n2 = (int) (distance / inc);
     if (splinePoints == 2) n2++;
     do {
       dx = x - lastx;
       dy = y - lasty;
       distance2 = Math.sqrt(dx * dx + dy * dy);
       // IJ.log(i+"   "+IJ.d2s(xinc,5)+"   "+IJ.d2s(yinc,5)+"   "+IJ.d2s(distance,2)+"
       // "+IJ.d2s(distance2,2)+"   "+IJ.d2s(x,2)+"   "+IJ.d2s(y,2)+"   "+IJ.d2s(lastx,2)+"
       // "+IJ.d2s(lasty,2)+"   "+n+"   "+n2);
       if (distance2 >= 1.0 - inc / 2.0 && n < xpoints.length - 1) {
         xpoints[n] = (float) x;
         ypoints[n] = (float) y;
         // IJ.log("--- "+IJ.d2s(x,2)+"   "+IJ.d2s(y,2)+"  "+n);
         n++;
         lastx = x;
         lasty = y;
       }
       x += xinc;
       y += yinc;
     } while (--n2 > 0);
   }
   xSpline = xpoints;
   ySpline = ypoints;
   splinePoints = n;
 }
예제 #8
0
 String getAngleAsString() {
   double angle1 = 0.0;
   double angle2 = 0.0;
   if (xpf != null) {
     angle1 = getFloatAngle(xpf[0], ypf[0], xpf[1], ypf[1]);
     angle2 = getFloatAngle(xpf[1], ypf[1], xpf[2], ypf[2]);
   } else {
     angle1 = getFloatAngle(xp[0], yp[0], xp[1], yp[1]);
     angle2 = getFloatAngle(xp[1], yp[1], xp[2], yp[2]);
   }
   degrees = Math.abs(180 - Math.abs(angle1 - angle2));
   if (degrees > 180.0) degrees = 360.0 - degrees;
   double degrees2 = Prefs.reflexAngle && type == ANGLE ? 360.0 - degrees : degrees;
   return ", angle=" + IJ.d2s(degrees2);
 }
예제 #9
0
 void drawRoiLabel(Graphics g, int index, Roi roi) {
   Rectangle r = roi.getBounds();
   int x = screenX(r.x);
   int y = screenY(r.y);
   double mag = getMagnification();
   int width = (int) (r.width * mag);
   int height = (int) (r.height * mag);
   int size = width > 40 && height > 40 ? 12 : 9;
   if (font != null) {
     g.setFont(font);
     size = font.getSize();
   } else if (size == 12) g.setFont(largeFont);
   else g.setFont(smallFont);
   boolean drawingList = index >= LIST_OFFSET;
   if (drawingList) index -= LIST_OFFSET;
   String label = "" + (index + 1);
   if (drawNames && roi.getName() != null) label = roi.getName();
   FontMetrics metrics = g.getFontMetrics();
   int w = metrics.stringWidth(label);
   x = x + width / 2 - w / 2;
   y = y + height / 2 + Math.max(size / 2, 6);
   int h = metrics.getAscent() + metrics.getDescent();
   if (bgColor != null) {
     g.setColor(bgColor);
     g.fillRoundRect(x - 1, y - h + 2, w + 1, h - 3, 5, 5);
   }
   if (!drawingList && labelRects != null && index < labelRects.length)
     labelRects[index] = new Rectangle(x - 1, y - h + 2, w + 1, h);
   g.setColor(labelColor);
   g.drawString(label, x, y - 2);
   g.setColor(defaultColor);
 }
예제 #10
0
  void Contrast(ImagePlus imp, int radius, double par1, double par2, boolean doIwhite) {
    // G. Landini, 2013
    // Based on a simple contrast toggle. This procedure does not have user-provided paramters other
    // than the kernel radius
    // Sets the pixel value to either white or black depending on whether its current value is
    // closest to the local Max or Min respectively
    // The procedure is similar to Toggle Contrast Enhancement (see Soille, Morphological Image
    // Analysis (2004), p. 259

    ImagePlus Maximp, Minimp;
    ImageProcessor ip = imp.getProcessor(), ipMax, ipMin;
    int c_value = 0;
    int mid_gray;
    byte object;
    byte backg;

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

    Maximp = duplicateImage(ip);
    ipMax = Maximp.getProcessor();
    RankFilters rf = new RankFilters();
    rf.rank(ipMax, radius, rf.MAX); // Maximum
    // Maximp.show();
    Minimp = duplicateImage(ip);
    ipMin = Minimp.getProcessor();
    rf.rank(ipMin, radius, rf.MIN); // Minimum
    // Minimp.show();
    byte[] pixels = (byte[]) ip.getPixels();
    byte[] max = (byte[]) ipMax.getPixels();
    byte[] min = (byte[]) ipMin.getPixels();
    for (int i = 0; i < pixels.length; i++) {
      pixels[i] =
          ((Math.abs((int) (max[i] & 0xff - pixels[i] & 0xff))
                  <= Math.abs((int) (pixels[i] & 0xff - min[i] & 0xff))))
              ? object
              : backg;
    }
    // imp.updateAndDraw();
    return;
  }
예제 #11
0
 void adjustSourceRect(double newMag, int x, int y) {
   // IJ.log("adjustSourceRect1: "+newMag+" "+dstWidth+"  "+dstHeight);
   int w = (int) Math.round(dstWidth / newMag);
   if (w * newMag < dstWidth) w++;
   int h = (int) Math.round(dstHeight / newMag);
   if (h * newMag < dstHeight) h++;
   x = offScreenX(x);
   y = offScreenY(y);
   Rectangle r = new Rectangle(x - w / 2, y - h / 2, w, h);
   if (r.x < 0) r.x = 0;
   if (r.y < 0) r.y = 0;
   if (r.x + w > imageWidth) r.x = imageWidth - w;
   if (r.y + h > imageHeight) r.y = imageHeight - h;
   srcRect = r;
   setMagnification(newMag);
   // IJ.log("adjustSourceRect2: "+srcRect+" "+dstWidth+"  "+dstHeight);
 }
예제 #12
0
 int[] smooth(int[] a, int n) {
   FloatProcessor fp = new FloatProcessor(n, 1);
   for (int i = 0; i < n; i++) fp.putPixelValue(i, 0, a[i]);
   GaussianBlur gb = new GaussianBlur();
   gb.blur1Direction(fp, 2.0, 0.01, true, 0);
   for (int i = 0; i < n; i++) a[i] = (int) Math.round(fp.getPixelValue(i, 0));
   return a;
 }
예제 #13
0
  /*------------------------------------------------------------------*/
  double getInitialCausalCoefficientMirrorOnBounds(double[] c, double z, double tolerance) {
    double z1 = z, zn = Math.pow(z, c.length - 1);
    double sum = c[0] + zn * c[c.length - 1];
    int horizon = c.length;

    if (0.0 < tolerance) {
      horizon = 2 + (int) (Math.log(tolerance) / Math.log(Math.abs(z)));
      horizon = (horizon < c.length) ? (horizon) : (c.length);
    }
    zn = zn * zn;
    for (int n = 1; (n < (horizon - 1)); n++) {
      zn = zn / z;
      sum = sum + (z1 + zn) * c[n];
      z1 = z1 * z;
    }
    return (sum / (1.0 - Math.pow(z, 2 * c.length - 2)));
  } /* end getInitialCausalCoefficientMirrorOnBounds */
예제 #14
0
 /**
  * Returns the perimeter length of ROIs created using the wand tool and the particle analyzer. The
  * algorithm counts edge pixels as 1 and corner pixels as sqrt(2). It does this by calculating the
  * total length of the ROI boundary and subtracting 2-sqrt(2) for each non-adjacent corner. For
  * example, a 1x1 pixel ROI has a boundary length of 4 and 2 non-adjacent edges so the perimeter
  * is 4-2*(2-sqrt(2)). A 2x2 pixel ROI has a boundary length of 8 and 4 non-adjacent edges so the
  * perimeter is 8-4*(2-sqrt(2)).
  */
 double getTracedPerimeter() {
   int sumdx = 0;
   int sumdy = 0;
   int nCorners = 0;
   int dx1 = xp[0] - xp[nPoints - 1];
   int dy1 = yp[0] - yp[nPoints - 1];
   int side1 = Math.abs(dx1) + Math.abs(dy1); // one of these is 0
   boolean corner = false;
   int nexti, dx2, dy2, side2;
   for (int i = 0; i < nPoints; i++) {
     nexti = i + 1;
     if (nexti == nPoints) nexti = 0;
     dx2 = xp[nexti] - xp[i];
     dy2 = yp[nexti] - yp[i];
     sumdx += Math.abs(dx1);
     sumdy += Math.abs(dy1);
     side2 = Math.abs(dx2) + Math.abs(dy2);
     if (side1 > 1 || !corner) {
       corner = true;
       nCorners++;
     } else corner = false;
     dx1 = dx2;
     dy1 = dy2;
     side1 = side2;
   }
   double w = 1.0, h = 1.0;
   if (imp != null) {
     Calibration cal = imp.getCalibration();
     w = cal.pixelWidth;
     h = cal.pixelHeight;
   }
   return sumdx * w + sumdy * h - (nCorners * ((w + h) - Math.sqrt(w * w + h * h)));
 }
예제 #15
0
 /** Draws an outline of this OvalRoi on the image. */
 public void drawPixels(ImageProcessor ip) {
   Polygon p = getPolygon();
   if (p.npoints > 0) {
     int saveWidth = ip.getLineWidth();
     if (getStrokeWidth() > 1f) ip.setLineWidth((int) Math.round(getStrokeWidth()));
     ip.drawPolygon(p);
     ip.setLineWidth(saveWidth);
   }
   if (Line.getWidth() > 1 || getStrokeWidth() > 1) updateFullWindow = true;
 }
예제 #16
0
 PolygonRoi trimPolygon(PolygonRoi roi, double length) {
   int[] x = roi.getXCoordinates();
   int[] y = roi.getYCoordinates();
   int n = roi.getNCoordinates();
   x = smooth(x, n);
   y = smooth(y, n);
   float[] curvature = getCurvature(x, y, n);
   Rectangle r = roi.getBounds();
   double threshold = rodbard(length);
   // IJ.log("trim: "+length+" "+threshold);
   double distance = Math.sqrt((x[1] - x[0]) * (x[1] - x[0]) + (y[1] - y[0]) * (y[1] - y[0]));
   x[0] += r.x;
   y[0] += r.y;
   int i2 = 1;
   int x1, y1, x2 = 0, y2 = 0;
   for (int i = 1; i < n - 1; i++) {
     x1 = x[i];
     y1 = y[i];
     x2 = x[i + 1];
     y2 = y[i + 1];
     distance += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) + 1;
     distance += curvature[i] * 2;
     if (distance >= threshold) {
       x[i2] = x2 + r.x;
       y[i2] = y2 + r.y;
       i2++;
       distance = 0.0;
     }
   }
   int type = roi.getType() == Roi.FREELINE ? Roi.POLYLINE : Roi.POLYGON;
   if (type == Roi.POLYLINE && distance > 0.0) {
     x[i2] = x2 + r.x;
     y[i2] = y2 + r.y;
     i2++;
   }
   PolygonRoi p = new PolygonRoi(x, y, i2, type);
   if (roi.getStroke() != null) p.setStrokeWidth(roi.getStrokeWidth());
   p.setStrokeColor(roi.getStrokeColor());
   p.setName(roi.getName());
   imp.setRoi(p);
   return p;
 }
예제 #17
0
 public void postProcess() {
   double stdDev;
   double n = num;
   for (int i = 0; i < len; i++) {
     if (num > 1) {
       stdDev = (n * sum2[i] - sum[i] * sum[i]) / n;
       if (stdDev > 0.0) result[i] = (float) Math.sqrt(stdDev / (n - 1.0));
       else result[i] = 0f;
     } else result[i] = 0f;
   }
 }
예제 #18
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();
  }
예제 #19
0
 void handleMouseMove(int sx, int sy) {
   // Do rubber banding
   int tool = Toolbar.getToolId();
   if (!(tool == Toolbar.POLYGON || tool == Toolbar.POLYLINE || tool == Toolbar.ANGLE)) {
     imp.deleteRoi();
     imp.draw();
     return;
   }
   drawRubberBand(sx, sy);
   degrees = Double.NaN;
   double len = -1;
   if (nPoints > 1) {
     double x1, y1, x2, y2;
     if (xpf != null) {
       x1 = xpf[nPoints - 2];
       y1 = ypf[nPoints - 2];
       x2 = xpf[nPoints - 1];
       y2 = ypf[nPoints - 1];
     } else {
       x1 = xp[nPoints - 2];
       y1 = yp[nPoints - 2];
       x2 = xp[nPoints - 1];
       y2 = yp[nPoints - 1];
     }
     degrees =
         getAngle(
             (int) Math.round(x1),
             (int) Math.round(y1),
             (int) Math.round(x2),
             (int) Math.round(y2));
     if (tool != Toolbar.ANGLE) {
       Calibration cal = imp.getCalibration();
       double pw = cal.pixelWidth, ph = cal.pixelHeight;
       if (IJ.altKeyDown()) {
         pw = 1.0;
         ph = 1.0;
       }
       len = Math.sqrt((x2 - x1) * pw * (x2 - x1) * pw + (y2 - y1) * ph * (y2 - y1) * ph);
     }
   }
   if (tool == Toolbar.ANGLE) {
     if (nPoints == 2) angle1 = degrees;
     else if (nPoints == 3) {
       double angle2 = getAngle(xp[1], yp[1], xp[2], yp[2]);
       degrees = Math.abs(180 - Math.abs(angle1 - angle2));
       if (degrees > 180.0) degrees = 360.0 - degrees;
     }
   }
   String length = len != -1 ? ", length=" + IJ.d2s(len) : "";
   double degrees2 =
       tool == Toolbar.ANGLE && nPoints == 3 && Prefs.reflexAngle ? 360.0 - degrees : degrees;
   String angle = !Double.isNaN(degrees) ? ", angle=" + IJ.d2s(degrees2) : "";
   int ox = ic != null ? ic.offScreenX(sx) : sx;
   int oy = ic != null ? ic.offScreenY(sy) : sy;
   IJ.showStatus(imp.getLocationAsString(ox, oy) + length + angle);
 }
예제 #20
0
 PolygonRoi trimFloatPolygon(PolygonRoi roi, double length) {
   FloatPolygon poly = roi.getFloatPolygon();
   float[] x = poly.xpoints;
   float[] y = poly.ypoints;
   int n = poly.npoints;
   x = smooth(x, n);
   y = smooth(y, n);
   float[] curvature = getCurvature(x, y, n);
   double threshold = rodbard(length);
   // IJ.log("trim: "+length+" "+threshold);
   double distance = Math.sqrt((x[1] - x[0]) * (x[1] - x[0]) + (y[1] - y[0]) * (y[1] - y[0]));
   int i2 = 1;
   double x1, y1, x2 = 0, y2 = 0;
   for (int i = 1; i < n - 1; i++) {
     x1 = x[i];
     y1 = y[i];
     x2 = x[i + 1];
     y2 = y[i + 1];
     distance += Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1)) + 1;
     distance += curvature[i] * 2;
     if (distance >= threshold) {
       x[i2] = (float) x2;
       y[i2] = (float) y2;
       i2++;
       distance = 0.0;
     }
   }
   int type = roi.getType() == Roi.FREELINE ? Roi.POLYLINE : Roi.POLYGON;
   if (type == Roi.POLYLINE && distance > 0.0) {
     x[i2] = (float) x2;
     y[i2] = (float) y2;
     i2++;
   }
   PolygonRoi p = new PolygonRoi(x, y, i2, type);
   if (roi.getStroke() != null) p.setStrokeWidth(roi.getStrokeWidth());
   p.setStrokeColor(roi.getStrokeColor());
   p.setDrawOffset(roi.getDrawOffset());
   p.setName(roi.getName());
   imp.setRoi(p);
   return p;
 }
예제 #21
0
 double getFloatSmoothedPerimeter() {
   double length = getSmoothedLineLength();
   double w2 = 1.0, h2 = 1.0;
   if (imp != null) {
     Calibration cal = imp.getCalibration();
     w2 = cal.pixelWidth * cal.pixelWidth;
     h2 = cal.pixelHeight * cal.pixelHeight;
   }
   double dx = xpf[nPoints - 1] - xpf[0];
   double dy = ypf[nPoints - 1] - ypf[0];
   length += Math.sqrt(dx * dx * w2 + dy * dy * h2);
   return length;
 }
예제 #22
0
 double getFloatSmoothedLineLength() {
   double length = 0.0;
   double w2 = 1.0;
   double h2 = 1.0;
   double dx, dy;
   if (imp != null) {
     Calibration cal = imp.getCalibration();
     w2 = cal.pixelWidth * cal.pixelWidth;
     h2 = cal.pixelHeight * cal.pixelHeight;
   }
   dx = (xpf[0] + xpf[1] + xpf[2]) / 3.0 - xpf[0];
   dy = (ypf[0] + ypf[1] + ypf[2]) / 3.0 - ypf[0];
   length += Math.sqrt(dx * dx * w2 + dy * dy * h2);
   for (int i = 1; i < nPoints - 2; i++) {
     dx = (xpf[i + 2] - xpf[i - 1]) / 3.0;
     dy = (ypf[i + 2] - ypf[i - 1]) / 3.0;
     length += Math.sqrt(dx * dx * w2 + dy * dy * h2);
   }
   dx = xpf[nPoints - 1] - (xpf[nPoints - 3] + xpf[nPoints - 2] + xpf[nPoints - 1]) / 3.0;
   dy = ypf[nPoints - 1] - (ypf[nPoints - 3] + ypf[nPoints - 2] + ypf[nPoints - 1]) / 3.0;
   length += Math.sqrt(dx * dx * w2 + dy * dy * h2);
   return length;
 }
예제 #23
0
 void addSelection() {
   ImagePlus imp = IJ.getImage();
   String macroOptions = Macro.getOptions();
   if (macroOptions != null && IJ.macroRunning() && macroOptions.indexOf("remove") != -1) {
     imp.setOverlay(null);
     return;
   }
   Roi roi = imp.getRoi();
   if (roi == null && imp.getOverlay() != null) {
     GenericDialog gd = new GenericDialog("No Selection");
     gd.addMessage("\"Overlay>Add\" requires a selection.");
     gd.setInsets(15, 40, 0);
     gd.addCheckbox("Remove existing overlay", false);
     gd.showDialog();
     if (gd.wasCanceled()) return;
     if (gd.getNextBoolean()) imp.setOverlay(null);
     return;
   }
   if (roi == null) {
     IJ.error("This command requires a selection.");
     return;
   }
   roi = (Roi) roi.clone();
   if (roi.getStrokeColor() == null) roi.setStrokeColor(Toolbar.getForegroundColor());
   int width = Line.getWidth();
   Rectangle bounds = roi.getBounds();
   boolean tooWide = width > Math.max(bounds.width, bounds.height) / 3.0;
   if (roi.getStroke() == null && width > 1 && !tooWide) roi.setStrokeWidth(Line.getWidth());
   Overlay overlay = imp.getOverlay();
   if (overlay != null && overlay.size() > 0 && !roi.isDrawingTool()) {
     Roi roi2 = overlay.get(overlay.size() - 1);
     if (roi.getStroke() == null) roi.setStrokeWidth(roi2.getStrokeWidth());
     if (roi.getFillColor() == null) roi.setFillColor(roi2.getFillColor());
   }
   boolean points = roi instanceof PointRoi && ((PolygonRoi) roi).getNCoordinates() > 1;
   if (points) roi.setStrokeColor(Color.red);
   if (!IJ.altKeyDown() && !(roi instanceof Arrow)) {
     RoiProperties rp = new RoiProperties("Add to Overlay", roi);
     if (!rp.showDialog()) return;
   }
   String name = roi.getName();
   boolean newOverlay = name != null && name.equals("new-overlay");
   if (overlay == null || newOverlay) overlay = new Overlay();
   overlay.add(roi);
   imp.setOverlay(overlay);
   overlay2 = overlay;
   if (points || (roi instanceof ImageRoi) || (roi instanceof Arrow)) imp.killRoi();
   Undo.setup(Undo.OVERLAY_ADDITION, imp);
 }
예제 #24
0
 /*
  * For a list of r² values, find the smallest r1² values such that a "ball"
  * of radius r1 centered at (dx,dy,dz) includes a "ball" of radius r
  * centered at the origin. "Ball" refers to a 3D integer grid.
  */
 int[] scanCube(int dx, int dy, int dz, int[] distSqValues) {
   final int numRadii = distSqValues.length;
   int[] r1Sq = new int[numRadii];
   if ((dx == 0) && (dy == 0) && (dz == 0)) {
     for (int rSq = 0; rSq < numRadii; rSq++) {
       r1Sq[rSq] = Integer.MAX_VALUE;
     }
   } else {
     final int dxAbs = -(int) Math.abs(dx);
     final int dyAbs = -(int) Math.abs(dy);
     final int dzAbs = -(int) Math.abs(dz);
     for (int rSqInd = 0; rSqInd < numRadii; rSqInd++) {
       final int rSq = distSqValues[rSqInd];
       int max = 0;
       final int r = 1 + (int) Math.sqrt(rSq);
       int scank, scankj;
       int dk, dkji;
       // int iBall;
       int iPlus;
       for (int k = 0; k <= r; k++) {
         scank = k * k;
         dk = (k - dzAbs) * (k - dzAbs);
         for (int j = 0; j <= r; j++) {
           scankj = scank + j * j;
           if (scankj <= rSq) {
             iPlus = ((int) Math.sqrt(rSq - scankj)) - dxAbs;
             dkji = dk + (j - dyAbs) * (j - dyAbs) + iPlus * iPlus;
             if (dkji > max) max = dkji;
           }
         }
       }
       r1Sq[rSqInd] = max;
     }
   }
   return r1Sq;
 }
예제 #25
0
 public void fitToWindow() {
   ImageWindow win = imp.getWindow();
   if (win == null) return;
   Rectangle bounds = win.getBounds();
   Insets insets = win.getInsets();
   int sliderHeight = (win instanceof StackWindow) ? 20 : 0;
   double xmag = (double) (bounds.width - 10) / srcRect.width;
   double ymag = (double) (bounds.height - (10 + insets.top + sliderHeight)) / srcRect.height;
   setMagnification(Math.min(xmag, ymag));
   int width = (int) (imageWidth * magnification);
   int height = (int) (imageHeight * magnification);
   if (width == dstWidth && height == dstHeight) return;
   srcRect = new Rectangle(0, 0, imageWidth, imageHeight);
   setDrawingSize(width, height);
   getParent().doLayout();
 }
예제 #26
0
  /** Returns the perimeter (for ROIs) or length (for lines). */
  public double getLength() {
    if (type == TRACED_ROI) return getTracedPerimeter();

    if (nPoints > 2) {
      if (type == FREEROI) return getSmoothedPerimeter();
      else if (type == FREELINE && !(width == 0 || height == 0)) return getSmoothedLineLength();
    }

    double length = 0.0;
    int dx, dy;
    double w2 = 1.0, h2 = 1.0;
    if (imp != null) {
      Calibration cal = imp.getCalibration();
      w2 = cal.pixelWidth * cal.pixelWidth;
      h2 = cal.pixelHeight * cal.pixelHeight;
    }
    if (xSpline != null) {
      double fdx, fdy;
      for (int i = 0; i < (splinePoints - 1); i++) {
        fdx = xSpline[i + 1] - xSpline[i];
        fdy = ySpline[i + 1] - ySpline[i];
        length += Math.sqrt(fdx * fdx * w2 + fdy * fdy * h2);
      }
      if (type == POLYGON) {
        fdx = xSpline[0] - xSpline[splinePoints - 1];
        fdy = ySpline[0] - ySpline[splinePoints - 1];
        length += Math.sqrt(fdx * fdx * w2 + fdy * fdy * h2);
      }
    } else if (xpf != null) {
      double fdx, fdy;
      for (int i = 0; i < (nPoints - 1); i++) {
        fdx = xpf[i + 1] - xpf[i];
        fdy = ypf[i + 1] - ypf[i];
        length += Math.sqrt(fdx * fdx * w2 + fdy * fdy * h2);
      }
      if (type == POLYGON) {
        fdx = xpf[0] - xpf[nPoints - 1];
        fdy = ypf[0] - ypf[nPoints - 1];
        length += Math.sqrt(fdx * fdx * w2 + fdy * fdy * h2);
      }
    } else {
      for (int i = 0; i < (nPoints - 1); i++) {
        dx = xp[i + 1] - xp[i];
        dy = yp[i + 1] - yp[i];
        length += Math.sqrt(dx * dx * w2 + dy * dy * h2);
      }
      if (type == POLYGON) {
        dx = xp[0] - xp[nPoints - 1];
        dy = yp[0] - yp[nPoints - 1];
        length += Math.sqrt(dx * dx * w2 + dy * dy * h2);
      }
    }
    return length;
  }
예제 #27
0
 float[] getCurvature(float[] x, float[] y, int n) {
   float[] x2 = new float[n];
   float[] y2 = new float[n];
   for (int i = 0; i < n; i++) {
     x2[i] = x[i];
     y2[i] = y[i];
   }
   ImageProcessor ipx = new FloatProcessor(n, 1, x, null);
   ImageProcessor ipy = new FloatProcessor(n, 1, y, null);
   ipx.convolve(kernel, kernel.length, 1);
   ipy.convolve(kernel, kernel.length, 1);
   float[] indexes = new float[n];
   float[] curvature = new float[n];
   for (int i = 0; i < n; i++) {
     indexes[i] = i;
     curvature[i] =
         (float) Math.sqrt((x2[i] - x[i]) * (x2[i] - x[i]) + (y2[i] - y[i]) * (y2[i] - y[i]));
   }
   return curvature;
 }
예제 #28
0
 byte[] read1bitImage(InputStream in) throws IOException {
   if (fi.compression == FileInfo.LZW)
     throw new IOException("ImageJ cannot open 1-bit LZW compressed TIFFs");
   int scan = (int) Math.ceil(width / 8.0);
   int len = scan * height;
   byte[] buffer = new byte[len];
   byte[] pixels = new byte[nPixels];
   DataInputStream dis = new DataInputStream(in);
   dis.readFully(buffer);
   int value1, value2, offset, index;
   for (int y = 0; y < height; y++) {
     offset = y * scan;
     index = y * width;
     for (int x = 0; x < scan; x++) {
       value1 = buffer[offset + x] & 0xff;
       for (int i = 7; i >= 0; i--) {
         value2 = (value1 & (1 << i)) != 0 ? 255 : 0;
         if (index < pixels.length) pixels[index++] = (byte) value2;
       }
     }
   }
   return pixels;
 }
예제 #29
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;
  }
예제 #30
0
  /*------------------------------------------------------------------*/
  void getSplineInterpolationCoefficients(double[] c, double tolerance) {
    double z[] = {Math.sqrt(3.0) - 2.0};
    double lambda = 1.0;

    if (c.length == 1) {
      return;
    }
    for (int k = 0; (k < z.length); k++) {
      lambda = lambda * (1.0 - z[k]) * (1.0 - 1.0 / z[k]);
    }
    for (int n = 0; (n < c.length); n++) {
      c[n] = c[n] * lambda;
    }
    for (int k = 0; (k < z.length); k++) {
      c[0] = getInitialCausalCoefficientMirrorOnBounds(c, z[k], tolerance);
      for (int n = 1; (n < c.length); n++) {
        c[n] = c[n] + z[k] * c[n - 1];
      }
      c[c.length - 1] = getInitialAntiCausalCoefficientMirrorOnBounds(c, z[k], tolerance);
      for (int n = c.length - 2; (0 <= n); n--) {
        c[n] = z[k] * (c[n + 1] - c[n]);
      }
    }
  } /* end getSplineInterpolationCoefficients */