Пример #1
0
  public boolean hasChanges(Mat current) {
    int PIXEL_DIFF_THRESHOLD = 5;
    int IMAGE_DIFF_THRESHOLD = 5;
    Mat bg = new Mat();
    Mat cg = new Mat();
    Mat diff = new Mat();
    Mat tdiff = new Mat();

    Imgproc.cvtColor(base, bg, Imgproc.COLOR_BGR2GRAY);
    Imgproc.cvtColor(current, cg, Imgproc.COLOR_BGR2GRAY);
    Core.absdiff(bg, cg, diff);
    Imgproc.threshold(diff, tdiff, PIXEL_DIFF_THRESHOLD, 0.0, Imgproc.THRESH_TOZERO);
    if (Core.countNonZero(tdiff) <= IMAGE_DIFF_THRESHOLD) {
      return false;
    }

    Imgproc.threshold(diff, diff, PIXEL_DIFF_THRESHOLD, 255, Imgproc.THRESH_BINARY);
    Imgproc.dilate(diff, diff, new Mat());
    Mat se = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, new Size(5, 5));
    Imgproc.morphologyEx(diff, diff, Imgproc.MORPH_CLOSE, se);

    List<MatOfPoint> points = new ArrayList<MatOfPoint>();
    Mat contours = new Mat();
    Imgproc.findContours(diff, points, contours, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    int n = 0;
    for (Mat pm : points) {
      log(lvl, "(%d) %s", n++, pm);
      printMatI(pm);
    }
    log(lvl, "contours: %s", contours);
    printMatI(contours);
    return true;
  }
Пример #2
0
  /**
   * Finds and extracts all contours in the given Mat. Optionally also removes contours with areas
   * below that of MIN_CONTOUR_AREA.
   *
   * @param mask A mask of all resistors in the image
   * @param originalImage The original image from which the mask was created
   * @param thresholdByArea If true, remove contours below threshold
   * @return The list a found contours
   */
  private List<MatOfPoint> getContours(Mat mask, Mat originalImage, boolean thresholdByArea) {
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(
        mask,
        contours,
        hierarchy,
        Imgproc.RETR_EXTERNAL,
        Imgproc.CHAIN_APPROX_SIMPLE,
        new Point(0, 0));

    // remove any remaining noise by only keeping contours which area > threshold
    if (thresholdByArea) {
      for (int i = 0; i < contours.size(); i++) {
        double area = Imgproc.contourArea(contours.get(i));
        if (area < MIN_CONTOUR_AREA || area > 6000) {
          contours.remove(i);
          i--;
        }
      }
    }

    Mat drawing = Mat.zeros(originalImage.size(), CvType.CV_8U);

    for (int i = 0; i < contours.size(); i++) {
      Scalar color = new Scalar(255, 255, 255);
      Imgproc.drawContours(drawing, contours, i, color, 4, 8, hierarchy, 0, new Point());
    }
    paintBR(drawing);

    return contours;
  }
Пример #3
0
  /**
   * Locate rectangles in an image
   *
   * @param grayImage Grayscale image
   * @return Rectangle locations
   */
  public RectangleLocationResult locateRectangles(Mat grayImage) {
    Mat gray = grayImage.clone();

    // Filter out some noise
    Filter.downsample(gray, 2);
    Filter.upsample(gray, 2);

    Mat cacheHierarchy = new Mat();
    Mat grayTemp = new Mat();
    List<Rectangle> rectangles = new ArrayList<>();
    List<Contour> contours = new ArrayList<>();

    Imgproc.Canny(gray, grayTemp, 0, THRESHOLD_CANNY, APERTURE_CANNY, true);
    Filter.dilate(gray, 2);

    List<MatOfPoint> contoursTemp = new ArrayList<>();
    // Find contours - the parameters here are very important to compression and retention
    Imgproc.findContours(
        grayTemp, contoursTemp, cacheHierarchy, Imgproc.CV_RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    // For each contour, test whether the contour is a rectangle
    // List<Contour> contours = new ArrayList<>();
    MatOfPoint2f approx = new MatOfPoint2f();
    for (MatOfPoint co : contoursTemp) {
      MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray());
      Contour c = new Contour(co);

      // Attempt to fit the contour to the best polygon
      Imgproc.approxPolyDP(
          matOfPoint2f, approx, c.arcLength(true) * EPLISON_APPROX_TOLERANCE_FACTOR, true);

      Contour approxContour = new Contour(approx);

      // Make sure the contour is big enough, CLOSED (convex), and has exactly 4 points
      if (approx.toArray().length == 4
          && Math.abs(approxContour.area()) > 1000
          && approxContour.isClosed()) {

        // TODO contours and rectangles array may not match up, but why would they?
        contours.add(approxContour);

        // Check each angle to be approximately 90 degrees
        double maxCosine = 0;
        for (int j = 2; j < 5; j++) {
          double cosine =
              Math.abs(
                  MathUtil.angle(
                      approx.toArray()[j % 4], approx.toArray()[j - 2], approx.toArray()[j - 1]));
          maxCosine = Math.max(maxCosine, cosine);
        }

        if (maxCosine < MAX_COSINE_VALUE) {
          // Convert the points to a rectangle instance
          rectangles.add(new Rectangle(approx.toArray()));
        }
      }
    }

    return new RectangleLocationResult(contours, rectangles);
  }
Пример #4
0
  private static Mat findLargestRectangle(Mat original_image) {
    Mat imgSource = original_image.clone();

    // convert the image to black and white
    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);

    // convert the image to black and white does (8 bit)
    Imgproc.Canny(imgSource, imgSource, 50, 50);

    // apply gaussian blur to smoothen lines of dots
    Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 5);

    // find the contours
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(
        imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    double maxArea = -1;
    MatOfPoint temp_contour = contours.get(0); // the largest is at the
    // index 0 for starting
    // point
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
    for (int idx = 0; idx < contours.size(); idx++) {
      temp_contour = contours.get(idx);
      double contourarea = Imgproc.contourArea(temp_contour);
      // compare this contour to the previous largest contour found
      if (contourarea > maxArea) {
        // check if this contour is a square
        MatOfPoint2f new_mat = new MatOfPoint2f(temp_contour.toArray());
        int contourSize = (int) temp_contour.total();
        Imgproc.approxPolyDP(new_mat, approxCurve, contourSize * 0.05, true);
        if (approxCurve.total() == 4) {
          maxArea = contourarea;
          largest_contours.add(temp_contour);
        }
      }
    }
    MatOfPoint temp_largest = largest_contours.get(largest_contours.size() - 1);
    largest_contours = new ArrayList<MatOfPoint>();

    largest_contours.add(temp_largest);

    // Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BayerBG2RGB);
    Imgproc.drawContours(original_image, largest_contours, -1, new Scalar(0, 255, 0), 10);

    // Mat perspectiveTransform = new Mat(3, 3, CvType.CV_32FC1);
    // Imgproc.warpPerspective(original_image, imgSource,
    // perspectiveTransform, new Size(300,300));

    Highgui.imwrite(output, original_image);

    // create the new image here using the largest detected square

    // Toast.makeText(getApplicationContext(), "Largest Contour: ",
    // Toast.LENGTH_LONG).show();

    return imgSource;
  }
  public static Mat getCCH(Mat image) {
    ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();
    Imgproc.findContours(
        image, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE);

    Mat chainHistogram = Mat.zeros(1, 8, CvType.CV_32F);
    int n = 0;
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    for (MatOfPoint contour : contours) {

      // get the freeman chain code from the contours
      int rows = contour.rows();
      // System.out.println("\nrows"+rows+"\n"+contour.dump());
      int direction = 7;
      Mat prevPoint = contours.get(0).row(0);
      n += rows - 1;
      for (int i = 1; i < rows; i++) {
        // get the current point
        double x1 = contour.get(i - 1, 0)[1];
        double y1 = contour.get(i - 1, 0)[0];

        // get the second point
        double x2 = contour.get(i, 0)[1];
        double y2 = contour.get(i, 0)[0];

        if (x2 == x1 && y2 == y1 + 1) direction = 0;
        else if (x2 == x1 - 1 && y2 == y1 + 1) direction = 1;
        else if (x2 == x1 - 1 && y2 == y1) direction = 2;
        else if (x2 == x1 - 1 && y2 == y1 - 1) direction = 3;
        else if (x2 == x1 && y2 == y1 - 1) direction = 4;
        else if (x2 == x1 + 1 && y2 == y1 - 1) direction = 5;
        else if (x2 == x1 + 1 && y2 == y1) direction = 6;
        else if (x2 == x1 + 1 && y2 == y1 + 1) direction = 7;
        else System.out.print("err");
        double counter = chainHistogram.get(0, direction)[0];
        chainHistogram.put(0, direction, ++counter);
        System.out.print(direction);
      }
    }
    System.out.println("\n" + chainHistogram.dump());
    Scalar alpha = new Scalar(n); // the factor
    Core.divide(chainHistogram, alpha, chainHistogram);
    System.out.println("\nrows=" + n + " " + chainHistogram.dump());
    return chainHistogram;
  }
  private boolean findMarkers(
      Mat imgMat, DtouchMarker marker, ArrayList<MatOfPoint> components, Mat hierarchy) {

    boolean markerFound = false;

    // holds all the markers identified in the camera.
    List<DtouchMarker> markersDetected = new ArrayList<DtouchMarker>();
    Mat contourImg = imgMat.clone();
    // Find blobs using connect component.
    Imgproc.findContours(
        contourImg, components, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_NONE);

    // No need to use contourImg so release it.
    contourImg.release();

    List<Integer> code = new ArrayList<Integer>();

    for (int i = 0; i < components.size(); i++) {
      // clean this list.
      code.clear();
      if (markerDetector.verifyRoot(i, hierarchy, code)) {
        // if marker found then add in the list.
        DtouchMarker markerDetected = new DtouchMarker();
        markerDetected.setCode(code);
        markerDetected.setComponentIndex(i);
        markersDetected.add(markerDetected);
      }
    }

    // if markers are found then decide which marker code occurred most.
    if (markersDetected.size() > 0) {
      DtouchMarker markerSelected = markerDetector.compareDetectedMarkers(markersDetected);
      if (markerSelected != null) {
        marker.setCode(markerSelected.getCode());
        marker.setComponentIndex(markerSelected.getComponentIndex());
        markerFound = true;
      }
    }

    return markerFound;
  }
  /**
   * calculates the center of mass using <code>colorForTrackingHSV</code> and <code>colorRadius
   * </code> as radius (in HSV-color space)
   *
   * @param hsv the frame of which the center of mass should be calculated off
   * @return the center of mass as a point in pixel coordinates (i.e. integer)
   */
  public Point calcCenterOfMass(Mat hsv) {
    blackWhiteMask = new Mat();
    Core.inRange(hsv, lowerBound, upperBound, blackWhiteMask);

    dilatedMask = new Mat();
    Imgproc.dilate(blackWhiteMask, dilatedMask, new Mat());

    contour = new ArrayList<MatOfPoint>();
    Mat mHierarchy = new Mat();
    Mat tempDilatedMask = dilatedMask.clone();
    Imgproc.findContours(
        tempDilatedMask, contour, mHierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    boundingRect = Imgproc.boundingRect(findLargestContour(contour));

    int centerOfMassX = boundingRect.x + boundingRect.width / 2;
    int centerOfMassY = boundingRect.y + boundingRect.height / 2;

    Point centerOfMass = new Point(centerOfMassX, centerOfMassY);
    trackPath.add(centerOfMass);
    return centerOfMass;
  }
Пример #8
0
  /**
   * Locate ellipses within an image
   *
   * @param grayImage Grayscale image
   * @return Ellipse locations
   */
  public EllipseLocationResult locateEllipses(Mat grayImage) {
    Mat gray = grayImage.clone();

    Filter.downsample(gray, 2);
    Filter.upsample(gray, 2);

    Imgproc.Canny(gray, gray, 5, 75, 3, true);
    Filter.dilate(gray, 2);

    Mat cacheHierarchy = new Mat();

    List<MatOfPoint> contoursTemp = new ArrayList<>();
    // Find contours - the parameters here are very important to compression and retention
    Imgproc.findContours(
        gray, contoursTemp, cacheHierarchy, Imgproc.CV_RETR_TREE, Imgproc.CHAIN_APPROX_TC89_KCOS);

    // List contours
    List<Contour> contours = new ArrayList<>();
    for (MatOfPoint co : contoursTemp) {
      contours.add(new Contour(co));
    }

    // Find ellipses by finding fit
    List<Ellipse> ellipses = new ArrayList<>();
    for (MatOfPoint co : contoursTemp) {
      contours.add(new Contour(co));
      // Contour must have at least 6 points for fitEllipse
      if (co.toArray().length < 6) continue;
      // Copy MatOfPoint to MatOfPoint2f
      MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray());
      // Fit an ellipse to the current contour
      Ellipse ellipse = new Ellipse(Imgproc.fitEllipse(matOfPoint2f));

      // Draw ellipse
      ellipses.add(ellipse);
    }

    return new EllipseLocationResult(contours, ellipses);
  }
Пример #9
0
  /**
   * Determines which pieces are kings
   *
   * @param in Mat image of board
   */
  public void determineKings(Mat in) {
    int playSquares = 32;

    Mat dst = new Mat(in.rows(), in.cols(), in.type());
    in.copyTo(dst);

    Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2GRAY); // change to single color

    Mat canny = new Mat();
    Imgproc.Canny(dst, canny, 100, 200); // make image a canny image that is only edges; 2,4
    // lower threshold values find more edges
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat(); // holds nested contour information
    Imgproc.findContours(
        canny,
        contours,
        hierarchy,
        Imgproc.RETR_LIST,
        Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE

    // draw contour image
    Mat mask = new Mat();
    mask = Mat.zeros(dst.size(), dst.type());
    Imgproc.drawContours(
        mask, contours, -1, new Scalar(255, 255, 255), 1, 8, hierarchy, 2, new Point());
    Highgui.imwrite("contours.jpg", mask);

    ArrayList occupied = new ArrayList<Integer>();
    for (int i = 0; i < playSquares; i++) {
      if (board[i] != 0) occupied.add(i);
    }

    for (int i = 0; i < contours.size(); i++) // assuming only contours are checker pieces
    {
      // determine if it should be a king
      // use Rect r = Imgproc.boundingRect then find height of it by r.height

      // Get bounding rect of contour
      Rect bound = Imgproc.boundingRect(contours.get(i));

      if (bound.height > in.rows() / 8) {
        // board[(int) occupied.get(0)]++; // make it a king
        // occupied.remove(0);
      }
    }

    // or apply to each region of interest

    /*
    // keep track of starting row square
    int parity = 0; // 0 is even, 1 is odd, tied to row number
    int count = 0; // row square
    int rowNum = 0; // row number, starting at 0

    int vsegment = in.rows() / 8; // only accounts 8 playable
    int hsegment = in.cols() / 12; // 8 playable, 2 capture, 2 extra
    int offset = hsegment * 2; // offset for playable board

    // For angle of camera
    int dx = 48;
    hsegment -= 8;


    // Go through all playable squares
    for (int i = 0; i < playSquares; i++)
    {
    	// change offset depending on the row
    	if (parity == 0) // playable squares start on immediate left
    		offset = hsegment * 3 + dx;
    	else // playable squares start on 2nd square from left
    		offset = hsegment * 2 + dx;

    	// find where roi should be
    	Point p1 = new Point(offset + count * hsegment, rowNum * vsegment); // top left point of rectangle (x,y)
    	Point p2 = new Point(offset + (count + 1) * hsegment, (rowNum + 1) * vsegment); // bottom right point of rectangle (x,y)

    	// create rectangle that is board square
    	Rect bound = new Rect(p1, p2);

    	// frame only includes rectangle
    	Mat roi = new Mat(in, bound);

           Imgproc.cvtColor(roi, roi, Imgproc.COLOR_BGR2GRAY); // change to single color

           Mat canny = new Mat();
           Imgproc.Canny(roi, canny, 2, 4); // make image a canny image that is only edges; 2,4
           // lower threshold values find more edges
           List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
           Mat hierarchy = new Mat(); // holds nested contour information
           Imgproc.findContours(canny, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE

           // Get bounding rect of contour
              Rect rect = Imgproc.boundingRect(contours.get(0));

              if (rect.height > in.rows() / 8)
    	{
    		board[i]++; // make it a king
    	}

    	count += 2;
    	if (count == 8)
    	{
    		parity = ++parity % 2; // change odd or even
    		count = 0;
    		rowNum++;
    		hsegment += 1;
    		dx -= 6;
    	}
    }*/
  }
Пример #10
0
  public static int identify_R_U(Mat binary) {
    // 0: hull points identified < 2
    // 1: R
    // 2: U
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    List<MatOfPoint> hullPoints = new ArrayList<MatOfPoint>();
    List<Point> hullPointList = new ArrayList<Point>();
    List<Point> filteredPointList = new ArrayList<Point>();
    MatOfPoint hullPointMat = new MatOfPoint();
    MatOfInt hull = new MatOfInt();
    Mat hierarchy = new Mat();

    // Find contour
    Imgproc.findContours(
        binary, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE);

    // Find convex hull
    for (int k = 0; k < contours.size(); k++) {
      Imgproc.convexHull(contours.get(k), hull);

      for (int j = 0; j < hull.toList().size(); j++) {
        hullPointList.add(contours.get(k).toList().get(hull.toList().get(j)));
      }

      hullPointMat.fromList(hullPointList);
      hullPoints.add(hullPointMat);
    }

    // Filter hull points. Only hull points relevant to hull classification
    // will remain.
    // Also, count the number of filtered hull points in left and right.
    for (int l = 0; l < hullPointList.size(); l++) {

      if (hullPointList.get(l).y < binary.rows() * 0.25) {

        if (l != hullPointList.size() - 1) {

          if (Math.hypot(
                      hullPointList.get(l).x - hullPointList.get(l + 1).x,
                      hullPointList.get(l).y - hullPointList.get(l + 1).y)
                  / binary.cols()
              > 0.08) {

            filteredPointList.add(hullPointList.get(l));
            // Core.circle(rgb,
            // new Point(UL.x + hullPointList.get(l).x, UL.y
            // + hullPointList.get(l).y), 5,
            // new Scalar(0, 255, 0));
          }
        }
      }
    }

    // Sort points by x axis, increasing
    if (filteredPointList.size() > 1) {
      if (filteredPointList.get(0).x > filteredPointList.get(1).x) {
        Point temp = filteredPointList.get(0);
        filteredPointList.set(0, filteredPointList.get(1));
        filteredPointList.set(1, temp);
      }

      if (filteredPointList.get(0).y > filteredPointList.get(1).y) return 1; // R
      else return 2; // U
    }

    return 0;
  }
  public Mat onCameraFrame(CvCameraViewFrame inputFrame) {
    mRgba = inputFrame.rgba();
    // convert to Gray scale
    Imgproc.cvtColor(mRgba, img_gray, Imgproc.COLOR_BGR2GRAY);
    // make it binary with threshold=100
    Imgproc.threshold(img_gray, erd, 100, 255, Imgproc.THRESH_OTSU);
    // remove pixel noise by "erode" with structuring element of 9X9
    Mat erode = Imgproc.getStructuringElement(Imgproc.MORPH_ERODE, new Size(9, 9));
    Imgproc.erode(erd, tgt, erode);
    // apply "dilation" to enlarge object
    Mat dilate = Imgproc.getStructuringElement(Imgproc.MORPH_DILATE, new Size(9, 9));
    Imgproc.dilate(tgt, erd, dilate);
    // take a window
    Size s = erd.size();
    int W = (int) s.width;
    int H = (int) s.height;
    Rect r = new Rect(0, H / 2 - 100, W, 200);
    Mat mask = new Mat(s, CvType.CV_8UC1, new Scalar(0, 0, 0));
    rectangle(mask, r.tl(), r.br(), new Scalar(255, 255, 255), -1);
    erd.copyTo(window, mask);

    // find the contours
    Imgproc.findContours(window, contours, dest, 0, 2);
    // find largest contour
    int maxContour = -1;
    double area = 0;
    for (int i = 0; i < contours.size(); i++) {
      double contArea = Imgproc.contourArea(contours.get(i));
      if (contArea > area) {
        area = contArea;
        maxContour = i;
      }
    }
    // form bounding rectangle for largest contour
    Rect rect = null;
    if (maxContour > -1) rect = Imgproc.boundingRect(contours.get(maxContour));
    // position to center
    while (!train) {
      if (rect != null) {
        Imgproc.rectangle(mRgba, rect.tl(), rect.br(), new Scalar(255, 255, 255), 5);
        if ((rect.x + rect.width / 2) > W / 2 - 20 && (rect.x + rect.width / 2) < W / 2 + 20) {
          runOnUiThread(
              new Runnable() {
                @Override
                public void run() {
                  Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_SHORT).show();
                }
              });
          train = true;
        }
      }
      if (contours != null) contours.clear();
      return mRgba;
    }
    if (train) {
      if (rect != null) {
        Imgproc.rectangle(mRgba, rect.tl(), rect.br(), new Scalar(255, 255, 255), 5);
        // direction of movement
        int thr = 100;
        if ((rect.x + rect.width / 2) < (W / 2 - thr)) {
          // move to the RIGHT
          uHandler.obtainMessage(MainActivity.LEFT).sendToTarget();
        } else {
          if ((rect.x + rect.width / 2) > (W / 2 + thr)) {
            uHandler.obtainMessage(MainActivity.RIGHT).sendToTarget();
          } else {
            uHandler.obtainMessage(MainActivity.FORWARD).sendToTarget();
          }
        }
      } else {
        // stop moving
        uHandler.obtainMessage(MainActivity.STOP).sendToTarget();
      }
    }
    if (contours != null) contours.clear();
    return mRgba;
  }
Пример #12
0
  public void processImage(Mat imageToProcess) {
    try {
      final Mat processedImage = imageToProcess.clone();
      // red
      final Mat redUpper = new Mat();
      final Mat redLower = new Mat();
      Core.inRange(processedImage, new Scalar(170, 100, 20), new Scalar(180, 255, 255), redUpper);
      Core.inRange(processedImage, new Scalar(0, 100, 20), new Scalar(20, 255, 255), redLower);
      Core.bitwise_or(redLower, redUpper, processedImage);

      // refining the binary image
      Imgproc.erode(processedImage, processedImage, new Mat(), new Point(-1, -1), 1);
      Imgproc.dilate(processedImage, processedImage, new Mat(), new Point(-1, -1), 0);

      // create a clone for the processedImage to be used in finding contours
      final Mat clone = processedImage.clone();
      Imgproc.cvtColor(processedImage, processedImage, Imgproc.COLOR_GRAY2RGB);

      // finds list of contours and draw the biggest on the processedImage
      final Scalar color1 = new Scalar(0, 0, 255);
      final Scalar color2 = new Scalar(255, 255, 0);
      final Scalar color3 = new Scalar(255, 255, 255);
      final List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
      Imgproc.findContours(
          clone, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_NONE);

      final List<MatOfPoint> contour = new ArrayList<MatOfPoint>(1);
      double maxArea = 0.0;
      for (int index = 0; index < contours.size(); index++) {
        double area = Imgproc.contourArea(contours.get(index));
        if (area > maxArea && area > 25 && Imgproc.boundingRect(contours.get(index)).y > 40) {
          maxArea = area;
          contour.add(0, contours.get(index));
        }
      }
      // finds bounding Rectangle and draws contours
      Rect boundingRect = new Rect();
      if (contour.size() > 0) {
        Imgproc.drawContours(processedImage, contour, -2, color1);
        boundingRect = Imgproc.boundingRect(contour.get(0));
        final double x = boundingRect.x;
        final double y = boundingRect.y;
        final double width = boundingRect.width;
        final double height = boundingRect.height;
        Core.rectangle(processedImage, new Point(x, y), new Point(x + width, y + height), color3);
      }
      // finding bounding Circle and draws it
      final Point center = new Point();
      final float[] radius = new float[1];
      if (contour.size() > 0) {
        final MatOfPoint2f contour2f = new MatOfPoint2f(contour.get(0).toArray());
        Imgproc.minEnclosingCircle(contour2f, center, radius);
        Core.circle(processedImage, center, (int) radius[0], color2);
      }

      final BallStruct redBallStruct = new BallStruct(boundingRect, center, (double) radius[0]);
      final BallTargeting ballTargeting = new BallTargeting(redBallStruct);

      synchronized (this) {
        distanceToRed = ballTargeting.getDistance();
        angleToRedInDegrees = ballTargeting.getAngle() * (180 / Math.PI);
        this.processedImage = processedImage;
      }
    } catch (Exception e) {

    }
  }
  public void process(Mat rgbaImage) {
    Mat pyrDownMat = new Mat();

    Imgproc.pyrDown(rgbaImage, pyrDownMat);
    Imgproc.pyrDown(pyrDownMat, pyrDownMat);

    Mat hsvMat = new Mat();
    Imgproc.cvtColor(pyrDownMat, hsvMat, Imgproc.COLOR_RGB2HSV_FULL);

    Mat Mask = new Mat();
    Core.inRange(hsvMat, mLowerBound, mUpperBound, Mask);
    Mat dilatedMask = new Mat();
    Imgproc.dilate(Mask, dilatedMask, new Mat());

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Mat hierarchy = new Mat();

    Imgproc.findContours(
        dilatedMask, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);

    blobCenters[0] = new Point();
    blobCenters[1] = new Point();

    if (contours.size() > 0) {

      // Find max contour area of the two biggest
      double[] maxArea = new double[2];
      maxArea[0] = 0; // biggest
      maxArea[1] = 0; // 2nd biggest
      Iterator<MatOfPoint> each = contours.iterator();
      int[] contourIndex = new int[2];
      contourIndex[0] = 0;
      contourIndex[1] = 0;
      int index = 0;
      while (each.hasNext()) {
        MatOfPoint wrapper = each.next();
        double area = Imgproc.contourArea(wrapper);
        if (area > maxArea[0]) { // area bigger than the maximum found
          maxArea[1] = maxArea[0];
          contourIndex[1] = contourIndex[0];
          maxArea[0] = area;
          contourIndex[0] = index;
        } else if (area > maxArea[1]) { // area bigger than the second maximum found
          maxArea[1] = area;
          contourIndex[1] = index;
        }
        index++;
      }

      //        // another possibility to iterate through contours
      //        for (index = 0; index < contours.size(); index++) {
      //            d = Imgproc.contourArea (contours.get(index));

      Log.d("index0", Integer.toString(contourIndex[0]));
      Log.d("index1", Integer.toString(contourIndex[1]));

      MatOfPoint2f mMOP2f1 = new MatOfPoint2f();
      float[] radius = new float[contours.size()];

      // contours is a List<MatOfPoint>
      // so contours.get(x) is a single MatOfPoint
      // but to use approxPolyDP we need to pass a MatOfPoint2f
      // so we need to do a conversion

      contours.get(contourIndex[0]).convertTo(mMOP2f1, CvType.CV_32FC2);
      // get the center of the bigger contour found
      Point tempCenter = new Point();
      Imgproc.minEnclosingCircle(mMOP2f1, tempCenter, radius);
      blobCenters[0].x = tempCenter.x;
      blobCenters[0].y = tempCenter.y;
      blobRadius[0] = radius[0];

      Log.d("center0.x", Double.toString(blobCenters[0].x));
      Log.d("center0.y", Double.toString(blobCenters[0].y));
      Log.d("radius0", Double.toString(blobRadius[0]));

      contours.get(contourIndex[1]).convertTo(mMOP2f1, CvType.CV_32FC2);
      Imgproc.minEnclosingCircle(mMOP2f1, tempCenter, radius);
      blobCenters[1].x = tempCenter.x;
      blobCenters[1].y = tempCenter.y;
      blobRadius[1] = radius[0];

      Log.d("center1.x", Double.toString(blobCenters[1].x));
      Log.d("center1.y", Double.toString(blobCenters[1].y));
      Log.d("radius1", Double.toString(blobRadius[1]));

      // Filter contours by area and resize to fit the original image size
      mContours.clear();
      each = contours.iterator();
      while (each.hasNext()) {
        MatOfPoint contour = each.next();
        if (Imgproc.contourArea(contour) > mMinContourArea * maxArea[1]) {
          Core.multiply(contour, new Scalar(4, 4), contour);
          mContours.add(contour);
        }
      }

    } else {

      blobCenters[0].x = 0;
      blobCenters[0].y = 0;
      blobCenters[1].x = 0;
      blobCenters[1].y = 0;
    }
  }
Пример #14
0
  public static void getSquare(Mat imgSource) {
    Mat sourceImage = imgSource.clone();
    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);
    // convert the image to black and white does (8 bit)
    Imgproc.Canny(imgSource, imgSource, 50, 50);

    // apply gaussian blur to smoothen lines of dots
    Imgproc.GaussianBlur(imgSource, imgSource, new org.opencv.core.Size(5, 5), 5);

    // find the contours
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(
        imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    double maxArea = -1;
    int maxAreaIdx = -1;
    // Log.d("size",Integer.toString(contours.size()));
    MatOfPoint temp_contour = contours.get(0); // the largest is at the
    // index 0 for starting
    // point
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    MatOfPoint largest_contour = contours.get(0);
    // largest_contour.ge
    List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
    // Imgproc.drawContours(imgSource,contours, -1, new Scalar(0, 255, 0),
    // 1);

    for (int idx = 0; idx < contours.size(); idx++) {
      temp_contour = contours.get(idx);
      double contourarea = Imgproc.contourArea(temp_contour);
      // compare this contour to the previous largest contour found
      if (contourarea > maxArea) {
        // check if this contour is a square
        MatOfPoint2f new_mat = new MatOfPoint2f(temp_contour.toArray());
        int contourSize = (int) temp_contour.total();
        MatOfPoint2f approxCurve_temp = new MatOfPoint2f();
        Imgproc.approxPolyDP(new_mat, approxCurve_temp, contourSize * 0.05, true);
        if (approxCurve_temp.total() == 4) {
          maxArea = contourarea;
          maxAreaIdx = idx;
          approxCurve = approxCurve_temp;
          largest_contour = temp_contour;
        }
      }
    }

    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BayerBG2RGB);

    double[] temp_double;
    temp_double = approxCurve.get(0, 0);
    Point p1 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p1,55,new Scalar(0,0,255));
    // Imgproc.warpAffine(sourceImage, dummy, rotImage,sourceImage.size());
    temp_double = approxCurve.get(1, 0);
    Point p2 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p2,150,new Scalar(255,255,255));
    temp_double = approxCurve.get(2, 0);
    Point p3 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p3,200,new Scalar(255,0,0));
    temp_double = approxCurve.get(3, 0);
    Point p4 = new Point(temp_double[0], temp_double[1]);
    // Core.circle(imgSource,p4,100,new Scalar(0,0,255));
    List<Point> source = getCorners(p1, p2, p3, p4);
    for (Point p : source) {
      // System.out.println(p);
    }
    Mat startM = Converters.vector_Point2f_to_Mat(source);
    // Imgproc.cvtColor(sourceImage, sourceImage, Imgproc.COLOR_BGR2GRAY);
    Mat result = warp(sourceImage, startM, 5);
    // result = warp(result,result,1);
    // Imgproc.cvtColor(result, result, Imgproc.COLOR_BGR2GRAY);
    Highgui.imwrite(output, result);
    // System.out.println("Done");
    // return result;
  }
Пример #15
0
  public MatOfPoint getContourOfBestMatch() {

    if (matches == null) return null;

    Mat threshold = new Mat(imgGray.size(), imgGray.type());
    Imgproc.threshold(imgGray, threshold, 70, 255, Imgproc.THRESH_TOZERO);

    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(
        threshold, contours, new Mat(), Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_NONE);
    // HashMap<Integer,MatOfPoint> coordinates = computeCoord(contours,)

    if (contours.size() == 0) return null;
    List<DMatch> matchList = matches.toList();
    List<KeyPoint> keyPointList = keyPointImg.toList();

    HashMap<Integer, Double> contourDensityMap = new HashMap<Integer, Double>();

    Log.i("getContourBestMatch::", "contour size::" + contours.size());

    for (int idx = 0; idx < contours.size(); idx++) {
      MatOfPoint2f ctr2f = new MatOfPoint2f(contours.get(idx).toArray());
      // double contourarea = Imgproc.contourArea(contours.get(idx));

      double contourarea = contours.get(idx).rows();
      if (contourarea < 50) continue;

      Rect r = Imgproc.boundingRect(contours.get(idx));

      double count = 0;
      // Log.i("contour area","contour area is::"+contourarea);
      for (DMatch match : matchList) {

        Point q = keyPointList.get(match.queryIdx).pt;
        if (q.x >= r.x && q.x <= (r.x + r.width) && q.y >= r.y && q.y <= (r.y + r.height)) count++;

        //
        // if(Imgproc.pointPolygonTest(ctr2f,keyPointList.get(match.queryIdx).pt,true)>0){
        //                    if(null ==contourDensityMap.get(idx))
        //                        contourDensityMap.put(idx,1.0);
        //
        //                    else{
        //                        contourDensityMap.put(idx,((Double)contourDensityMap.get(idx))+1);
        //                    }
        //
        //                }

      }
      //            if(contourDensityMap.containsKey(idx)) {
      //
      // Log.i("contourPoint","idx::"+idx+"count::"+contourDensityMap.get(idx)+"contour
      // area::"+contourarea);
      //                contourDensityMap.put(idx, contourDensityMap.get(idx) / contourarea);
      //            }
      if (count != 0) {
        contourDensityMap.put(idx, count / contourarea);
      }
    }

    Log.i("MarkerTracker", "contour density size::" + contourDensityMap.size());

    Map.Entry<Integer, Double> maxEntry = null;

    for (Map.Entry<Integer, Double> entry : contourDensityMap.entrySet()) {
      Log.i("contourDensityMap", "Entry value::" + entry.getValue());
      if (maxEntry == null || entry.getValue().compareTo(maxEntry.getValue()) > 0) {
        maxEntry = entry;
      }
    }
    Log.i("maxEntry::", "" + (maxEntry == null ? null : maxEntry.getKey()));
    // return contours;
    return contours.get(maxEntry != null ? maxEntry.getKey() : 0);
  }
Пример #16
0
  public void processWithContours(Mat in, Mat out) {
    int playSquares = 32; // number of playable game board squares

    // keep track of starting row square
    int parity = 0; // 0 is even, 1 is odd, tied to row number
    int count = 0; // row square
    int rowNum = 0; // row number, starting at 0

    int vsegment = in.rows() / 8; // only accounts 8 playable
    int hsegment = in.cols() / 10; // 8 playable, 2 capture
    int hOffset = hsegment * 2; // offset for playable board
    int vOffset = vsegment + 40;

    // For angle of camera
    int dx = 80;
    int ddx = 0;
    hsegment -= 16;

    int dy = 20;
    vsegment -= 24;
    int ddy = 0;

    // Go through all playable squares
    for (int i = 0; i < playSquares; i++) {
      // change offset depending on the row
      if (parity == 0) // playable squares start on 2nd square from left
      {
        if (rowNum >= 5) dx -= 3;
        hOffset = hsegment * 2 + dx;
      } else // playable squares start on immediate left
      {
        if (rowNum >= 5) dx -= 3;
        hOffset = hsegment + dx;
      }

      if (rowNum == 0) ddy = 5;
      if (rowNum == 4) if (count == 6) ddx = 10;
      if (rowNum == 5) {
        if (count == 0) ddx = -6;
        else if (count == 2) ddx = 6;
        else if (count == 4) ddx = 12;
        else if (count == 6) ddx = 20;
      }
      if (rowNum == 6) {
        if (count == 0) ddx = 0;
        else if (count == 2) ddx = 16;
        else if (count == 4) ddx = 32;
        else if (count == 6) ddx = 40;
      }
      if (rowNum == 7) {
        if (count == 0) ddx = 6;
        else if (count == 2) ddx = 24;
        else if (count == 4) ddx = 40;
        else ddx = 52;
      }

      // find where roi should be
      // System.out.println("" + vOffset);
      Point p1 =
          new Point(
              hOffset + count * hsegment + ddx + 5,
              vOffset + rowNum * vsegment - dy - 5 - ddy); // top left point of rectangle (x,y)
      Point p2 =
          new Point(
              hOffset + (count + 1) * hsegment + ddx - 5,
              vOffset
                  + (rowNum + 1) * vsegment
                  - dy
                  - 5
                  - ddy); // bottom right point of rectangle (x,y)

      // create rectangle that is board square
      Rect bound = new Rect(p1, p2);

      Mat roi;
      char color;
      if (i == 0) {
        // frame only includes rectangle
        roi = new Mat(in, bound);

        // get the color
        color = identifyColor(roi);

        // copy input image to output image
        in.copyTo(out);
      } else {
        // frame only includes rectangle
        roi = new Mat(out, bound);

        // get the color
        color = identifyColor(roi);
      }

      Imgproc.cvtColor(roi, roi, Imgproc.COLOR_BGR2GRAY); // change to single color

      Mat canny = new Mat();
      Imgproc.Canny(roi, canny, 20, 40); // make image a canny image that is only edges; 2,4
      // lower threshold values find more edges
      List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
      Mat hierarchy = new Mat(); // holds nested contour information
      Imgproc.findContours(
          canny,
          contours,
          hierarchy,
          Imgproc.RETR_LIST,
          Imgproc.CHAIN_APPROX_SIMPLE); // Imgproc.RETR_LIST, TREE

      System.out.println(++test + "\t" + contours.size());

      if (contours.size() > 3) // or error value for color is below 1
      {
        switch (color) {
          case COLOR_BLUE:
            // Imgproc.rectangle(out, p1, p2, new Scalar(255, 0, 0), 2);
            Core.rectangle(out, p1, p2, new Scalar(255, 0, 0), 2);
            board[i] = CheckersBoard.BLACK; // end user's piece
            break;
          case COLOR_ORANGE:
            // Imgproc.rectangle(out, p1, p2, new Scalar(0, 128, 255), 2);
            Core.rectangle(out, p1, p2, new Scalar(0, 128, 255), 2);
            board[i] = CheckersBoard.WHITE; // system's piece
            break;
          case COLOR_WHITE:
            // Imgproc.rectangle(out, p1, p2, new Scalar(255, 255, 255), 2);
            Core.rectangle(out, p1, p2, new Scalar(255, 255, 255), 2);
            board[i] = CheckersBoard.EMPTY;
            break;
          case COLOR_BLACK: // this is black
            // Imgproc.rectangle(out, p1, p2, new Scalar(0, 0, 0), 2);
            Core.rectangle(
                out,
                p1,
                p2,
                new Scalar(0, 0, 0),
                2); // maybe add 8, 0 as line type and fractional bits
            board[i] = CheckersBoard.EMPTY;
            break;
        }
      }

      System.out.println("in color switch " + board[i]);
      count += 2;
      if (count == 8) {
        parity = ++parity % 2; // change odd or even
        count = 0;
        rowNum++;
        hsegment += 2;
        dx -= 10;
        dy += 10;
        vsegment += 3;
        ddy = 0;
      }
    }
  }
  /**
   * detection_contours, détecte les contours, les affiches et gères le traitement
   * d'authentification
   *
   * @param inmat : la matrice qui arrive pour la detection de contour
   * @param outmat : la matrice qui sort après les comptours
   */
  public void detection_contours(Mat inmat, Mat outmat) {
    Mat v = new Mat();
    Mat vv = outmat.clone();

    List<MatOfPoint> contours = new ArrayList(); // Tous les contours
    int key; // Plus gros contours
    MatOfInt hullI = new MatOfInt();
    List<MatOfPoint> hullP = new ArrayList<MatOfPoint>();
    Rect r; // Rectangle du plus gros contours

    // Trouve tous les contours
    Imgproc.findContours(vv, contours, v, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    // Calcul l'indice du plus gros contours
    key = findBiggestContour(contours);
    // S'il y a au moins un contours et le
    if (key != 0) {
      Imgproc.drawContours(inmat, contours, key, new Scalar(0, 0, 255));
      r = Imgproc.boundingRect(contours.get(key));
      Core.rectangle(currentFrame, r.br(), r.tl(), new Scalar(0, 255, 0), 1);
    }

    // Calcul les points convexes de la main
    Imgproc.convexHull(contours.get(key), hullI, false);

    // S'il y a des points de convexion
    if (hullI != null) {
      // Reinitialise les points de convexion
      hullP.clear();

      // On calcule le nombres de points de convexion
      for (int i = 0; contours.size() >= i; i++) hullP.add(new MatOfPoint());

      int[] cId = hullI.toArray();

      // On récupère dans un tableau de points, les points du contours
      Point[] contourPts = contours.get(key).toArray();

      // Réinitialisation des points de recherche dans les tableau
      int findRectA = 0;
      int findRectB = 0;
      int findRectC = 0;
      int findRectD = 0;

      // Pour chaque point de convexion
      for (int i = 0; i < cId.length; i++) {
        // Dessin du point de convexion sur la matrice
        Core.circle(inmat, contourPts[cId[i]], 2, new Scalar(241, 247, 45), -3);

        // Si le point de convexion se trouve dans un des carrés
        //     on incrémente le compteur associé
        if (isInRectangle(rectA, contourPts[cId[i]])) findRectA++;
        else if (isInRectangle(rectB, contourPts[cId[i]])) findRectB++;
        else if (isInRectangle(rectC, contourPts[cId[i]])) findRectC++;
        else if (isInRectangle(rectD, contourPts[cId[i]])) findRectD++;
      }

      // Si on a trouvé la main dans le rectangle A
      if (findRectA >= 5) {
        if (cptRect == 0) {
          numeroRect[cptRect] = 1;
          cptRect++;
          System.out.println("Haut gauche");
        } else {
          if (numeroRect[cptRect - 1] != 1) {
            numeroRect[cptRect] = 1;
            if (cptRect == 3) cptRect = 0;
            else cptRect++;
            System.out.println("Haut gauche");
          }
        }
      }

      // Si on a trouvé la main dans le rectangle B
      if (findRectB >= 5) {
        if (cptRect == 0) {
          numeroRect[cptRect] = 2;
          cptRect++;
          System.out.println("Bas gauche");
        } else {
          if (numeroRect[cptRect - 1] != 2) {
            numeroRect[cptRect] = 2;
            if (cptRect == 3) cptRect = 0;
            else cptRect++;
            System.out.println("Bas gauche");
          }
        }
      }

      // Si on a trouvé la main dans le rectangle C
      if (findRectC >= 5) {
        if (cptRect == 0) {
          numeroRect[cptRect] = 3;
          if (cptRect == 3) cptRect = 0;
          else cptRect++;
          System.out.println("Haut droite");
        } else {
          if (numeroRect[cptRect - 1] != 3) {
            numeroRect[cptRect] = 3;
            if (cptRect == 3) cptRect = 0;
            else cptRect++;
            System.out.println("Haut droite");
          }
        }
      }

      // Si on a trouvé la main dans le rectangle D
      if (findRectD >= 5) {
        if (cptRect == 0) {
          numeroRect[cptRect] = 4;
          cptRect++;
          System.out.println("Bas droite");
        } else {
          if (numeroRect[cptRect - 1] != 4) {
            numeroRect[cptRect] = 4;
            if (cptRect == 3) cptRect = 0;
            else cptRect++;

            System.out.println("Bas droite");
          }
        }
      }

      // Si on a sélectionné 3 fenètres et que cela correspond au mot de passe
      //      MOT DE PASSE : Haut Gauche - Bas Droite - Bas Gauche
      if (cptRect == 3) {
        if ((numeroRect[0] == 1) && (numeroRect[1] == 4) && (numeroRect[2] == 2))
          this.jTextField2.setText("Authenticated");
        // Réinitilisation du compteur
        cptRect = 0;
      }
    }
  }
Пример #18
0
  public Point findLaser(Mat inputFrame) {
    Mat mHsv = new Mat();

    Imgproc.cvtColor(inputFrame, mHsv, Imgproc.COLOR_RGB2HSV);

    // Find laser center
    Mat center = new Mat();
    Core.inRange(mHsv, new Scalar(0, 0, 250), new Scalar(180, 16, 255), center);

    Mat h = new Mat();
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(center, contours, h, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    center.release();

    Mat center_mask = Mat.zeros(inputFrame.rows(), inputFrame.cols(), CvType.CV_8U);
    if (contours.size() > 0) {
      for (int i = 0; i < contours.size(); i++) {
        int radius = 10;
        // Point[] cont_pos = contours.get(i).toArray();
        Moments m = Imgproc.moments(contours.get(i));
        Point p = new Point();
        p.x = m.get_m10() / m.get_m00();
        p.y = m.get_m01() / m.get_m00();
        Core.circle(center_mask, p, radius * 2, new Scalar(255), -1);
      }
    }

    // Find halo
    Mat ranged = new Mat();
    Core.inRange(mHsv, new Scalar(100, 32, 225), new Scalar(150, 255, 255), ranged);
    mHsv.release();
    // Mat f_frame =ranged.clone();

    // Find halo around bright dot
    Core.bitwise_and(ranged, center_mask, ranged);
    center_mask.release();

    // Find biggest resulting contour
    for (int i = 1; i < contours.size(); i++) {
      contours.get(i).release();
    }
    contours.clear();
    Imgproc.findContours(ranged, contours, h, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    h.release();
    ranged.release();

    if (contours.size() > 0) {
      MatOfPoint biggest_cont = contours.get(0);
      double cont_size = Imgproc.contourArea(biggest_cont);
      for (int i = 1; i < contours.size(); i++) {
        MatOfPoint cur = contours.get(i);
        if (Imgproc.contourArea(cur) > cont_size) {
          biggest_cont = cur;
          cont_size = Imgproc.contourArea(cur);
        }
      }
      Moments m = Imgproc.moments(biggest_cont);
      Point p = new Point();
      p.x = m.get_m10() / m.get_m00();
      p.y = m.get_m01() / m.get_m00();
      for (int i = 1; i < contours.size(); i++) {
        contours.get(i).release();
      }
      biggest_cont.release();

      return p;
    } else {
      return null;
    }
  }
Пример #19
0
  /**
   * Extracts and classifies colour bands for each Resistor. Each ColourBand object is instantiated
   * and linked to their parent Resistor object.
   *
   * @param resistorList A list of Resistor objects from which to extract the colour bands
   * @param paintDebugInfo If ture, the extracted colour band ROIs are displayed on the GUI
   */
  private void extractColourBandsAndClassify(List<Resistor> resistorList, boolean paintDebugInfo) {
    if (resistorList.size() > 0) {
      for (int r = 0; r < resistorList.size(); r++) {
        Mat resImg = resistorList.get(r).resistorMat;

        Mat imgHSV = new Mat();
        Mat satImg = new Mat();
        Mat hueImg = new Mat();

        // convert to HSV
        Imgproc.cvtColor(resImg, imgHSV, Imgproc.COLOR_BGR2HSV);
        ArrayList<Mat> channels = new ArrayList<Mat>();
        Core.split(imgHSV, channels);
        // extract channels
        satImg = channels.get(1); // saturation
        hueImg = channels.get(0); // hue

        // threshold saturation channel
        Mat threshedROISatBands = new Mat(); // ~130 sat thresh val
        Imgproc.threshold(satImg, threshedROISatBands, SAT_BAND_THRESH, 255, Imgproc.THRESH_BINARY);

        // threshold hue channel
        Mat threshedROIHueBands = new Mat(); // ~50 hue thresh val
        Imgproc.threshold(hueImg, threshedROIHueBands, HUE_BAND_THRESH, 255, Imgproc.THRESH_BINARY);

        // combine the thresholded binary images
        Mat bandROI = new Mat();
        Core.bitwise_or(threshedROIHueBands, threshedROISatBands, bandROI);

        // find contours in binary ROI image
        ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Mat hierarchy = new Mat();
        Imgproc.findContours(
            bandROI,
            contours,
            hierarchy,
            Imgproc.RETR_EXTERNAL,
            Imgproc.CHAIN_APPROX_SIMPLE,
            new Point(0, 0));

        // remove any remaining noise by only keeping contours which area > threshold
        for (int i = 0; i < contours.size(); i++) {
          double area = Imgproc.contourArea(contours.get(i));
          if (area < MIN_BAND_AREA) {
            contours.remove(i);
            i--;
          }
        }

        // create a ColourBand object for each detected band
        // storing its center, the contour and the bandROI
        for (int i = 0; i < contours.size(); i++) {
          MatOfPoint contour = contours.get(i);

          // extract this colour band and store in a Mat
          Rect boundingRect = Imgproc.boundingRect(contour);
          Mat mask = Mat.zeros(bandROI.size(), CvType.CV_8U);
          Imgproc.drawContours(mask, contours, i, new Scalar(255), Core.FILLED);
          Mat imageROI = new Mat();
          resImg.copyTo(imageROI, mask);
          Mat colourBandROI = new Mat(imageROI, boundingRect);

          // instantiate new ColourBand object
          ColourBand cb = new ColourBand(findCenter(contour), contour, colourBandROI);

          // cluster the band colour
          cb.clusterBandColour(BAND_COLOUR_K_MEANS);

          // classify using the Lab colourspace as feature vector
          Mat sampleMat =
              new Mat(1, 3, CvType.CV_32FC1); // create a Mat contacting the clustered band colour
          sampleMat.put(0, 0, cb.clusteredColourLAB[0]);
          sampleMat.put(0, 1, cb.clusteredColourLAB[1]);
          sampleMat.put(0, 2, cb.clusteredColourLAB[2]);
          Mat classifiedValue = new Mat(1, 1, CvType.CV_32FC1);
          Mat neighborResponses = new Mat(); // dont actually use this
          Mat dists = new Mat(); // dont actually use this
          // classify
          knn.find_nearest(sampleMat, 3, classifiedValue, neighborResponses, dists);

          // cast classified value into Colour enum and store
          cb.classifiedColour = ColourEnumVals[(int) classifiedValue.get(0, 0)[0]];
          // add the band to the parent resistor
          resistorList.get(r).bands.add(cb);
        }

        // paint the extracted band ROIs
        if (paintDebugInfo) {
          Mat finalBandROIMask = Mat.zeros(bandROI.size(), CvType.CV_8U);
          for (int i = 0; i < contours.size(); i++) {
            Scalar color = new Scalar(255, 255, 255);
            Imgproc.drawContours(
                finalBandROIMask, contours, i, color, -1, 4, hierarchy, 0, new Point());
          }
          Mat colourROI = new Mat();
          resImg.copyTo(colourROI, finalBandROIMask);
          paintResistorSubRegion(colourROI, r);
        }
      }
    }
  }
Пример #20
0
  public void run() {
    ArrayList<Geometry.Quad> squares;

    Mat image = new Mat();
    Utils.bitmapToMat(source, image);

    Mat bwimage = new Mat();
    cvtColor(image, bwimage, COLOR_RGB2GRAY);

    Mat blurred = new Mat();
    medianBlur(image, blurred, 9);

    int width = blurred.width();
    int height = blurred.height();
    int depth = blurred.depth();

    Mat gray0 = new Mat(width, height, depth);
    blurred.copyTo(gray0);

    squares = new ArrayList<Geometry.Quad>();

    // find squares in every color plane of the image
    for (int c = 0; c < 3; c++) {
      Core.mixChannels(
          Arrays.asList(blurred), Arrays.asList(new Mat[] {gray0}), new MatOfInt(c, 0));

      // try several threshold levels
      int thresholdLevel = 8;
      for (int l = 0; l < thresholdLevel; l++) {
        // use canny instead of 0 threshold level
        // canny helps catch squares with gradient shading
        Mat gray = new Mat();

        if (l == 0) {
          Canny(gray0, gray, 10.0, 20.0, 3, false);
          Mat kernel = new Mat(11, 11, CvType.CV_8UC1, new Scalar(1));
          dilate(gray, gray, kernel);
        } else {
          Mat thresh = new Mat(gray0.rows(), gray0.cols(), gray0.type());
          threshold(gray0, thresh, ((double) l) / thresholdLevel * 255, 128, THRESH_BINARY_INV);
          cvtColor(thresh, gray, COLOR_BGR2GRAY);
        }

        // find contours and store them in a list
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        findContours(gray, contours, new Mat(), RETR_LIST, CHAIN_APPROX_SIMPLE);

        // test contours
        for (MatOfPoint contour : contours) {
          // approximate contour with accuracy proportional to the contour perimeter
          MatOfPoint2f thisContour = new MatOfPoint2f(contour.toArray());
          double arclength = 0.02 * arcLength(thisContour, true);
          MatOfPoint2f approx = new MatOfPoint2f();
          approxPolyDP(thisContour, approx, arclength, true);

          double area = contourArea(approx);
          boolean isConvex = isContourConvex(new MatOfPoint(approx.toArray()));

          if (approx.rows() == 4 && Math.abs(area) > SQUARE_SIZE && isConvex) {
            double maxCosine = 0;

            Point[] approxArray = approx.toArray();
            for (int j = 2; j < 5; j++) {
              double cosine =
                  Math.abs(angle(approxArray[j % 4], approxArray[j - 2], approxArray[j - 1]));
              maxCosine = Math.max(maxCosine, cosine);
            }

            if (maxCosine > THRESHOLD_COS) {
              squares.add(new Geometry.Quad(approxArray));
              Log.d(TAG, "area = " + area);
            }
          }
        }
      }
    }

    result = new Bundle();
    result.putParcelableArrayList("squares", squares);
    Log.d(TAG, "result created");

    finish();
  }