使用OpenCV4Android覆盖图像

时间:2019-06-28 00:02:36

标签: android opencv

我一直试图将图像覆盖在相机检测到的矩形上。我正在使用一个函数,该函数从sd卡(.jpg)返回图像的路径,但是它似乎未正确加载图像,或者至少我无法在所需位置显示它。

首先,我检查图像是否已加载(如果未加载,则进行加载)。然后,我继续识别矩形。识别出一个矩形后,我想用加载的图像在框架上覆盖该矩形,然后将修改后的框架返回到ImageView。

我将与您分享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;

我想在矩形上看到图像,但是我一直在看相同的未修改图像。我只收到一次“ Empty!”(空!)日志,因此它应该正确读取图像并将其存储在Mat上。另外,在其他2个记录行数和列数的日志中,我得到的数字大于0。所以...

检查图像是否正确加载是正确的方法吗? 您现在为什么该代码不起作用?我还阅读了有关addWeighted函数的信息,但是我尝试调整较小图像的大小,但失败了。

提前谢谢!

编辑,这是代码中识别矩形的部分,必须在框架的矩形上渲染新图像:

 //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()));

                    }
                }

作为示例,您可以从InkHunter应用程序的网页上查看以下图像:https://i1.wp.com/goosed.ie/wp-content/uploads/2016/10/inkhunter-cover-for-tattoo-ideas-1.jpg?fit=800%2C450&ssl=1

1 个答案:

答案 0 :(得分:0)

我找到了解决方法。

图片尺寸和图片通道数必须相同,并使用遮罩更快地处理图片。