OpenCV, Android: color detection from particular area or portion of an image?

Viewed 2310

I want to detect the entire area below the black object.

I've managed to get the rectangle area below the black object like so

    Point leftPoint = new Point(0,yValueBlack); //far left, black object height
    Point rightPoint = new Point(sourceBitmap.getWidth(),sourceBitmap.getHeight()); //btm right of entire bitmap

    Rect bottomRect = new Rect(leftPoint,rightPoint);

Whereby Rect bottomRect = new Rect(leftPoint,rightPoint); is the area i want to detect the green strip in, like in the picture. This is to prevent the application from searching anything above the picture and causing error when other objects are in frame.

I have a bitmap of the black object bounded by a bounding rectangle, I want to detect only Rect bottomRect = new Rect(leftPoint,rightPoint); from that bitmap & then draw the bounding rectangle for the green strip.

The way i defined my mat's size is like this Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);

However when i tried to use the same method to define my mat size to fit the rectangle area below black object like so: Mat croppedMat = new Mat(bottomRect, CvType.CV_8UC3); It'd give me an error.

Here's how it would look like I think:

  1. Detect and draw bounding rectangle around black object (Done)

  2. Find rectangle area(RAT) below black object

  3. Detect and draw bounding rectangle around green object within the RAT(I can detect and draw bounding rectangle for green object, cant seem to do it WITHIN the specified RAT)

  4. Display bitmap like shown in image below(done)

enter image description here

EDIT:

after detecting the black object, the bounding rect is drawn and is currently on roiBitmap. Cropping the roiBitmap and trying to display it(I'd be detecting the green tape from this bitmap that's cropped out eventually.) in an imageview is giving me error:

CvException [org.opencv.core.CvException: cv::Exception: /build/master_pack-android/opencv/modules/core/src/matrix.cpp:483: error: (-215) 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows in function cv::Mat::Mat(const cv::Mat&, const cv::Range&, const cv::Range&)

my code:

private Bitmap findCombine(Bitmap sourceBitmap) {
        Bitmap roiBitmap = null;
        Scalar green = new Scalar(0, 255, 0, 255);
        Mat sourceMat = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
        Utils.bitmapToMat(sourceBitmap, sourceMat);
        Mat roiTmp = sourceMat.clone();
        bitmapWidth = sourceBitmap.getWidth();
        Log.e("bitmapWidth", String.valueOf(bitmapWidth));
        final Mat hsvMat = new Mat();
        sourceMat.copyTo(hsvMat);

        // convert mat to HSV format for Core.inRange()
        Imgproc.cvtColor(hsvMat, hsvMat, Imgproc.COLOR_RGB2HSV);

        Scalar lowerb = new Scalar(85, 50, 40);         // lower color border for BLUE
        Scalar upperb = new Scalar(135, 255, 255);      // upper color border for BLUE

        Scalar lowerblack = new Scalar(0, 0, 0);         // lower color border for BLACK
        Scalar upperblack = new Scalar(180, 255, 40);      // upper color border for BLACK

        Scalar testRunL = new Scalar(60, 50, 40); // lower Green   83 100 51
        Scalar testRunU = new Scalar(90, 255, 255); // upper Green

        Core.inRange(hsvMat, lowerblack, upperblack, roiTmp);   // select only blue pixels
        // find contours
        List<MatOfPoint> contours = new ArrayList<>();
        List<RotatedRect> boundingRects = new ArrayList<>();
        Imgproc.findContours(roiTmp, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

        // find appropriate bounding rectangles
        for (MatOfPoint contour : contours) {
            MatOfPoint2f areaPoints = new MatOfPoint2f(contour.toArray());
            RotatedRect boundingRect = Imgproc.minAreaRect(areaPoints);

            double rectangleArea = boundingRect.size.area();

            // test min ROI area in pixels
            if (rectangleArea > 1300 && rectangleArea < 500000) {//400000
                Point rotated_rect_points[] = new Point[4];
                boundingRect.points(rotated_rect_points);
                Rect rect3 = Imgproc.boundingRect(new MatOfPoint(rotated_rect_points));

                Log.e("blackArea", String.valueOf(rect3.area()));
                // test horizontal ROI orientation
                if (rect3.height > rect3.width) {
                    Imgproc.rectangle(sourceMat, rect3.tl(), rect3.br(), green, 3);
                    xBlack = rect3.br().x;
                    yBlack = rect3.br().y;//bottom
                    battHeight = (rect3.br().y - rect3.tl().y); //batt height in pixel
                    Log.e("BLACKBR, TL", String.valueOf(rect3.br().y) + "," + String.valueOf(rect3.tl().y));
                }

            }

        }
  

   roiBitmap = Bitmap.createBitmap(sourceMat.cols(), sourceMat.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(sourceMat, roiBitmap);


    Point leftPoint = new Point(0, yBlack); //far left, black object height
    Point rightPoint = new Point(roiBitmap.getWidth(), roiBitmap.getHeight()); //btm right of entire bitmap

    Rect bottomRect = new Rect(leftPoint, rightPoint);
    double rectWidth = sourceBitmap.getWidth() - 0;
    double rectHeight = sourceBitmap.getHeight() - yBlack;
    Log.e("rectWidth", String.valueOf(rectWidth));
    Log.e("rectHeight", String.valueOf(rectHeight));
    Size bottomRectSize = new Size(rectHeight, rectWidth);

    Bitmap cropBitmap = null;
    Bitmap sourceBitmapT = null;

    Mat sourceMatT = new Mat(sourceBitmap.getWidth(), sourceBitmap.getHeight(), CvType.CV_8UC3);
    Log.e("sourceMatT, BottomRect","SMT "+ String.valueOf(sourceMatT.size()) + " bottomRect " + String.valueOf(bottomRect.size()));


    Mat cropMat = new Mat(sourceMatT, bottomRect);
    ImageView imgCropped = (ImageView) findViewById(R.id.cropped_image_view);
    Utils.bitmapToMat(roiBitmap, sourceMatT);
    //mgCropped.setImageBitmap(sourceBitmapT);

    Utils.matToBitmap(cropMat, cropBitmap);
    imgCropped.setImageBitmap(cropBitmap);

Log.e("sourceMatT, BottomRect","SMT "+ String.valueOf(sourceMatT.size()) + " bottomRect " + String.valueOf(bottomRect.size()));

returned me these values:

sourceMatT, BottomRect: SMT 1920x1080 bottomRect 1080x656

1 Answers
Related