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]); } }
/* 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; }
/** * 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))); }
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); }
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; }
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; } }
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; }
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; }
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; }
/* * 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; }
/** 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; }
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; }
/*------------------------------------------------------------------*/ 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 */
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; }
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; }
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]); } }
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]); }
/** * 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; }
/** * 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; }
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; } } }
/* 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)); }
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(); }
/*------------------------------------------------------------------*/ 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 */
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; }
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(); }