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; } }