/**
   * 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;
  }
Пример #2
0
  /**
   * Creates Resistor objects for all resistors extracted from given contours. Optionally, also
   * displays a bounding rectangle for all contours in the top left frame of the GUI.
   *
   * @param contours The contours defining the resistors
   * @param image The image from which the contours were extracted
   * @param showBoundingRect If true draws a bounding rectange for each contour
   * @return A list of Resistor objects
   */
  private List<Resistor> extractResistorsFromContours(
      List<MatOfPoint> contours, Mat image, boolean showBoundingRect) {
    List<Mat> extractedResistors = new ArrayList<Mat>();
    List<Rect> boundingRect = new ArrayList<Rect>();
    List<Resistor> resistors = new ArrayList<Resistor>();

    for (int i = 0; i < contours.size(); i++) {
      // bounding rectangle
      boundingRect.add(Imgproc.boundingRect(contours.get(i)));
      Mat mask = Mat.zeros(image.size(), CvType.CV_8U);
      Imgproc.drawContours(mask, contours, i, new Scalar(255), Core.FILLED);

      Mat contourRegion;
      Mat imageROI = new Mat();
      image.copyTo(imageROI, mask);
      contourRegion = new Mat(imageROI, boundingRect.get(i));
      extractedResistors.add(contourRegion);

      // the center of the resistor as a point within the original captured image
      Point resistorCenterPoint = findCenter(contours.get(i));

      // create a new resistor entry
      Resistor r = new Resistor(resistorCenterPoint, contourRegion);
      resistors.add(r);
    }

    if (showBoundingRect) {
      Mat drawing = new Mat();
      image.copyTo(drawing);
      for (int i = 0; i < contours.size(); i++) {
        Core.rectangle(
            drawing, boundingRect.get(i).tl(), boundingRect.get(i).br(), new Scalar(0, 0, 255), 2);
      }
      paintTL(drawing);
    }

    return resistors;
  }
Пример #3
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);
        }
      }
    }
  }
  /**
   * 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;
      }
    }
  }
Пример #5
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;
    	}
    }*/
  }
  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;
  }
Пример #7
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) {

    }
  }
Пример #8
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);
  }
Пример #9
0
  public static void Circle(List<MatOfPoint> contours, int index) {
    int i = index;
    Mat mRGBA = new Mat();
    Utils.bitmapToMat(image, mRGBA);
    // cyklus s podmienkou na konci
    do {
      int buff[] = new int[4];
      hierarchy.get(0, i, buff);

      // Get contour form list
      Mat contour = contours.get(i);

      // id kont�ry
      int id = i;

      // dostaneme �a��ie id kont�ry
      i = buff[0];

      // zis�ujeme �i m�me dostato�ne ve�k� kont�ru aby sme sa �ou v�bec zaoberali
      if (Imgproc.contourArea(contour) > 500) {

        List<Point> points = new ArrayList<Point>();

        // dostaneme celkov� po�et kont�r
        int num = (int) contour.total();

        // vytvor�me si pole o dvojn�sobnej ve�kosti samotnej kontury
        int temp[] = new int[num * 2];

        // na��tame si kont�ru do do�asnej premennej
        contour.get(0, 0, temp);

        // konvertujeme  List<Point> do MatOfPoint2f pre pou�itie fitEllipse
        for (int j = 0; j < num * 2; j = j + 2) {
          points.add(new Point(temp[j], temp[j + 1]));
        }
        MatOfPoint2f specialPointMtx = new MatOfPoint2f(points.toArray(new Point[0]));

        // do premennej bound uklad�me dokonal� elipsu
        RotatedRect bound = Imgproc.fitEllipse(specialPointMtx);

        // Vypo��ta sa hodnota pi
        double pi =
            Imgproc.contourArea(contour) / ((bound.size.height / 2) * (bound.size.width / 2));

        // zis�ujeme toleranciu pi - zaoplenie
        if (Math.abs(pi - 3.14) > 0.03) {
          int k = buff[2];
          // zis�ujeme �i existuje nejak� rodi� kont�ry
          if (k != -1) {
            Circle(contours, k);
          }
          continue;
        }

        // konvertujeme MatOfPoint2f do MatOfPoint  pre funckiu fitEllipse - rozdie� je len v 32-bit
        // float a 32-bit int
        MatOfPoint NewMtx = new MatOfPoint(specialPointMtx.toArray());
        // dostaneme s�radnice najmen�ieho mo�n�ho �tvorca
        Rect box = Imgproc.boundingRect(NewMtx);
        // nacita obrazok znova
        Mat mat_for_count = new Mat();
        Utils.bitmapToMat(image, mat_for_count);
        // vytvori sa klon stvorca - dobry kandidat pre vyhladanie
        Mat candidate = ((mat_for_count).submat(box)).clone();
        // napln maticu binarnou ciernou
        Mat mask = new Mat(box.size(), candidate.type(), new Scalar(0, 0, 0));
        // naplni ciernu plochu bielimi konturami
        Imgproc.drawContours(
            mask,
            contours,
            id,
            new Scalar(255, 255, 255),
            -1,
            8,
            hierarchy,
            0,
            new Point(-box.x, -box.y));
        // ulozi sa kandidat
        Mat roi = new Mat(candidate.size(), candidate.type(), new Scalar(255, 255, 255));
        // ulozia sa len informacie o kandidatovi
        candidate.copyTo(roi, mask);

        double longAxis;
        double shortAxis;
        // ziska dve osy elipsy
        if (bound.size.height < bound.size.width) {
          shortAxis = bound.size.height / 2;
          longAxis = bound.size.width / 2;
        } else {
          shortAxis = bound.size.width / 2;
          longAxis = bound.size.height / 2;
        }

        // zastavi sa vyhladavanie pokial je elipsa prilis ovalna
        if ((longAxis / shortAxis) < 2.0) {
          signList.add(roi);
          boxList.add(box);
        }
      }
      // zis�uje sa �i je tam e�te �al�� kandid�t
    } while (i != -1);
  }