/** Frees memory by deleting a few slices from the end of the stack. */ public void trim() { int n = (int) Math.round(Math.log(nSlices) + 1.0); for (int i = 0; i < n; i++) { deleteLastSlice(); System.gc(); } }
void createEllipse(ImagePlus imp) { IJ.showStatus("Fitting ellipse"); Roi roi = imp.getRoi(); if (roi == null) { noRoi("Fit Ellipse"); return; } if (roi.isLine()) { IJ.error("Fit Ellipse", "\"Fit Ellipse\" does not work with line selections"); return; } ImageProcessor ip = imp.getProcessor(); ip.setRoi(roi); int options = Measurements.CENTROID + Measurements.ELLIPSE; ImageStatistics stats = ImageStatistics.getStatistics(ip, options, null); double dx = stats.major * Math.cos(stats.angle / 180.0 * Math.PI) / 2.0; double dy = -stats.major * Math.sin(stats.angle / 180.0 * Math.PI) / 2.0; double x1 = stats.xCentroid - dx; double x2 = stats.xCentroid + dx; double y1 = stats.yCentroid - dy; double y2 = stats.yCentroid + dy; double aspectRatio = stats.minor / stats.major; imp.killRoi(); imp.setRoi(new EllipseRoi(x1, y1, x2, y2, aspectRatio)); }
public void fitSpline(int evaluationPoints) { if (xpf == null) { xpf = toFloat(xp); ypf = toFloat(yp); subPixel = true; } if (xSpline == null || splinePoints != evaluationPoints) { splinePoints = evaluationPoints; xSpline = new float[splinePoints]; ySpline = new float[splinePoints]; } int nNodes = nPoints; if (type == POLYGON) { nNodes++; if (nNodes >= xpf.length) enlargeArrays(); xpf[nNodes - 1] = xpf[0]; ypf[nNodes - 1] = ypf[0]; } float[] xindex = new float[nNodes]; for (int i = 0; i < nNodes; i++) xindex[i] = i; SplineFitter sfx = new SplineFitter(xindex, xpf, nNodes); SplineFitter sfy = new SplineFitter(xindex, ypf, nNodes); // Evaluate the splines at all points double scale = (double) (nNodes - 1) / (splinePoints - 1); float xs = 0f, ys = 0f; float xmin = Float.MAX_VALUE, xmax = -xmin, ymin = xmin, ymax = xmax; for (int i = 0; i < splinePoints; i++) { double xvalue = i * scale; xs = (float) sfx.evalSpline(xindex, xpf, nNodes, xvalue); if (xs < xmin) xmin = xs; if (xs > xmax) xmax = xs; xSpline[i] = xs; ys = (float) sfy.evalSpline(xindex, ypf, nNodes, xvalue); if (ys < ymin) ymin = ys; if (ys > ymax) ymax = ys; ySpline[i] = ys; } int ixmin = (int) Math.floor(xmin + 0.5f); int ixmax = (int) Math.floor(xmax + 0.5f); int iymin = (int) Math.floor(ymin + 0.5f); int iymax = (int) Math.floor(ymax + 0.5f); if (ixmin != 0) { for (int i = 0; i < nPoints; i++) xpf[i] -= ixmin; for (int i = 0; i < splinePoints; i++) xSpline[i] -= ixmin; } if (iymin != 0) { for (int i = 0; i < nPoints; i++) ypf[i] -= iymin; for (int i = 0; i < splinePoints; i++) ySpline[i] -= iymin; } x += ixmin; y += iymin; width = ixmax - ixmin; height = iymax - iymin; bounds = null; cachedMask = null; // update protected xp and yp arrays for backward compatibility xp = toInt(xpf, xp, nPoints); yp = toInt(ypf, yp, nPoints); }
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]); } }
/** * Zooms out by making the source rectangle (srcRect) larger and centering it on (x,y). If we * can't make it larger, then make the window smaller. */ public void zoomOut(int x, int y) { if (magnification <= 0.03125) return; double oldMag = magnification; double newMag = getLowerZoomLevel(magnification); double srcRatio = (double) srcRect.width / srcRect.height; double imageRatio = (double) imageWidth / imageHeight; double initialMag = imp.getWindow().getInitialMagnification(); if (Math.abs(srcRatio - imageRatio) > 0.05) { double scale = oldMag / newMag; int newSrcWidth = (int) Math.round(srcRect.width * scale); int newSrcHeight = (int) Math.round(srcRect.height * scale); if (newSrcWidth > imageWidth) newSrcWidth = imageWidth; if (newSrcHeight > imageHeight) newSrcHeight = imageHeight; int newSrcX = srcRect.x - (newSrcWidth - srcRect.width) / 2; int newSrcY = srcRect.y - (newSrcHeight - srcRect.height) / 2; if (newSrcX < 0) newSrcX = 0; if (newSrcY < 0) newSrcY = 0; srcRect = new Rectangle(newSrcX, newSrcY, newSrcWidth, newSrcHeight); // IJ.log(newMag+" "+srcRect+" "+dstWidth+" "+dstHeight); int newDstWidth = (int) (srcRect.width * newMag); int newDstHeight = (int) (srcRect.height * newMag); setMagnification(newMag); setMaxBounds(); // IJ.log(newDstWidth+" "+dstWidth+" "+newDstHeight+" "+dstHeight); if (newDstWidth < dstWidth || newDstHeight < dstHeight) { // IJ.log("pack"); setDrawingSize(newDstWidth, newDstHeight); imp.getWindow().pack(); } else repaint(); return; } if (imageWidth * newMag > dstWidth) { int w = (int) Math.round(dstWidth / newMag); if (w * newMag < dstWidth) w++; int h = (int) Math.round(dstHeight / newMag); if (h * newMag < dstHeight) h++; x = offScreenX(x); y = offScreenY(y); Rectangle r = new Rectangle(x - w / 2, y - h / 2, w, h); if (r.x < 0) r.x = 0; if (r.y < 0) r.y = 0; if (r.x + w > imageWidth) r.x = imageWidth - w; if (r.y + h > imageHeight) r.y = imageHeight - h; srcRect = r; } else { srcRect = new Rectangle(0, 0, imageWidth, imageHeight); setDrawingSize((int) (imageWidth * newMag), (int) (imageHeight * newMag)); // setDrawingSize(dstWidth/2, dstHeight/2); imp.getWindow().pack(); } // IJ.write(newMag + " " + srcRect.x+" "+srcRect.y+" "+srcRect.width+" "+srcRect.height+" // "+dstWidth + " " + dstHeight); setMagnification(newMag); // IJ.write(srcRect.x + " " + srcRect.width + " " + dstWidth); setMaxBounds(); repaint(); }
double rodbard(double x) { // y = c*((a-x/(x-d))^(1/b) // a=3.9, b=.88, c=712, d=44 double ex; if (x == 0.0) ex = 5.0; else ex = Math.exp(Math.log(x / 700.0) * 0.88); double y = 3.9 - 44.0; y = y / (1.0 + ex); return y + 44.0; }
/* 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; }
String getAngleAsString() { double angle1 = 0.0; double angle2 = 0.0; if (xpf != null) { angle1 = getFloatAngle(xpf[0], ypf[0], xpf[1], ypf[1]); angle2 = getFloatAngle(xpf[1], ypf[1], xpf[2], ypf[2]); } else { angle1 = getFloatAngle(xp[0], yp[0], xp[1], yp[1]); angle2 = getFloatAngle(xp[1], yp[1], xp[2], yp[2]); } degrees = Math.abs(180 - Math.abs(angle1 - angle2)); if (degrees > 180.0) degrees = 360.0 - degrees; double degrees2 = Prefs.reflexAngle && type == ANGLE ? 360.0 - degrees : degrees; return ", angle=" + IJ.d2s(degrees2); }
void drawRoiLabel(Graphics g, int index, Roi roi) { Rectangle r = roi.getBounds(); int x = screenX(r.x); int y = screenY(r.y); double mag = getMagnification(); int width = (int) (r.width * mag); int height = (int) (r.height * mag); int size = width > 40 && height > 40 ? 12 : 9; if (font != null) { g.setFont(font); size = font.getSize(); } else if (size == 12) g.setFont(largeFont); else g.setFont(smallFont); boolean drawingList = index >= LIST_OFFSET; if (drawingList) index -= LIST_OFFSET; String label = "" + (index + 1); if (drawNames && roi.getName() != null) label = roi.getName(); FontMetrics metrics = g.getFontMetrics(); int w = metrics.stringWidth(label); x = x + width / 2 - w / 2; y = y + height / 2 + Math.max(size / 2, 6); int h = metrics.getAscent() + metrics.getDescent(); if (bgColor != null) { g.setColor(bgColor); g.fillRoundRect(x - 1, y - h + 2, w + 1, h - 3, 5, 5); } if (!drawingList && labelRects != null && index < labelRects.length) labelRects[index] = new Rectangle(x - 1, y - h + 2, w + 1, h); g.setColor(labelColor); g.drawString(label, x, y - 2); g.setColor(defaultColor); }
void Contrast(ImagePlus imp, int radius, double par1, double par2, boolean doIwhite) { // G. Landini, 2013 // Based on a simple contrast toggle. This procedure does not have user-provided paramters other // than the kernel radius // Sets the pixel value to either white or black depending on whether its current value is // closest to the local Max or Min respectively // The procedure is similar to Toggle Contrast Enhancement (see Soille, Morphological Image // Analysis (2004), p. 259 ImagePlus Maximp, Minimp; ImageProcessor ip = imp.getProcessor(), ipMax, ipMin; int c_value = 0; int mid_gray; byte object; byte backg; if (doIwhite) { object = (byte) 0xff; backg = (byte) 0; } else { object = (byte) 0; backg = (byte) 0xff; } Maximp = duplicateImage(ip); ipMax = Maximp.getProcessor(); RankFilters rf = new RankFilters(); rf.rank(ipMax, radius, rf.MAX); // Maximum // Maximp.show(); Minimp = duplicateImage(ip); ipMin = Minimp.getProcessor(); rf.rank(ipMin, radius, rf.MIN); // Minimum // Minimp.show(); byte[] pixels = (byte[]) ip.getPixels(); byte[] max = (byte[]) ipMax.getPixels(); byte[] min = (byte[]) ipMin.getPixels(); for (int i = 0; i < pixels.length; i++) { pixels[i] = ((Math.abs((int) (max[i] & 0xff - pixels[i] & 0xff)) <= Math.abs((int) (pixels[i] & 0xff - min[i] & 0xff)))) ? object : backg; } // imp.updateAndDraw(); return; }
void adjustSourceRect(double newMag, int x, int y) { // IJ.log("adjustSourceRect1: "+newMag+" "+dstWidth+" "+dstHeight); int w = (int) Math.round(dstWidth / newMag); if (w * newMag < dstWidth) w++; int h = (int) Math.round(dstHeight / newMag); if (h * newMag < dstHeight) h++; x = offScreenX(x); y = offScreenY(y); Rectangle r = new Rectangle(x - w / 2, y - h / 2, w, h); if (r.x < 0) r.x = 0; if (r.y < 0) r.y = 0; if (r.x + w > imageWidth) r.x = imageWidth - w; if (r.y + h > imageHeight) r.y = imageHeight - h; srcRect = r; setMagnification(newMag); // IJ.log("adjustSourceRect2: "+srcRect+" "+dstWidth+" "+dstHeight); }
int[] smooth(int[] a, int n) { FloatProcessor fp = new FloatProcessor(n, 1); for (int i = 0; i < n; i++) fp.putPixelValue(i, 0, a[i]); GaussianBlur gb = new GaussianBlur(); gb.blur1Direction(fp, 2.0, 0.01, true, 0); for (int i = 0; i < n; i++) a[i] = (int) Math.round(fp.getPixelValue(i, 0)); return a; }
/*------------------------------------------------------------------*/ double getInitialCausalCoefficientMirrorOnBounds(double[] c, double z, double tolerance) { double z1 = z, zn = Math.pow(z, c.length - 1); double sum = c[0] + zn * c[c.length - 1]; int horizon = c.length; if (0.0 < tolerance) { horizon = 2 + (int) (Math.log(tolerance) / Math.log(Math.abs(z))); horizon = (horizon < c.length) ? (horizon) : (c.length); } zn = zn * zn; for (int n = 1; (n < (horizon - 1)); n++) { zn = zn / z; sum = sum + (z1 + zn) * c[n]; z1 = z1 * z; } return (sum / (1.0 - Math.pow(z, 2 * c.length - 2))); } /* end getInitialCausalCoefficientMirrorOnBounds */
/** * 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))); }
/** Draws an outline of this OvalRoi on the image. */ public void drawPixels(ImageProcessor ip) { Polygon p = getPolygon(); if (p.npoints > 0) { int saveWidth = ip.getLineWidth(); if (getStrokeWidth() > 1f) ip.setLineWidth((int) Math.round(getStrokeWidth())); ip.drawPolygon(p); ip.setLineWidth(saveWidth); } if (Line.getWidth() > 1 || getStrokeWidth() > 1) updateFullWindow = true; }
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; } }
public void run(String arg) { int[] wList = WindowManager.getIDList(); if (wList == null) { IJ.error("No images are open."); return; } double thalf = 0.5; boolean keep; GenericDialog gd = new GenericDialog("Bleach correction"); gd.addNumericField("t½:", thalf, 1); gd.addCheckbox("Keep source stack:", true); gd.showDialog(); if (gd.wasCanceled()) return; long start = System.currentTimeMillis(); thalf = gd.getNextNumber(); keep = gd.getNextBoolean(); if (keep) IJ.run("Duplicate...", "title='Bleach corrected' duplicate"); ImagePlus imp1 = WindowManager.getCurrentImage(); int d1 = imp1.getStackSize(); double v1, v2; int width = imp1.getWidth(); int height = imp1.getHeight(); ImageProcessor ip1, ip2, ip3; int slices = imp1.getStackSize(); ImageStack stack1 = imp1.getStack(); ImageStack stack2 = imp1.getStack(); int currentSlice = imp1.getCurrentSlice(); for (int n = 1; n <= slices; n++) { ip1 = stack1.getProcessor(n); ip3 = stack1.getProcessor(1); ip2 = stack2.getProcessor(n); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { v1 = ip1.getPixelValue(x, y); v2 = ip3.getPixelValue(x, y); // =B8/(EXP(-C$7*A8)) v1 = (v1 / Math.exp(-n * thalf)); ip2.putPixelValue(x, y, v1); } } IJ.showProgress((double) n / slices); IJ.showStatus(n + "/" + slices); } // stack2.show(); imp1.updateAndDraw(); }
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 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; }
void addSelection() { ImagePlus imp = IJ.getImage(); String macroOptions = Macro.getOptions(); if (macroOptions != null && IJ.macroRunning() && macroOptions.indexOf("remove") != -1) { imp.setOverlay(null); return; } Roi roi = imp.getRoi(); if (roi == null && imp.getOverlay() != null) { GenericDialog gd = new GenericDialog("No Selection"); gd.addMessage("\"Overlay>Add\" requires a selection."); gd.setInsets(15, 40, 0); gd.addCheckbox("Remove existing overlay", false); gd.showDialog(); if (gd.wasCanceled()) return; if (gd.getNextBoolean()) imp.setOverlay(null); return; } if (roi == null) { IJ.error("This command requires a selection."); return; } roi = (Roi) roi.clone(); if (roi.getStrokeColor() == null) roi.setStrokeColor(Toolbar.getForegroundColor()); int width = Line.getWidth(); Rectangle bounds = roi.getBounds(); boolean tooWide = width > Math.max(bounds.width, bounds.height) / 3.0; if (roi.getStroke() == null && width > 1 && !tooWide) roi.setStrokeWidth(Line.getWidth()); Overlay overlay = imp.getOverlay(); if (overlay != null && overlay.size() > 0 && !roi.isDrawingTool()) { Roi roi2 = overlay.get(overlay.size() - 1); if (roi.getStroke() == null) roi.setStrokeWidth(roi2.getStrokeWidth()); if (roi.getFillColor() == null) roi.setFillColor(roi2.getFillColor()); } boolean points = roi instanceof PointRoi && ((PolygonRoi) roi).getNCoordinates() > 1; if (points) roi.setStrokeColor(Color.red); if (!IJ.altKeyDown() && !(roi instanceof Arrow)) { RoiProperties rp = new RoiProperties("Add to Overlay", roi); if (!rp.showDialog()) return; } String name = roi.getName(); boolean newOverlay = name != null && name.equals("new-overlay"); if (overlay == null || newOverlay) overlay = new Overlay(); overlay.add(roi); imp.setOverlay(overlay); overlay2 = overlay; if (points || (roi instanceof ImageRoi) || (roi instanceof Arrow)) imp.killRoi(); Undo.setup(Undo.OVERLAY_ADDITION, imp); }
/* * 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; }
public void fitToWindow() { ImageWindow win = imp.getWindow(); if (win == null) return; Rectangle bounds = win.getBounds(); Insets insets = win.getInsets(); int sliderHeight = (win instanceof StackWindow) ? 20 : 0; double xmag = (double) (bounds.width - 10) / srcRect.width; double ymag = (double) (bounds.height - (10 + insets.top + sliderHeight)) / srcRect.height; setMagnification(Math.min(xmag, ymag)); int width = (int) (imageWidth * magnification); int height = (int) (imageHeight * magnification); if (width == dstWidth && height == dstHeight) return; srcRect = new Rectangle(0, 0, imageWidth, imageHeight); setDrawingSize(width, height); getParent().doLayout(); }
/** 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; }
byte[] read1bitImage(InputStream in) throws IOException { if (fi.compression == FileInfo.LZW) throw new IOException("ImageJ cannot open 1-bit LZW compressed TIFFs"); int scan = (int) Math.ceil(width / 8.0); int len = scan * height; byte[] buffer = new byte[len]; byte[] pixels = new byte[nPixels]; DataInputStream dis = new DataInputStream(in); dis.readFully(buffer); int value1, value2, offset, index; for (int y = 0; y < height; y++) { offset = y * scan; index = y * width; for (int x = 0; x < scan; x++) { value1 = buffer[offset + x] & 0xff; for (int i = 7; i >= 0; i--) { value2 = (value1 & (1 << i)) != 0 ? 255 : 0; if (index < pixels.length) pixels[index++] = (byte) value2; } } } return pixels; }
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; }
/*------------------------------------------------------------------*/ 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 */