简体   繁体   English

使用 OpenCV4Android 覆盖图像

[英]Overlaying image with OpenCV4Android

I've been trying to overlay an image over a rectangle detected by the camera.我一直在尝试将图像覆盖在相机检测到的矩形上。 I'm using a function that is returning the path of my image from my sd card (.jpg), but it looks that it is not loading it correctly, or at least I can't display it where I want.我正在使用一个函数从我的 SD 卡 (.jpg) 返回我的图像路径,但它看起来没有正确加载它,或者至少我无法在我想要的地方显示它。

First of all, I check if the image is loaded (and I load it if it isn't).首先,我检查图像是否已加载(如果没有,则加载它)。 Then, I proceed recognizing rectangles.然后,我继续识别矩形。 Once I recognize one, I'm suppose to overlay that rectangle on the frame with the loaded image, and then return to the ImageView the modified frame.一旦我认出了一个,我想用加载的图像在框架上覆盖那个矩形,然后返回到 ImageView 修改后的框架。

I'll share with you my code from the onCameraFrame function ("image" is a Mat object where I store my loaded image from my sdcard, and "img_path" is the string where the image's path is stored):我将与您分享我在 onCameraFrame 函数中的代码(“image”是一个 Mat 对象,我在其中存储我从 sdcard 加载的图像,而“img_path”是存储图像路径的字符串):

Mat dst = inputFrame.rgba();

//Here I check if the image is loaded
        if (image.empty()){
            Log.v("Image","Empty!");
            image = imread(img_path, CV_LOAD_IMAGE_UNCHANGED);
        } else {

            //If the image is loaded, then I proceed to process the frame.
            Mat gray = inputFrame.gray();


            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) {
                        Rect r = Imgproc.boundingRect(cnt);
                        image.copyTo(dst.submat(r));

                        Log.v("Test 1",Integer.toString(image.width()));
                        Log.v("Test 2",Integer.toString(image.height()));

                    }
                }
            }
        }
        return dst;

I want to see over the rectangles the image, but I keep looking at the same unmodified.我想查看图像的矩形,但我一直在查看相同的未修改内容。 I am getting only once the log "Empty!", so it should be reading correctly the image and storing it on my Mat.我只收到一次日志“空!”,所以它应该正确读取图像并将其存储在我的垫子上。 Also, on the other 2 Logs where I am writting the image number of rows and columns, I am getting a number bigger than 0. So...另外,在我写入图像行和列数的其他 2 个日志中,我得到的数字大于 0。所以......

Is that the right way of checking if the image is correctly loaded?这是检查图像是否正确加载的正确方法吗? Do you now why that code is not working?您现在知道为什么该代码不起作用了吗? I also read about the function addWeighted, but I tried to resized the smaller image and it failed.我还阅读了 addWeighted 函数,但我尝试调整较小图像的大小,但失败了。

Thanks in advance!!提前致谢!!

EDIT This is the part of the code where I recognize the rectangle and I have to render the new image over the rectangle on the frame:编辑这是我识别矩形的代码部分,我必须在框架上的矩形上渲染新图像:

 //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) {
                        Rect r = Imgproc.boundingRect(cnt);
                        image.copyTo(dst.submat(r));

                        Log.v("Test 1",Integer.toString(image.width()));
                        Log.v("Test 2",Integer.toString(image.height()));

                    }
                }

As an example, you can check the following image from the InkHunter app's webpage: https://i1.wp.com/goosed.ie/wp-content/uploads/2016/10/inkhunter-cover-for-tattoo-ideas-1.jpg?fit=800%2C450&ssl=1例如,您可以从 InkHunter 应用程序的网页查看以下图片: https ://i1.wp.com/goosed.ie/wp-content/uploads/2016/10/inkhunter-cover-for-tattoo-ideas- 1.jpg?fit=800%2C450&ssl=1

I found the solution.我找到了解决方案。

Both image size and image channels number must be same, and use mask for faster processing images.图像大小和图像通道数必须相同,并使用掩码更快地处理图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM