OpenCv android : Copy part of an image to new Mat

♀尐吖头ヾ 提交于 2019-12-08 07:33:54

问题


I am new to OpenCV and trying to learn by implementing. I need to draw the contours I have detected in new Mat so I can work with them.

This is my Original image:

After doing some work I achieved this by finding and drawing contours:

Here's my code

m = Utils.loadResource(MainActivity.this, R.drawable.sheet1, Highgui.CV_LOAD_IMAGE_COLOR);

Bitmap bm = Bitmap.createBitmap(m.cols(), m.rows(),Bitmap.Config.ARGB_8888);

Imgproc.cvtColor(m, m, Imgproc.COLOR_BGR2GRAY);
Imgproc.medianBlur(m, m, 3);
Imgproc.threshold(m, m, 0, 255, Imgproc.THRESH_OTSU);
Core.bitwise_not(m, m);
Imgproc.dilate(m, m, Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(1,118)));

//Contours detection

java.util.List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

Imgproc.findContours(m, contours, new Mat() ,Imgproc.RETR_EXTERNAL , Imgproc.CHAIN_APPROX_SIMPLE);
Imgproc.cvtColor(m, m, Imgproc.COLOR_GRAY2BGR);

//Contour drawing

Mat matArray = new Mat();

Imgproc.drawContours(m, contours, -1, new Scalar(153,255,204), 3);

Utils.matToBitmap(m, bm);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setImageBitmap(bm);

Now, I want to save every MCQ in new Mat. How can this be implemented in android Java?


回答1:


You can use boundingRect to have rectangular contours. Then, for each contour, you can use the Point stored in it to create the new Mat. You can use cv::getPerspectiveTransform and cv::warpPerspectivewith the points and an empty Mat.

I don't know how it works in Java, but in C++ its something similar to that.

you can take a look at this : http://docs.opencv.org/doc/tutorials/imgproc/shapedescriptors/bounding_rects_circles/bounding_rects_circles.html

Hope it helps.




回答2:


Here is the code you can change the inRange values as per your requirement:

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {

/* orientation change added by Susmita
        Mat mRgbaT = mRGBa.t();
        Core.flip(mRGBa.t(), mRgbaT, 1);
        Imgproc.resize(mRgbaT, mRgbaT, mRGBa.size());
        return mRgbaT;*/
//

    //Get a frame from the camera in RGB format
    mRGBa = inputFrame.rgba();

    //Remove noise from the image.
    Imgproc.medianBlur(mRGBa, mBlur, 5);

    //Convert image to HSV format
    Imgproc.cvtColor(mBlur, imHSV, Imgproc.COLOR_RGB2HSV);

    //Filter out Green coloured objects in the image.
    //TODO: This scale has to be optimized to detect on Greed colored LED
    Core.inRange(imHSV, new Scalar(50, 100, 100, 100), new Scalar(70, 225, 255, 255), imHSV);

    //Remove noise from the image.
    Imgproc.GaussianBlur(imHSV, imHSV, new Size(9, 9), 2, 2);

    //Convert the image from HSV to Gray scale image.
    imHSV.convertTo(imGray, CvType.CV_8U);

    //Apply threshold to the gray scale image to remove unnecessay objects from image.
    Imgproc.threshold(imGray, imGray, 50, 255, Imgproc.THRESH_BINARY);

    //Perform edge detection the image
    Imgproc.Canny(imGray, imGray, 100, 200);

    //Find Contours(closed shapes) in the image. (Detected LED will be a contour)
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(imGray, contours, new Mat(), Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));

    // For each detected contour(closed shape) Find the co-ordinates of the countour and draw a rectangle on the input image.
    //TODO: For each Contour detected, below logic can be changed to detect countours having only 4 edges(rectangle/square).
    for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
        // Minimum size allowed for consideration
        MatOfPoint2f approxCurve = new MatOfPoint2f();

        MatOfPoint2f contour2f = new MatOfPoint2f(contours.get(contourIdx).toArray());

        //Processing on mMOP2f1 which is in type MatOfPoint2f
        double approxDistance = Imgproc.arcLength(contour2f, true) * 0.02;

        //Detect contours
        Imgproc.approxPolyDP(contour2f, approxCurve, approxDistance, true);

        //Convert back to MatOfPoint
        MatOfPoint points = new MatOfPoint(approxCurve.toArray());

        // Get bounding rect of contour
        Rect rect = Imgproc.boundingRect(points);

        //Draw rectangle for the detected countour on the original image
        Imgproc.rectangle(mRGBa, new Point(rect.x, rect.y), new Point(rect.x + rect.width, rect.y + rect.height),
                new Scalar(255, 0, 255, 255), 2);
    }
    return  mRGBa;
}


来源:https://stackoverflow.com/questions/29184697/opencv-android-copy-part-of-an-image-to-new-mat

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!