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; }
/** * @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; }
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(); }
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; } }