0

I'm trying to overlay on the live frame a little image previosuly selected by the user. I already have the image's path from a previous activity. My problem is that I am not able to show the image on the frame.

I'm trying to detect a rectangle on the frame, and over the rectangle display the image selected. I could detect the rectangle, but now i can't display the image on any part of the frame (I don't care about the rectangle right now). I've been trying to do it with the explanations from Adding Image Overlay OpenCV for Android and add watermark small image to large image opencv4android but it didn't worked for me.

public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {

        Mat gray = inputFrame.gray();
        Mat dst = inputFrame.rgba();

        Imgproc.pyrDown(gray, dsIMG, new Size(gray.cols() / 2, gray.rows() / 2));
        Imgproc.pyrUp(dsIMG, usIMG, gray.size());

        Imgproc.Canny(usIMG, bwIMG, 0, threshold);

        Imgproc.dilate(bwIMG, bwIMG, new Mat(), new Point(-1, 1), 1);

        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();

        cIMG = bwIMG.clone();

        Imgproc.findContours(cIMG, contours, hovIMG, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);


        for (MatOfPoint cnt : contours) {

            MatOfPoint2f curve = new MatOfPoint2f(cnt.toArray());

            Imgproc.approxPolyDP(curve, approxCurve, 0.02 * Imgproc.arcLength(curve, true), true);

            int numberVertices = (int) approxCurve.total();

            double contourArea = Imgproc.contourArea(cnt);

            if (Math.abs(contourArea) < 100) {
                continue;
            }

            //Rectangle detected
            if (numberVertices >= 4 && numberVertices <= 6) {

                List<Double> cos = new ArrayList<>();

                for (int j = 2; j < numberVertices + 1; j++) {
                    cos.add(angle(approxCurve.toArray()[j % numberVertices], approxCurve.toArray()[j - 2], approxCurve.toArray()[j - 1]));
                }

                Collections.sort(cos);

                double mincos = cos.get(0);
                double maxcos = cos.get(cos.size() - 1);

                if (numberVertices == 4 && mincos >= -0.3 && maxcos <= 0.5) {

                     //Small watermark image
                    Mat a = imread(img_path);

                    Mat bSubmat = dst.submat(0, dst.rows() -1 , 0, dst.cols()-1);
                    a.copyTo(bSubmat);


                }
            }

        }

        return dst;

    }

NOTE: img_path is the path of the selected image I want to display over the frame. I got it from the previous activity.

By now, I just want to display the image over the frame. Later, I will try to display it on the same position where it found the rectangle. Please, any suggestion or recommendation is welcome, as I am new with OpenCV. I'm sorry for my english, but feel free to ask me anything I didn't explain correctly. I'll do my best to explain it better. Thanks a lot!

Community
  • 1
  • 1

1 Answers1

0

If you just want to display the image as an overlay, and not save it as part of the video, you may find it easier to simple display it in a separate view above the video view. This will likely use less processing, battery etc also.

If you want to draw onto the camera image bitmap then the following will allow you do that:

   Bitmap cameraBitmap = BitmapFactory.decodeByteArray(bytes,0,bytes.length, opt);
            Canvas camImgCanvas = new Canvas(cameraBitmap);
            Drawable d = ContextCompat.getDrawable(getActivity(), R.drawable.myDrawable);
            //Centre the drawing
            int bitMapWidthCenter = cameraBitmap.getWidth()/2;
            int bitMapheightCenter = cameraBitmap.getHeight()/2;
            d.setBounds(bitMapWidthCenter, bitMapheightCenter, bitMapWidthCenter+d.getIntrinsicWidth(),
                    bitMapheightCenter+d.getIntrinsicHeight());
            //And draw it...
            d.draw(camImgCanvas);
Mick
  • 24,231
  • 1
  • 54
  • 120
  • Ok, I'll investigate more about your idea. I wanted to work with OpenCV4Android because my final idea is to replace the rectangle detected with the image selected. But if your idea works fine for me, I'll let you know. Thanks a lot! – Luciano Ruiz Morales Jun 18 '19 at 23:02
  • @LucianoRuizMorales - just in case it was not clear - the code above will allow you add the image directly into the captured frame and you can then save that, if you do decide that is the way you want to go. – Mick Jun 19 '19 at 07:55
  • Thanks for the explanation! I will try your suggestion. Everything that you could give me I will give it a try. – Luciano Ruiz Morales Jun 19 '19 at 23:21