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