예제 #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;
  }
  /**
   * 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;
  }
예제 #3
0
  /**
   * @param inputImg
   * @param minValue
   * @param maxValue
   * @return Mat
   */
  public static Mat thresholding(Mat inputImg, Integer minValue, Integer maxValue) {

    Mat frame = inputImg;
    // яскравість
    // frame.convertTo(frame , -1, 10d * 33 / 100, 0);
    // Imgproc.medianBlur(frame,frame, 17);

    // Core.bitwise_not(frame,frame );

    // Mat frame = new Mat(image.rows(), image.cols(), image.type());

    // frame.convertTo(frame, -1, 10d * 20 / 100, 0);

    Mat hsvImg = new Mat();
    List<Mat> hsvPlanes = new ArrayList<>();
    Mat thresholdImg = new Mat();

    int thresh_type = Imgproc.THRESH_BINARY_INV;

    // if (this.inverse.isSelected())
    // thresh_type = Imgproc.THRESH_BINARY;

    // threshold the image with the average hue value
    // System.out.println("size " +frame.size());
    hsvImg.create(frame.size(), CvType.CV_8U);
    // Imgproc.cvtColor(frame, hsvImg, Imgproc.COLOR_BGR2HSV);
    Core.split(hsvImg, hsvPlanes);

    // get the average hue value of the image
    // double threshValue = PreProcessingOperation.getHistAverage(hsvImg, hsvPlanes.get(0));
    // System.out.println(threshValue);
    /*
    if(threshValue > 40){
        maxValue = 160;
    }else{
        maxValue = 40;
    }*/

    //        Imgproc.threshold(hsvPlanes.get(1), thresholdImg, minValue , maxValue , thresh_type);

    Imgproc.blur(thresholdImg, thresholdImg, new Size(27, 27));

    // dilate to fill gaps, erode to smooth edges
    Imgproc.dilate(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);
    Imgproc.erode(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);

    Imgproc.threshold(thresholdImg, thresholdImg, minValue, maxValue, Imgproc.THRESH_BINARY);

    // create the new image
    Mat foreground = new Mat(frame.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
    Core.bitwise_not(thresholdImg, foreground);

    frame.copyTo(foreground, thresholdImg);

    ///////////////////////////////////////////////////////////////////////////////////////
    ///
    ////

    return foreground;
    /*Mat hsvImg = new Mat();
    List<Mat> hsvPlanes = new ArrayList<>();
    Mat thresholdImg = new Mat();
    int thresh_type = Imgproc.THRESH_BINARY_INV;
    // threshold the image with the average hue value
    hsvImg.create(inputImg.size(), CvType.CV_8U);
    Imgproc.cvtColor(inputImg, hsvImg, Imgproc.COLOR_BGR2HSV);
    Core.split(hsvImg, hsvPlanes);
    // get the average hue value of the image
    double threshValue = PreProcessingOperation.getHistAverage(hsvImg, hsvPlanes.get(0));
    Imgproc.threshold(hsvPlanes.get(0), thresholdImg, minValue,
            maxValue, thresh_type);
    Imgproc.blur(thresholdImg, thresholdImg, new Size(3, 3));
    // dilate to fill gaps, erode to smooth edges
    Imgproc.dilate(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 3);
    Imgproc.erode(thresholdImg, thresholdImg, new Mat(), new Point(-1, -1), 1);
    Imgproc.threshold(thresholdImg, thresholdImg, minValue,
            maxValue, Imgproc.THRESH_BINARY);
    // create the new image
    Mat foreground = new Mat(inputImg.size(), CvType.CV_8UC3, new Scalar(255, 255, 255));
    inputImg.copyTo(foreground, thresholdImg);
    Core.bitwise_not(foreground,foreground);
    return foreground;*/
  }
  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;
  }
예제 #5
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();
  }
예제 #6
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;
    }
  }