예제 #1
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]);
   }
 }
예제 #2
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;
 }
예제 #3
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)));
 }
예제 #4
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);
 }
예제 #5
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;
 }
예제 #6
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;
   }
 }
예제 #7
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;
 }
예제 #8
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;
 }
예제 #9
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;
 }
예제 #10
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;
 }
예제 #11
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;
  }
예제 #12
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;
 }
예제 #13
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 */
예제 #14
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;
  }
예제 #15
0
파일: Info.java 프로젝트: boron1111/ij
  String getInfo(ImagePlus imp, ImageProcessor ip) {
    String s = new String("\n");
    s += "Title: " + imp.getTitle() + "\n";
    Calibration cal = imp.getCalibration();
    int stackSize = imp.getStackSize();
    int channels = imp.getNChannels();
    int slices = imp.getNSlices();
    int frames = imp.getNFrames();
    int digits = imp.getBitDepth() == 32 ? 4 : 0;
    if (cal.scaled()) {
      String unit = cal.getUnit();
      String units = cal.getUnits();
      s +=
          "Width:  "
              + IJ.d2s(imp.getWidth() * cal.pixelWidth, 2)
              + " "
              + units
              + " ("
              + imp.getWidth()
              + ")\n";
      s +=
          "Height:  "
              + IJ.d2s(imp.getHeight() * cal.pixelHeight, 2)
              + " "
              + units
              + " ("
              + imp.getHeight()
              + ")\n";
      if (slices > 1)
        s += "Depth:  " + IJ.d2s(slices * cal.pixelDepth, 2) + " " + units + " (" + slices + ")\n";
      double xResolution = 1.0 / cal.pixelWidth;
      double yResolution = 1.0 / cal.pixelHeight;
      int places = Tools.getDecimalPlaces(xResolution, yResolution);
      if (xResolution == yResolution)
        s += "Resolution:  " + IJ.d2s(xResolution, places) + " pixels per " + unit + "\n";
      else {
        s += "X Resolution:  " + IJ.d2s(xResolution, places) + " pixels per " + unit + "\n";
        s += "Y Resolution:  " + IJ.d2s(yResolution, places) + " pixels per " + unit + "\n";
      }
    } else {
      s += "Width:  " + imp.getWidth() + " pixels\n";
      s += "Height:  " + imp.getHeight() + " pixels\n";
      if (stackSize > 1) s += "Depth:  " + slices + " pixels\n";
    }
    if (stackSize > 1)
      s +=
          "Voxel size: "
              + d2s(cal.pixelWidth)
              + "x"
              + d2s(cal.pixelHeight)
              + "x"
              + d2s(cal.pixelDepth)
              + " "
              + cal.getUnit()
              + "\n";
    else
      s +=
          "Pixel size: "
              + d2s(cal.pixelWidth)
              + "x"
              + d2s(cal.pixelHeight)
              + " "
              + cal.getUnit()
              + "\n";

    s += "ID: " + imp.getID() + "\n";
    String zOrigin = stackSize > 1 || cal.zOrigin != 0.0 ? "," + d2s(cal.zOrigin) : "";
    s += "Coordinate origin:  " + d2s(cal.xOrigin) + "," + d2s(cal.yOrigin) + zOrigin + "\n";
    int type = imp.getType();
    switch (type) {
      case ImagePlus.GRAY8:
        s += "Bits per pixel: 8 ";
        String lut = "LUT";
        if (imp.getProcessor().isColorLut()) lut = "color " + lut;
        else lut = "grayscale " + lut;
        if (imp.isInvertedLut()) lut = "inverting " + lut;
        s += "(" + lut + ")\n";
        if (imp.getNChannels() > 1) s += displayRanges(imp);
        else s += "Display range: " + (int) ip.getMin() + "-" + (int) ip.getMax() + "\n";
        break;
      case ImagePlus.GRAY16:
      case ImagePlus.GRAY32:
        if (type == ImagePlus.GRAY16) {
          String sign = cal.isSigned16Bit() ? "signed" : "unsigned";
          s += "Bits per pixel: 16 (" + sign + ")\n";
        } else s += "Bits per pixel: 32 (float)\n";
        if (imp.getNChannels() > 1) s += displayRanges(imp);
        else {
          s += "Display range: ";
          double min = ip.getMin();
          double max = ip.getMax();
          if (cal.calibrated()) {
            min = cal.getCValue((int) min);
            max = cal.getCValue((int) max);
          }
          s += IJ.d2s(min, digits) + " - " + IJ.d2s(max, digits) + "\n";
        }
        break;
      case ImagePlus.COLOR_256:
        s += "Bits per pixel: 8 (color LUT)\n";
        break;
      case ImagePlus.COLOR_RGB:
        s += "Bits per pixel: 32 (RGB)\n";
        break;
    }
    double interval = cal.frameInterval;
    double fps = cal.fps;
    if (stackSize > 1) {
      ImageStack stack = imp.getStack();
      int slice = imp.getCurrentSlice();
      String number = slice + "/" + stackSize;
      String label = stack.getShortSliceLabel(slice);
      if (label != null && label.length() > 0) label = " (" + label + ")";
      else label = "";
      if (interval > 0.0 || fps != 0.0) {
        s += "Frame: " + number + label + "\n";
        if (fps != 0.0) {
          String sRate =
              Math.abs(fps - Math.round(fps)) < 0.00001 ? IJ.d2s(fps, 0) : IJ.d2s(fps, 5);
          s += "Frame rate: " + sRate + " fps\n";
        }
        if (interval != 0.0)
          s +=
              "Frame interval: "
                  + ((int) interval == interval ? IJ.d2s(interval, 0) : IJ.d2s(interval, 5))
                  + " "
                  + cal.getTimeUnit()
                  + "\n";
      } else s += "Image: " + number + label + "\n";
      if (imp.isHyperStack()) {
        if (channels > 1) s += "  Channel: " + imp.getChannel() + "/" + channels + "\n";
        if (slices > 1) s += "  Slice: " + imp.getSlice() + "/" + slices + "\n";
        if (frames > 1) s += "  Frame: " + imp.getFrame() + "/" + frames + "\n";
      }
      if (imp.isComposite()) {
        if (!imp.isHyperStack() && channels > 1) s += "  Channels: " + channels + "\n";
        String mode = ((CompositeImage) imp).getModeAsString();
        s += "  Composite mode: \"" + mode + "\"\n";
      }
    }

    if (ip.getMinThreshold() == ImageProcessor.NO_THRESHOLD) s += "No Threshold\n";
    else {
      double lower = ip.getMinThreshold();
      double upper = ip.getMaxThreshold();
      int dp = digits;
      if (cal.calibrated()) {
        lower = cal.getCValue((int) lower);
        upper = cal.getCValue((int) upper);
        dp = cal.isSigned16Bit() ? 0 : 4;
      }
      s += "Threshold: " + IJ.d2s(lower, dp) + "-" + IJ.d2s(upper, dp) + "\n";
    }
    ImageCanvas ic = imp.getCanvas();
    double mag = ic != null ? ic.getMagnification() : 1.0;
    if (mag != 1.0) s += "Magnification: " + IJ.d2s(mag, 2) + "\n";

    if (cal.calibrated()) {
      s += " \n";
      int curveFit = cal.getFunction();
      s += "Calibration Function: ";
      if (curveFit == Calibration.UNCALIBRATED_OD) s += "Uncalibrated OD\n";
      else if (curveFit == Calibration.CUSTOM) s += "Custom lookup table\n";
      else s += CurveFitter.fList[curveFit] + "\n";
      double[] c = cal.getCoefficients();
      if (c != null) {
        s += "  a: " + IJ.d2s(c[0], 6) + "\n";
        s += "  b: " + IJ.d2s(c[1], 6) + "\n";
        if (c.length >= 3) s += "  c: " + IJ.d2s(c[2], 6) + "\n";
        if (c.length >= 4) s += "  c: " + IJ.d2s(c[3], 6) + "\n";
        if (c.length >= 5) s += "  c: " + IJ.d2s(c[4], 6) + "\n";
      }
      s += "  Unit: \"" + cal.getValueUnit() + "\"\n";
    } else s += "Uncalibrated\n";

    FileInfo fi = imp.getOriginalFileInfo();
    if (fi != null) {
      if (fi.url != null && !fi.url.equals("")) s += "URL: " + fi.url + "\n";
      else if (fi.directory != null && fi.fileName != null)
        s += "Path: " + fi.directory + fi.fileName + "\n";
    }

    ImageWindow win = imp.getWindow();
    if (win != null) {
      Point loc = win.getLocation();
      Dimension screen = IJ.getScreenSize();
      s +=
          "Screen location: "
              + loc.x
              + ","
              + loc.y
              + " ("
              + screen.width
              + "x"
              + screen.height
              + ")\n";
    }

    Overlay overlay = imp.getOverlay();
    if (overlay != null) {
      String hidden = imp.getHideOverlay() ? " (hidden)" : " ";
      int n = overlay.size();
      String elements = n == 1 ? " element" : " elements";
      s += "Overlay: " + n + elements + (imp.getHideOverlay() ? " (hidden)" : "") + "\n";
    } else s += "No Overlay\n";

    Roi roi = imp.getRoi();
    if (roi == null) {
      if (cal.calibrated()) s += " \n";
      s += "No Selection\n";
    } else if (roi instanceof EllipseRoi) {
      s += "\nElliptical Selection\n";
      double[] p = ((EllipseRoi) roi).getParams();
      double dx = p[2] - p[0];
      double dy = p[3] - p[1];
      double major = Math.sqrt(dx * dx + dy * dy);
      s += "  Major: " + IJ.d2s(major, 2) + "\n";
      s += "  Minor: " + IJ.d2s(major * p[4], 2) + "\n";
      s += "  X1: " + IJ.d2s(p[0], 2) + "\n";
      s += "  Y1: " + IJ.d2s(p[1], 2) + "\n";
      s += "  X2: " + IJ.d2s(p[2], 2) + "\n";
      s += "  Y2: " + IJ.d2s(p[3], 2) + "\n";
      s += "  Aspect ratio: " + IJ.d2s(p[4], 2) + "\n";
    } else {
      s += " \n";
      s += roi.getTypeAsString() + " Selection";
      String points = null;
      if (roi instanceof PointRoi) {
        int npoints = ((PolygonRoi) roi).getNCoordinates();
        String suffix = npoints > 1 ? "s)" : ")";
        points = " (" + npoints + " point" + suffix;
      }
      String name = roi.getName();
      if (name != null) {
        s += " (\"" + name + "\")";
        if (points != null) s += "\n " + points;
      } else if (points != null) s += points;
      s += "\n";
      Rectangle r = roi.getBounds();
      if (roi instanceof Line) {
        Line line = (Line) roi;
        s += "  X1: " + IJ.d2s(line.x1d * cal.pixelWidth) + "\n";
        s += "  Y1: " + IJ.d2s(yy(line.y1d, imp) * cal.pixelHeight) + "\n";
        s += "  X2: " + IJ.d2s(line.x2d * cal.pixelWidth) + "\n";
        s += "  Y2: " + IJ.d2s(yy(line.y2d, imp) * cal.pixelHeight) + "\n";
      } else if (cal.scaled()) {
        s += "  X: " + IJ.d2s(cal.getX(r.x)) + " (" + r.x + ")\n";
        s += "  Y: " + IJ.d2s(cal.getY(r.y, imp.getHeight())) + " (" + r.y + ")\n";
        s += "  Width: " + IJ.d2s(r.width * cal.pixelWidth) + " (" + r.width + ")\n";
        s += "  Height: " + IJ.d2s(r.height * cal.pixelHeight) + " (" + r.height + ")\n";
      } else {
        s += "  X: " + r.x + "\n";
        s += "  Y: " + yy(r.y, imp) + "\n";
        s += "  Width: " + r.width + "\n";
        s += "  Height: " + r.height + "\n";
      }
    }

    return s;
  }
예제 #16
0
 public void updatebeta() {
   for (int i = 0; i <= ncurves; i++) {
     brightmincc[i] = (bright1[i] * beta) / Math.sqrt(intensity1[i] / intensity2[i]);
     eminccarray[i].setText("" + (float) brightmincc[i]);
   }
 }
예제 #17
0
 private void updateavg() {
   nmeas[ncurves] = 0;
   avg = new float[xpts][ypts];
   avgweights = new float[xpts][ypts];
   for (int i = 0; i < ncurves; i++) {
     if (include[i]) {
       for (int j = 0; j < xpts; j++) {
         for (int k = 0; k < ypts; k++) {
           avg[j][k] += pch[i][j][k];
           nmeas[ncurves] += (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 i = 0; i < xpts; i++) {
     for (int j = 0; j < ypts; j++) {
       double normed = (double) avg[i][j] / (double) nmeas[ncurves];
       avgweights[i][j] = (float) ((double) nmeas[ncurves] / (normed * (1.0f - normed)));
       if (avg[i][j] > 0.0f) {
         avgweights[i][j] = (float) ((double) nmeas[ncurves] / (normed * (1.0f - normed)));
       } else {
         avgweights[i][j] = 1.0f;
       }
       tempavg += (double) i * normed;
       tempavg2 += (double) i * (double) i * normed;
       temp2avg += (double) j * normed;
       temp2avg2 += (double) j * (double) j * normed;
       tempccavg += (double) i * (double) j * normed;
     }
   }
   tempccavg -= tempavg * temp2avg;
   brightcc[ncurves] = tempccavg / Math.sqrt(tempavg * temp2avg);
   tempavg2 -= tempavg * tempavg;
   tempavg2 /= tempavg;
   bright1[ncurves] = (tempavg2 - 1.0);
   temp2avg2 -= temp2avg * temp2avg;
   temp2avg2 /= temp2avg;
   bright2[ncurves] = (temp2avg2 - 1.0);
   intensity1[ncurves] = tempavg;
   intensity2[ncurves] = temp2avg;
   if (psfflag == 0) {
     bright1[ncurves] /= 0.3536;
     bright2[ncurves] /= 0.3536;
     brightcc[ncurves] /= 0.3536;
   } else {
     if (psfflag == 1) {
       bright1[ncurves] /= 0.078;
       bright2[ncurves] /= 0.078;
       brightcc[ncurves] /= 0.078;
     } else {
       bright1[ncurves] /= 0.5;
       bright2[ncurves] /= 0.5;
       brightcc[ncurves] /= 0.5;
     }
   }
   number1[ncurves] = intensity1[ncurves] / bright1[ncurves];
   number2[ncurves] = intensity2[ncurves] / bright2[ncurves];
   brightmincc[ncurves] =
       (bright1[ncurves] * beta) * Math.sqrt(intensity1[ncurves] / intensity2[ncurves]);
 }
예제 #18
0
  /**
   * DistanceRidgetoLocalThickness
   *
   * <p>Input: Distance Ridge (32-bit stack) (Output from Distance Ridge.java) Output: Local
   * Thickness. Overwrites the input.
   *
   * <ul>
   *   <li>Version 1: September 6, 2006.
   *   <li>Version 2: September 25, 2006. Fixed several bugs that resulted in non-symmetrical output
   *       from symmetrical input.
   *   <li>Version 2.1 Oct. 1, 2006. Fixed a rounding error that caused some points to be missed.
   *   <li>Version 3 July 31, 2007. Parallel processing version.
   *   <li>Version 3.1 Multiplies the output by 2 to conform with the definition of local thickness
   * </ul>
   *
   * @param imp
   */
  private void distanceRidgetoLocalThickness(ImagePlus imp, float[][] s) {
    final int w = imp.getWidth();
    final int h = imp.getHeight();
    final int d = imp.getStackSize();
    float[] sk;
    // Count the distance ridge points on each slice
    int[] nRidge = new int[d];
    int ind, nr, iR;
    IJ.showStatus("Local Thickness: scanning stack ");
    for (int k = 0; k < d; k++) {
      sk = s[k];
      nr = 0;
      for (int j = 0; j < h; j++) {
        final int wj = w * j;
        for (int i = 0; i < w; i++) {
          ind = i + wj;
          if (sk[ind] > 0) nr++;
        }
      }
      nRidge[k] = nr;
    }
    int[][] iRidge = new int[d][];
    int[][] jRidge = new int[d][];
    float[][] rRidge = new float[d][];
    // Pull out the distance ridge points
    int[] iRidgeK, jRidgeK;
    float[] rRidgeK;
    float sMax = 0;
    for (int k = 0; k < d; k++) {
      nr = nRidge[k];
      iRidge[k] = new int[nr];
      jRidge[k] = new int[nr];
      rRidge[k] = new float[nr];
      sk = s[k];
      iRidgeK = iRidge[k];
      jRidgeK = jRidge[k];
      rRidgeK = rRidge[k];
      iR = 0;
      for (int j = 0; j < h; j++) {
        final int wj = w * j;
        for (int i = 0; i < w; i++) {
          ind = i + wj;
          if (sk[ind] > 0) {;
            iRidgeK[iR] = i;
            jRidgeK[iR] = j;
            rRidgeK[iR++] = sk[ind];
            if (sk[ind] > sMax) sMax = sk[ind];
            sk[ind] = 0;
          }
        }
      }
    }
    int nThreads = Runtime.getRuntime().availableProcessors();
    final Object[] resources = new Object[d]; // For synchronization
    for (int k = 0; k < d; k++) {
      resources[k] = new Object();
    }
    LTThread[] ltt = new LTThread[nThreads];
    for (int thread = 0; thread < nThreads; thread++) {
      ltt[thread] =
          new LTThread(thread, nThreads, w, h, d, nRidge, s, iRidge, jRidge, rRidge, resources);
      ltt[thread].start();
    }
    try {
      for (int thread = 0; thread < nThreads; thread++) {
        ltt[thread].join();
      }
    } catch (InterruptedException ie) {
      IJ.error("A thread was interrupted .");
    }

    // Fix the square values and apply factor of 2
    IJ.showStatus("Local Thickness: square root ");
    for (int k = 0; k < d; k++) {
      sk = s[k];
      for (int j = 0; j < h; j++) {
        final int wj = w * j;
        for (int i = 0; i < w; i++) {
          ind = i + wj;
          sk[ind] = (float) (2 * Math.sqrt(sk[ind]));
        }
      }
    }
    IJ.showStatus("Local Thickness complete");
    return;
  }
예제 #19
0
  /**
   * Saito-Toriwaki algorithm for Euclidian Distance Transformation. Direct application of Algorithm
   * 1. Bob Dougherty 8/8/2006
   *
   * <ul>
   *   <li>Version S1A: lower memory usage.
   *   <li>Version S1A.1 A fixed indexing bug for 666-bin data set
   *   <li>Version S1A.2 Aug. 9, 2006. Changed noResult value.
   *   <li>Version S1B Aug. 9, 2006. Faster.
   *   <li>Version S1B.1 Sept. 6, 2006. Changed comments.
   *   <li>Version S1C Oct. 1, 2006. Option for inverse case. <br>
   *       Fixed inverse behavior in y and z directions.
   *   <li>Version D July 30, 2007. Multithread processing for step 2.
   * </ul>
   *
   * <p>This version assumes the input stack is already in memory, 8-bit, and outputs to a new
   * 32-bit stack. Versions that are more stingy with memory may be forthcoming.
   *
   * @param imp 8-bit (binary) ImagePlus
   */
  private float[][] geometryToDistanceMap(ImagePlus imp, boolean inv) {
    final int w = imp.getWidth();
    final int h = imp.getHeight();
    final int d = imp.getStackSize();
    int nThreads = Runtime.getRuntime().availableProcessors();

    // Create references to input data
    ImageStack stack = imp.getStack();
    byte[][] data = new byte[d][];
    for (int k = 0; k < d; k++) data[k] = (byte[]) stack.getPixels(k + 1);

    // Create 32 bit floating point stack for output, s. Will also use it
    // for g in Transformation 1.
    float[][] s = new float[d][];
    for (int k = 0; k < d; k++) {
      ImageProcessor ipk = new FloatProcessor(w, h);
      s[k] = (float[]) ipk.getPixels();
    }
    float[] sk;
    // Transformation 1. Use s to store g.
    IJ.showStatus("EDT transformation 1/3");
    Step1Thread[] s1t = new Step1Thread[nThreads];
    for (int thread = 0; thread < nThreads; thread++) {
      s1t[thread] = new Step1Thread(thread, nThreads, w, h, d, inv, s, data);
      s1t[thread].start();
    }
    try {
      for (int thread = 0; thread < nThreads; thread++) {
        s1t[thread].join();
      }
    } catch (InterruptedException ie) {
      IJ.error("A thread was interrupted in step 1 .");
    }
    // Transformation 2. g (in s) -> h (in s)
    IJ.showStatus("EDT transformation 2/3");
    Step2Thread[] s2t = new Step2Thread[nThreads];
    for (int thread = 0; thread < nThreads; thread++) {
      s2t[thread] = new Step2Thread(thread, nThreads, w, h, d, s);
      s2t[thread].start();
    }
    try {
      for (int thread = 0; thread < nThreads; thread++) {
        s2t[thread].join();
      }
    } catch (InterruptedException ie) {
      IJ.error("A thread was interrupted in step 2 .");
    }
    // Transformation 3. h (in s) -> s
    IJ.showStatus("EDT transformation 3/3");
    Step3Thread[] s3t = new Step3Thread[nThreads];
    for (int thread = 0; thread < nThreads; thread++) {
      s3t[thread] = new Step3Thread(thread, nThreads, w, h, d, inv, s, data);
      s3t[thread].start();
    }
    try {
      for (int thread = 0; thread < nThreads; thread++) {
        s3t[thread].join();
      }
    } catch (InterruptedException ie) {
      IJ.error("A thread was interrupted in step 3 .");
    }
    // Find the largest distance for scaling
    // Also fill in the background values.
    float distMax = 0;
    final int wh = w * h;
    float dist;
    for (int k = 0; k < d; k++) {
      sk = s[k];
      for (int ind = 0; ind < wh; ind++) {
        if (((data[k][ind] & 255) < 128) ^ inv) {
          sk[ind] = 0;
        } else {
          dist = (float) Math.sqrt(sk[ind]);
          sk[ind] = dist;
          distMax = (dist > distMax) ? dist : distMax;
        }
      }
    }
    IJ.showProgress(1.0);
    IJ.showStatus("Done");
    return s;
  }
예제 #20
0
  void Sauvola(ImagePlus imp, int radius, double par1, double par2, boolean doIwhite) {
    // Sauvola recommends K_VALUE = 0.5 and R_VALUE = 128.
    // This is a modification of Niblack's thresholding method.
    // Sauvola J. and Pietaksinen M. (2000) "Adaptive Document Image Binarization"
    // Pattern Recognition, 33(2): 225-236
    // http://www.ee.oulu.fi/mvg/publications/show_pdf.php?ID=24
    // Ported to ImageJ plugin from E Celebi's fourier_0.8 routines
    // This version uses a circular local window, instead of a rectagular one

    ImagePlus Meanimp, Varimp;
    ImageProcessor ip = imp.getProcessor(), ipMean, ipVar;
    double k_value = 0.5;
    double r_value = 128;
    byte object;
    byte backg;

    if (par1 != 0) {
      IJ.log("Sauvola: changed k_value from :" + k_value + "  to:" + par1);
      k_value = par1;
    }

    if (par2 != 0) {
      IJ.log("Sauvola: changed r_value from :" + r_value + "  to:" + par2);
      r_value = par2;
    }

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

    Meanimp = duplicateImage(ip);
    ImageConverter ic = new ImageConverter(Meanimp);
    ic.convertToGray32();

    ipMean = Meanimp.getProcessor();
    RankFilters rf = new RankFilters();
    rf.rank(ipMean, radius, rf.MEAN); // Mean
    // Meanimp.show();
    Varimp = duplicateImage(ip);
    ic = new ImageConverter(Varimp);
    ic.convertToGray32();
    ipVar = Varimp.getProcessor();
    rf.rank(ipVar, radius, rf.VARIANCE); // Variance
    // Varimp.show();
    byte[] pixels = (byte[]) ip.getPixels();
    float[] mean = (float[]) ipMean.getPixels();
    float[] var = (float[]) ipVar.getPixels();

    for (int i = 0; i < pixels.length; i++)
      pixels[i] =
          ((int) (pixels[i] & 0xff)
                  > (int) (mean[i] * (1.0 + k_value * ((Math.sqrt(var[i]) / r_value) - 1.0))))
              ? object
              : backg;
    // imp.updateAndDraw();
    return;
  }
  void jacobi(double[][] a, int n, double[] d, double[][] v)
        /* 	a matrice de depart,
        n taille du systeme,
        d valeurs propres
        v matrice de passage : vecteur propre normalises  */

      {
    int j, iq, ip, i;
    double tresh, theta, tau, t, sm, s, h, g, c;
    double[] b = new double[3];
    double[] z = new double[3];

    for (ip = 0; ip < n; ip++) {
      for (iq = 0; iq < n; iq++) {
        v[ip][iq] = 0.0;
      }
      v[ip][ip] = 1.0;
    }
    for (ip = 0; ip < n; ip++) {
      b[ip] = d[ip] = a[ip][ip];
      z[ip] = 0.0;
    }
    // int nrot=0;
    for (i = 1; i <= 50; i++) {
      sm = 0.0;
      for (ip = 0; ip < n - 1; ip++) {
        for (iq = ip + 1; iq < n; iq++) sm += Math.abs(a[ip][iq]);
      }
      if (sm == 0.0) {
        return;
      }
      if (i < 4) tresh = 0.2 * sm / (n * n);
      else tresh = 0.0;
      for (ip = 0; ip < n - 1; ip++) {
        for (iq = ip + 1; iq < n; iq++) {
          g = 100.0 * Math.abs(a[ip][iq]);
          if (i > 4
              && Math.abs(d[ip]) + g == Math.abs(d[ip])
              && Math.abs(d[iq]) + g == Math.abs(d[iq])) a[ip][iq] = 0.0;
          else if (Math.abs(a[ip][iq]) > tresh) {
            h = d[iq] - d[ip];
            if (Math.abs(h) + g == Math.abs(h)) t = (a[ip][iq]) / h;
            else {
              theta = 0.5 * h / (a[ip][iq]);
              t = 1.0 / (Math.abs(theta) + Math.sqrt(1.0 + theta * theta));
              if (theta < 0.0) t = -t;
            }
            c = 1.0 / Math.sqrt(1 + t * t);
            s = t * c;
            tau = s / (1.0 + c);
            h = t * a[ip][iq];
            z[ip] -= h;
            z[iq] += h;
            d[ip] -= h;
            d[iq] += h;
            a[ip][iq] = 0.0;
            for (j = 0; j <= ip - 1; j++) {
              ROTATE(a, j, ip, j, iq, tau, s);
            }
            for (j = ip + 1; j <= iq - 1; j++) {
              ROTATE(a, ip, j, j, iq, tau, s);
            }
            for (j = iq + 1; j < n; j++) {
              ROTATE(a, ip, j, iq, j, tau, s);
            }
            for (j = 0; j < n; j++) {
              ROTATE(v, j, ip, j, iq, tau, s);
            }
            // ++nrot;
          }
        }
      }
      for (ip = 0; ip < n; ip++) {
        b[ip] += z[ip];
        d[ip] = b[ip];
        z[ip] = 0.0;
      }
    }
  }
예제 #22
0
  /*
  if selection is closed shape, create a circle with the same area and centroid, otherwise use<br>
  the Pratt method to fit a circle to the points that define the line or multi-point selection.<br>
  Reference: Pratt V., Direct least-squares fitting of algebraic surfaces", Computer Graphics, Vol. 21, pages 145-152 (1987).<br>
  Original code: Nikolai Chernov's MATLAB script for Newton-based Pratt fit.<br>
  (http://www.math.uab.edu/~chernov/cl/MATLABcircle.html)<br>
  Java version: https://github.com/mdoube/BoneJ/blob/master/src/org/doube/geometry/FitCircle.java<br>
  @authors Nikolai Chernov, Michael Doube, Ved Sharma
  */
  void fitCircle(ImagePlus imp) {
    Roi roi = imp.getRoi();
    if (roi == null) {
      noRoi("Fit Circle");
      return;
    }

    if (roi.isArea()) { // create circle with the same area and centroid
      ImageProcessor ip = imp.getProcessor();
      ip.setRoi(roi);
      ImageStatistics stats =
          ImageStatistics.getStatistics(ip, Measurements.AREA + Measurements.CENTROID, null);
      double r = Math.sqrt(stats.pixelCount / Math.PI);
      imp.killRoi();
      int d = (int) Math.round(2.0 * r);
      IJ.makeOval(
          (int) Math.round(stats.xCentroid - r), (int) Math.round(stats.yCentroid - r), d, d);
      return;
    }

    Polygon poly = roi.getPolygon();
    int n = poly.npoints;
    int[] x = poly.xpoints;
    int[] y = poly.ypoints;
    if (n < 3) {
      IJ.error("Fit Circle", "At least 3 points are required to fit a circle.");
      return;
    }

    // calculate point centroid
    double sumx = 0, sumy = 0;
    for (int i = 0; i < n; i++) {
      sumx = sumx + poly.xpoints[i];
      sumy = sumy + poly.ypoints[i];
    }
    double meanx = sumx / n;
    double meany = sumy / n;

    // calculate moments
    double[] X = new double[n], Y = new double[n];
    double Mxx = 0, Myy = 0, Mxy = 0, Mxz = 0, Myz = 0, Mzz = 0;
    for (int i = 0; i < n; i++) {
      X[i] = x[i] - meanx;
      Y[i] = y[i] - meany;
      double Zi = X[i] * X[i] + Y[i] * Y[i];
      Mxy = Mxy + X[i] * Y[i];
      Mxx = Mxx + X[i] * X[i];
      Myy = Myy + Y[i] * Y[i];
      Mxz = Mxz + X[i] * Zi;
      Myz = Myz + Y[i] * Zi;
      Mzz = Mzz + Zi * Zi;
    }
    Mxx = Mxx / n;
    Myy = Myy / n;
    Mxy = Mxy / n;
    Mxz = Mxz / n;
    Myz = Myz / n;
    Mzz = Mzz / n;

    // calculate the coefficients of the characteristic polynomial
    double Mz = Mxx + Myy;
    double Cov_xy = Mxx * Myy - Mxy * Mxy;
    double Mxz2 = Mxz * Mxz;
    double Myz2 = Myz * Myz;
    double A2 = 4 * Cov_xy - 3 * Mz * Mz - Mzz;
    double A1 = Mzz * Mz + 4 * Cov_xy * Mz - Mxz2 - Myz2 - Mz * Mz * Mz;
    double A0 = Mxz2 * Myy + Myz2 * Mxx - Mzz * Cov_xy - 2 * Mxz * Myz * Mxy + Mz * Mz * Cov_xy;
    double A22 = A2 + A2;
    double epsilon = 1e-12;
    double ynew = 1e+20;
    int IterMax = 20;
    double xnew = 0;
    int iterations = 0;

    // Newton's method starting at x=0
    for (int iter = 1; iter <= IterMax; iter++) {
      iterations = iter;
      double yold = ynew;
      ynew = A0 + xnew * (A1 + xnew * (A2 + 4. * xnew * xnew));
      if (Math.abs(ynew) > Math.abs(yold)) {
        if (IJ.debugMode) IJ.log("Fit Circle: wrong direction: |ynew| > |yold|");
        xnew = 0;
        break;
      }
      double Dy = A1 + xnew * (A22 + 16 * xnew * xnew);
      double xold = xnew;
      xnew = xold - ynew / Dy;
      if (Math.abs((xnew - xold) / xnew) < epsilon) break;
      if (iter >= IterMax) {
        if (IJ.debugMode) IJ.log("Fit Circle: will not converge");
        xnew = 0;
      }
      if (xnew < 0) {
        if (IJ.debugMode) IJ.log("Fit Circle: negative root:  x = " + xnew);
        xnew = 0;
      }
    }
    if (IJ.debugMode)
      IJ.log("Fit Circle: n=" + n + ", xnew=" + IJ.d2s(xnew, 2) + ", iterations=" + iterations);

    // calculate the circle parameters
    double DET = xnew * xnew - xnew * Mz + Cov_xy;
    double CenterX = (Mxz * (Myy - xnew) - Myz * Mxy) / (2 * DET);
    double CenterY = (Myz * (Mxx - xnew) - Mxz * Mxy) / (2 * DET);
    double radius = Math.sqrt(CenterX * CenterX + CenterY * CenterY + Mz + 2 * xnew);
    if (Double.isNaN(radius)) {
      IJ.error("Fit Circle", "Points are collinear.");
      return;
    }
    CenterX = CenterX + meanx;
    CenterY = CenterY + meany;
    imp.killRoi();
    IJ.makeOval(
        (int) Math.round(CenterX - radius),
        (int) Math.round(CenterY - radius),
        (int) Math.round(2 * radius),
        (int) Math.round(2 * radius));
  }
예제 #23
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();
  }
예제 #24
0
  /*------------------------------------------------------------------*/
  void doIt(ImageProcessor ip) {
    int width = ip.getWidth();
    int height = ip.getHeight();
    double hLine[] = new double[width];
    double vLine[] = new double[height];

    if (!(ip.getPixels() instanceof float[])) {
      throw new IllegalArgumentException("Float image required");
    }
    switch (operation) {
      case GRADIENT_MAGNITUDE:
        {
          ImageProcessor h = ip.duplicate();
          ImageProcessor v = ip.duplicate();
          float[] floatPixels = (float[]) ip.getPixels();
          float[] floatPixelsH = (float[]) h.getPixels();
          float[] floatPixelsV = (float[]) v.getPixels();

          getHorizontalGradient(h, FLT_EPSILON);
          getVerticalGradient(v, FLT_EPSILON);
          for (int y = 0, k = 0; (y < height); y++) {
            for (int x = 0; (x < width); x++, k++) {
              floatPixels[k] =
                  (float)
                      Math.sqrt(
                          floatPixelsH[k] * floatPixelsH[k] + floatPixelsV[k] * floatPixelsV[k]);
            }
            stepProgressBar();
          }
        }
        break;
      case GRADIENT_DIRECTION:
        {
          ImageProcessor h = ip.duplicate();
          ImageProcessor v = ip.duplicate();
          float[] floatPixels = (float[]) ip.getPixels();
          float[] floatPixelsH = (float[]) h.getPixels();
          float[] floatPixelsV = (float[]) v.getPixels();

          getHorizontalGradient(h, FLT_EPSILON);
          getVerticalGradient(v, FLT_EPSILON);
          for (int y = 0, k = 0; (y < height); y++) {
            for (int x = 0; (x < width); x++, k++) {
              floatPixels[k] = (float) Math.atan2(floatPixelsH[k], floatPixelsV[k]);
            }
            stepProgressBar();
          }
        }
        break;
      case LAPLACIAN:
        {
          ImageProcessor hh = ip.duplicate();
          ImageProcessor vv = ip.duplicate();
          float[] floatPixels = (float[]) ip.getPixels();
          float[] floatPixelsHH = (float[]) hh.getPixels();
          float[] floatPixelsVV = (float[]) vv.getPixels();

          getHorizontalHessian(hh, FLT_EPSILON);
          getVerticalHessian(vv, FLT_EPSILON);
          for (int y = 0, k = 0; (y < height); y++) {
            for (int x = 0; (x < width); x++, k++) {
              floatPixels[k] = (float) (floatPixelsHH[k] + floatPixelsVV[k]);
            }
            stepProgressBar();
          }
        }
        break;
      case LARGEST_HESSIAN:
        {
          ImageProcessor hh = ip.duplicate();
          ImageProcessor vv = ip.duplicate();
          ImageProcessor hv = ip.duplicate();
          float[] floatPixels = (float[]) ip.getPixels();
          float[] floatPixelsHH = (float[]) hh.getPixels();
          float[] floatPixelsVV = (float[]) vv.getPixels();
          float[] floatPixelsHV = (float[]) hv.getPixels();

          getHorizontalHessian(hh, FLT_EPSILON);
          getVerticalHessian(vv, FLT_EPSILON);
          getCrossHessian(hv, FLT_EPSILON);
          for (int y = 0, k = 0; (y < height); y++) {
            for (int x = 0; (x < width); x++, k++) {
              floatPixels[k] =
                  (float)
                      (0.5
                          * (floatPixelsHH[k]
                              + floatPixelsVV[k]
                              + Math.sqrt(
                                  4.0 * floatPixelsHV[k] * floatPixelsHV[k]
                                      + (floatPixelsHH[k] - floatPixelsVV[k])
                                          * (floatPixelsHH[k] - floatPixelsVV[k]))));
            }
            stepProgressBar();
          }
        }
        break;
      case SMALLEST_HESSIAN:
        {
          ImageProcessor hh = ip.duplicate();
          ImageProcessor vv = ip.duplicate();
          ImageProcessor hv = ip.duplicate();
          float[] floatPixels = (float[]) ip.getPixels();
          float[] floatPixelsHH = (float[]) hh.getPixels();
          float[] floatPixelsVV = (float[]) vv.getPixels();
          float[] floatPixelsHV = (float[]) hv.getPixels();

          getHorizontalHessian(hh, FLT_EPSILON);
          getVerticalHessian(vv, FLT_EPSILON);
          getCrossHessian(hv, FLT_EPSILON);
          for (int y = 0, k = 0; (y < height); y++) {
            for (int x = 0; (x < width); x++, k++) {
              floatPixels[k] =
                  (float)
                      (0.5
                          * (floatPixelsHH[k]
                              + floatPixelsVV[k]
                              - Math.sqrt(
                                  4.0 * floatPixelsHV[k] * floatPixelsHV[k]
                                      + (floatPixelsHH[k] - floatPixelsVV[k])
                                          * (floatPixelsHH[k] - floatPixelsVV[k]))));
            }
            stepProgressBar();
          }
        }
        break;
      case HESSIAN_ORIENTATION:
        {
          ImageProcessor hh = ip.duplicate();
          ImageProcessor vv = ip.duplicate();
          ImageProcessor hv = ip.duplicate();
          float[] floatPixels = (float[]) ip.getPixels();
          float[] floatPixelsHH = (float[]) hh.getPixels();
          float[] floatPixelsVV = (float[]) vv.getPixels();
          float[] floatPixelsHV = (float[]) hv.getPixels();

          getHorizontalHessian(hh, FLT_EPSILON);
          getVerticalHessian(vv, FLT_EPSILON);
          getCrossHessian(hv, FLT_EPSILON);
          for (int y = 0, k = 0; (y < height); y++) {
            for (int x = 0; (x < width); x++, k++) {
              if (floatPixelsHV[k] < 0.0) {
                floatPixels[k] =
                    (float)
                        (-0.5
                            * Math.acos(
                                (floatPixelsHH[k] - floatPixelsVV[k])
                                    / Math.sqrt(
                                        4.0 * floatPixelsHV[k] * floatPixelsHV[k]
                                            + (floatPixelsHH[k] - floatPixelsVV[k])
                                                * (floatPixelsHH[k] - floatPixelsVV[k]))));
              } else {
                floatPixels[k] =
                    (float)
                        (0.5
                            * Math.acos(
                                (floatPixelsHH[k] - floatPixelsVV[k])
                                    / Math.sqrt(
                                        4.0 * floatPixelsHV[k] * floatPixelsHV[k]
                                            + (floatPixelsHH[k] - floatPixelsVV[k])
                                                * (floatPixelsHH[k] - floatPixelsVV[k]))));
              }
            }
            stepProgressBar();
          }
        }
        break;
      default:
        throw new IllegalArgumentException("Invalid operation");
    }
    ip.resetMinAndMax();
    imp.updateAndDraw();
  } /* end doIt */
예제 #25
0
  void Niblack(ImagePlus imp, int radius, double par1, double par2, boolean doIwhite) {
    // Niblack recommends K_VALUE = -0.2 for images with black foreground
    // objects, and K_VALUE = +0.2 for images with white foreground objects.
    //  Niblack W. (1986) "An introduction to Digital Image Processing" Prentice-Hall.
    // Ported to ImageJ plugin from E Celebi's fourier_0.8 routines
    // This version uses a circular local window, instead of a rectagular one

    ImagePlus Meanimp, Varimp;
    ImageProcessor ip = imp.getProcessor(), ipMean, ipVar;
    double k_value;
    int c_value = 0;

    byte object;
    byte backg;

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

    if (par1 != 0) {
      IJ.log("Niblack: changed k_value from :" + k_value + "  to:" + par1);
      k_value = par1;
    }

    if (par2 != 0) {
      IJ.log(
          "Niblack: changed c_value from :"
              + c_value
              + "  to:"
              + par2); // requested feature, not in original
      c_value = (int) par2;
    }

    Meanimp = duplicateImage(ip);
    ImageConverter ic = new ImageConverter(Meanimp);
    ic.convertToGray32();

    ipMean = Meanimp.getProcessor();
    RankFilters rf = new RankFilters();
    rf.rank(ipMean, radius, rf.MEAN); // Mean
    // Meanimp.show();
    Varimp = duplicateImage(ip);
    ic = new ImageConverter(Varimp);
    ic.convertToGray32();
    ipVar = Varimp.getProcessor();
    rf.rank(ipVar, radius, rf.VARIANCE); // Variance
    // Varimp.show();
    byte[] pixels = (byte[]) ip.getPixels();
    float[] mean = (float[]) ipMean.getPixels();
    float[] var = (float[]) ipVar.getPixels();

    for (int i = 0; i < pixels.length; i++)
      pixels[i] =
          ((int) (pixels[i] & 0xff) > (int) (mean[i] + k_value * Math.sqrt(var[i]) - c_value))
              ? object
              : backg;
    // imp.updateAndDraw();
    return;
  }
예제 #26
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");        }      
  void sauvegarde(
      int v1[],
      double v2[],
      double s[],
      double s2[],
      double xg[],
      double yg[],
      double zg[],
      double[][] J,
      double[][][] dir,
      int n,
      byte[] bord,
      double[][] lmin,
      double[][] lmax,
      String directory,
      String name) {
    double sp;

    PrintWriter pw = null;
    try {
      FileOutputStream fos = new FileOutputStream(directory + name);
      BufferedOutputStream bos = new BufferedOutputStream(fos);
      pw = new PrintWriter(bos);
    } catch (IOException e) {
      return;
    }

    pw.println(
        "nb xg yg zg volpix volmarch surfacemarch surfacemarchnb sphericity I1 I2 I3 vI1x vI1y vI1z  vI2x vI2y vI2z  vI3x vI3y vI3z a b c Fab Fac Fbc xmin xmax ymin ymax zmin zmax dx dy dz border");

    for (int i = 0; i < n; i++) {
      pw.print(i + 1);
      pw.print(" ");
      pw.print(xg[i]);
      pw.print(" ");
      pw.print(yg[i]);
      pw.print(" ");
      pw.print(zg[i]);
      pw.print(" ");
      pw.print(v1[i]);
      pw.print(" ");
      pw.print(v2[i]);
      pw.print(" ");
      pw.print(s[i]);
      pw.print(" ");
      pw.print(s2[i]);
      sp = 6 * v2[i] * Math.sqrt(3.14159265 / (s2[i] * s2[i] * s2[i]));
      pw.print(" ");
      pw.print(sp);
      pw.print(" ");
      pw.print(J[0][i]);
      pw.print(" ");
      pw.print(J[1][i]);
      pw.print(" ");
      pw.print(J[2][i]);
      pw.print(" ");
      pw.print(dir[0][0][i]);
      pw.print(" ");
      pw.print(dir[1][0][i]);
      pw.print(" ");
      pw.print(dir[2][0][i]);
      pw.print(" ");
      pw.print(dir[0][1][i]);
      pw.print(" ");
      pw.print(dir[1][1][i]);
      pw.print(" ");
      pw.print(dir[2][1][i]);
      pw.print(" ");
      pw.print(dir[0][2][i]);
      pw.print(" ");
      pw.print(dir[1][2][i]);
      pw.print(" ");
      pw.print(dir[2][2][i]);
      pw.print(" ");
      double ma = (J[0][i] + J[1][i] - J[2][i]);
      double mb = (J[0][i] - J[1][i] + J[2][i]);
      double mc = (-J[0][i] + J[1][i] + J[2][i]);
      double b1 = (3 * mb * mb / (16 * Math.sqrt(ma * mc)));
      b1 = Math.pow(b1, 0.2);
      double a = b1 * Math.sqrt(ma / mb);
      double b = b1;
      double c = b * Math.sqrt(mc / mb);
      double Fab = Math.sqrt((J[0][i] + J[1][i] - J[2][i]) / (J[0][i] - J[1][i] + J[2][i]));
      double Fac = Math.sqrt((J[0][i] + J[1][i] - J[2][i]) / (-J[0][i] + J[1][i] + J[2][i]));
      double Fbc = Math.sqrt((J[0][i] - J[1][i] + J[2][i]) / (-J[0][i] + J[1][i] + J[2][i]));
      pw.print(a);
      pw.print(" ");
      pw.print(b);
      pw.print(" ");
      pw.print(c);
      pw.print(" ");
      pw.print(Fab);
      pw.print(" ");
      pw.print(Fac);
      pw.print(" ");
      pw.print(Fbc);
      pw.print(" ");
      pw.print(lmin[i][0] - 0.5);
      pw.print(" ");
      pw.print(lmax[i][0] + 0.5);
      pw.print(" ");
      pw.print(lmin[i][1] - 0.5);
      pw.print(" ");
      pw.print(lmax[i][1] + 0.5);
      pw.print(" ");
      pw.print(lmin[i][2] - 0.5);
      pw.print(" ");
      pw.print(lmax[i][2] + 0.5);
      pw.print(" ");
      double dx = lmax[i][0] - lmin[i][0] + 1;
      double dy = lmax[i][1] - lmin[i][1] + 1;
      double dz = lmax[i][2] - lmin[i][2] + 1;
      double a1 = dx;
      if (dy < a1) a1 = dy;
      if (dz < a1) a1 = dz;

      double a3 = dx;
      if (dy > a3) a3 = dy;
      if (dz > a3) a3 = dz;
      double a2 = dx;

      if (dx != a1 && dx != a3) a2 = dx;
      if (dy != a1 && dy != a3) a2 = dy;
      if (dz != a1 && dz != a3) a2 = dz;

      pw.print(" ");
      pw.print(a1);
      pw.print(" ");
      pw.print(a2);
      pw.print(" ");
      pw.print(a3);
      pw.print(" ");
      pw.println(bord[i]);
    }
    pw.close();
  }