Beispiel #1
0
 /**
  * Traces the boundary of the area with pixel values within 'tolerance' of the value of the pixel
  * at the starting location. 'tolerance' is in uncalibrated units. 'mode' can be FOUR_CONNECTED or
  * EIGHT_CONNECTED. Mode LEGACY_MODE is for compatibility with previous versions of ImageJ;
  * ignored if tolerance > 0. Mode bit THRESHOLDED_MODE for internal use only; it is set by
  * autoOutline with 'upper' and 'lower' arguments. When successful, npoints>0 and the boundary
  * points can be accessed in the public xpoints and ypoints fields.
  */
 public void autoOutline(int startX, int startY, double tolerance, int mode) {
   if (startX < 0 || startX >= width || startY < 0 || startY >= height) return;
   if (fpixels != null && Float.isNaN(getPixel(startX, startY))) return;
   exactPixelValue = tolerance == 0;
   boolean thresholdMode = (mode & THRESHOLDED_MODE) != 0;
   boolean legacyMode = (mode & LEGACY_MODE) != 0 && tolerance == 0;
   if (!thresholdMode) {
     double startValue = getPixel(startX, startY);
     lowerThreshold = (float) (startValue - tolerance);
     upperThreshold = (float) (startValue + tolerance);
   }
   int x = startX;
   int y = startY;
   int seedX; // the first inside pixel
   if (inside(x, y)) { // find a border when coming from inside
     seedX = x; // (seedX, startY) is an inside pixel
     do {
       x++;
     } while (inside(x, y));
   } else { // find a border when coming from outside (thresholded only)
     do {
       x++;
       if (x >= width) return; // no border found
     } while (!inside(x, y));
     seedX = x;
   }
   boolean fourConnected;
   if (legacyMode) fourConnected = !thresholdMode && !(isLine(x, y));
   else fourConnected = (mode & FOUR_CONNECTED) != 0;
   // now, we have a border between (x-1, y) and (x,y)
   boolean first = true;
   while (true) { // loop until we have not traced an inner hole
     boolean insideSelected = traceEdge(x, y, fourConnected);
     if (legacyMode) return; // in legacy mode, don't care what we have got
     if (insideSelected) { // not an inner hole
       if (first) return; // started at seed, so we got it (sucessful)
       if (xmin <= seedX) { // possibly the correct particle
         Polygon poly = new Polygon(xpoints, ypoints, npoints);
         if (poly.contains(seedX, startY)) return; // successful, particle contains seed
       }
     }
     first = false;
     // we have traced an inner hole or the wrong particle
     if (!inside(x, y))
       do {
         x++; // traverse the hole
         if (x > width) throw new RuntimeException("Wand Malfunction"); // should never happen
       } while (!inside(x, y));
     do {
       x++;
     } while (inside(x, y)); // retry here; maybe no inner hole any more
   }
 }
Beispiel #2
0
 public boolean contains(int x, int y) {
   if (!super.contains(x, y)) return false;
   if (xSpline != null) {
     FloatPolygon poly = new FloatPolygon(xSpline, ySpline, splinePoints);
     return poly.contains(x - this.x, y - this.y);
   } else if (xpf != null) {
     FloatPolygon poly = new FloatPolygon(xpf, ypf, nPoints);
     return poly.contains(x - this.x, y - this.y);
   } else {
     Polygon poly = new Polygon(xp, yp, nPoints);
     return poly.contains(x - this.x, y - this.y);
   }
 }
Beispiel #3
0
 void finishPolygon() {
   if (xpf != null) {
     FloatPolygon poly = new FloatPolygon(xpf, ypf, nPoints);
     Rectangle r = poly.getBounds();
     x = r.x;
     y = r.y;
     width = r.width;
     height = r.height;
     bounds = poly.getFloatBounds();
     float xbase = (float) bounds.getX();
     float ybase = (float) bounds.getY();
     for (int i = 0; i < nPoints; i++) {
       xpf[i] -= xbase;
       ypf[i] -= ybase;
     }
   } else {
     Polygon poly = new Polygon(xp, yp, nPoints);
     Rectangle r = poly.getBounds();
     x = r.x;
     y = r.y;
     width = r.width;
     height = r.height;
     for (int i = 0; i < nPoints; i++) {
       xp[i] = xp[i] - x;
       yp[i] = yp[i] - y;
     }
     bounds = null;
   }
   if (nPoints < 2
       || (!(type == FREELINE || type == POLYLINE || type == ANGLE)
           && (nPoints < 3 || width == 0 || height == 0))) {
     if (imp != null) imp.deleteRoi();
     if (type != POINT) return;
   }
   state = NORMAL;
   if (imp != null && !(type == TRACED_ROI)) imp.draw(x - 5, y - 5, width + 10, height + 10);
   oldX = x;
   oldY = y;
   oldWidth = width;
   oldHeight = height;
   if (Recorder.record
       && userCreated
       && (type == POLYGON
           || type == POLYLINE
           || type == ANGLE
           || (type == POINT && Recorder.scriptMode() && nPoints == 3)))
     Recorder.recordRoi(getPolygon(), type);
   if (type != POINT) modifyRoi();
   LineWidthAdjuster.update();
 }
 void analyzeParticle(int x, int y, ImagePlus imp, ImageProcessor ip) {
   // Wand wand = new Wand(ip);
   ImageProcessor ip2 = redirectIP != null ? redirectIP : ip;
   wand.autoOutline(x, y, level1, level2, wandMode);
   if (wand.npoints == 0) {
     IJ.log("wand error: " + x + " " + y);
     return;
   }
   Roi roi = new PolygonRoi(wand.xpoints, wand.ypoints, wand.npoints, roiType);
   Rectangle r = roi.getBounds();
   if (r.width > 1 && r.height > 1) {
     PolygonRoi proi = (PolygonRoi) roi;
     pf.setPolygon(proi.getXCoordinates(), proi.getYCoordinates(), proi.getNCoordinates());
     ip2.setMask(pf.getMask(r.width, r.height));
     if (floodFill) ff.particleAnalyzerFill(x, y, level1, level2, ip2.getMask(), r);
   }
   ip2.setRoi(r);
   ip.setValue(fillColor);
   ImageStatistics stats = getStatistics(ip2, measurements, calibration);
   boolean include = true;
   if (excludeEdgeParticles) {
     if (r.x == minX || r.y == minY || r.x + r.width == maxX || r.y + r.height == maxY)
       include = false;
     if (polygon != null) {
       Rectangle bounds = roi.getBounds();
       int x1 = bounds.x + wand.xpoints[wand.npoints - 1];
       int y1 = bounds.y + wand.ypoints[wand.npoints - 1];
       int x2, y2;
       for (int i = 0; i < wand.npoints; i++) {
         x2 = bounds.x + wand.xpoints[i];
         y2 = bounds.y + wand.ypoints[i];
         if (!polygon.contains(x2, y2)) {
           include = false;
           break;
         }
         if ((x1 == x2 && ip.getPixel(x1, y1 - 1) == fillColor)
             || (y1 == y2 && ip.getPixel(x1 - 1, y1) == fillColor)) {
           include = false;
           break;
         }
         x1 = x2;
         y1 = y2;
       }
     }
   }
   ImageProcessor mask = ip2.getMask();
   if (minCircularity > 0.0 || maxCircularity < 1.0) {
     double perimeter = roi.getLength();
     double circularity =
         perimeter == 0.0 ? 0.0 : 4.0 * Math.PI * (stats.pixelCount / (perimeter * perimeter));
     if (circularity > 1.0) circularity = 1.0;
     // IJ.log(circularity+"	"+perimeter+"  "+stats.area);
     if (circularity < minCircularity || circularity > maxCircularity) include = false;
   }
   if (stats.pixelCount >= minSize && stats.pixelCount <= maxSize && include) {
     particleCount++;
     if (roiNeedsImage) roi.setImage(imp);
     stats.xstart = x;
     stats.ystart = y;
     saveResults(stats, roi);
     if (showChoice != NOTHING) drawParticle(drawIP, roi, stats, mask);
   }
   if (redirectIP != null) ip.setRoi(r);
   ip.fill(mask);
 }