所以我想在图像周围绘制一个矩形。 我正在使用Open CV从较大的图像中找到一个子图像。 我的计算方法是将模板图​​像(目标)和目标图像(场景)都转换为HSV,并获得对象的背投影,并将其与饱和的场景图像进行比较。 有点用。 (将为任何改进感到高兴)。 基本上,我想在图像周围绘制一个rect并将提取的rect从场景提取到Mat。 我尝试了几种方法来做,但似乎没有用。 这是我的代码。 我的问题是如何从目标图像获取子图像?

public List<DMatch> subListGoodMatches(List<DMatch> good_matches) {
        Collections.sort(good_matches, (DMatch o1, DMatch o2) -> {
            if (o1.distance < o2.distance) {
                return -1;
            }
            if (o1.distance > o2.distance) {
                return 1;
            }
            return 0;
        });

        if (good_matches.size() > 10) {
            good_matches = good_matches.subList(0, 10);
        }

        return good_matches;
    }

    public List<Mat> calculateHistograms(Mat image) {
        Imgproc.cvtColor(image, image, Imgproc.COLOR_BGR2HSV);

        List<Mat> hsv_planes = new ArrayList<Mat>();
        Core.split(image, hsv_planes);

        MatOfInt histSize = new MatOfInt(256);
        final MatOfFloat histRange = new MatOfFloat(0f, 256f);
        boolean accumulate = true;

        Mat h_hist = new Mat();
        Mat s_hist = new Mat();
        Mat v_hist = new Mat();

        //Break channels
        List<Mat> h_plane = new ArrayList<Mat>();
        List<Mat> s_plane = new ArrayList<Mat>();
        List<Mat> v_plane = new ArrayList<Mat>();

        h_plane.add(hsv_planes.get(0));
        s_plane.add(hsv_planes.get(1));
        v_plane.add(hsv_planes.get(2));

        Imgproc.calcHist(h_plane, new MatOfInt(0), new Mat(), h_hist, histSize, histRange, accumulate);
        Imgproc.calcHist(s_plane, new MatOfInt(0), new Mat(), s_hist, histSize, histRange, accumulate);
        Imgproc.calcHist(v_plane, new MatOfInt(0), new Mat(), v_hist, histSize, histRange, accumulate);

        //Draw combined histograms
        int hist_w = 512;
        int hist_h = 600;
        long bin_w = Math.round((double) hist_w / 256);

        Mat histImage = new Mat(hist_h, hist_w, CvType.CV_8UC3, new Scalar(0, 0, 0));
        Core.normalize(h_hist, h_hist, 3, histImage.rows(), Core.NORM_MINMAX, -1, new Mat());
        Core.normalize(s_hist, s_hist, 3, histImage.rows(), Core.NORM_MINMAX, -1, new Mat());
        Core.normalize(v_hist, v_hist, 3, histImage.rows(), Core.NORM_MINMAX, -1, new Mat());

        for (int i = 1; i < 256; i++) {
            Point p1 = new Point(bin_w * (i - 1), hist_h - Math.round(h_hist.get(i - 1, 0)[0]));
            Point p2 = new Point(bin_w * (i), hist_h - Math.round(h_hist.get(i, 0)[0]));
            Core.line(histImage, p1, p2, RED, 2, 8, 0);

            Point p3 = new Point(bin_w * (i - 1), hist_h - Math.round(s_hist.get(i - 1, 0)[0]));
            Point p4 = new Point(bin_w * (i), hist_h - Math.round(s_hist.get(i, 0)[0]));
            Core.line(histImage, p3, p4, GREEN, 2, 8, 0);

            Point p5 = new Point(bin_w * (i - 1), hist_h - Math.round(v_hist.get(i - 1, 0)[0]));
            Point p6 = new Point(bin_w * (i), hist_h - Math.round(v_hist.get(i, 0)[0]));
            Core.line(histImage, p5, p6, BLUE, 2, 8, 0);

        }

        Highgui.imwrite("img-histogram.jpg", histImage);
        System.out.println("Hist size is: " + hsv_planes.size());

        List<Mat> histograms = new ArrayList<Mat>();
        histograms.add(h_hist);
        histograms.add(s_hist);
        histograms.add(v_hist);

        return histograms;
    }

    public Mat identifyLowSat(Mat image) {

        Mat hsvTargetImage = new Mat();
        Imgproc.cvtColor(image, hsvTargetImage, Imgproc.COLOR_BGR2HSV);
        List<Mat> hsv_planes = new ArrayList<Mat>();
        Core.split(hsvTargetImage, hsv_planes);

        //Get saturation channel
        Mat s_hist = hsv_planes.get(1);

        Imgproc.threshold(s_hist, s_hist, 65, 255, Imgproc.THRESH_BINARY);

        Highgui.imwrite("img-saturation.png", s_hist);

        return s_hist;
    }

    public Mat getBackProjOfHueTemplate(Mat image, Mat hue_histogram) {

        Mat hsvTargetImage = new Mat();
        Imgproc.cvtColor(image, hsvTargetImage, Imgproc.COLOR_BGR2HSV);
        List<Mat> hsv_planes = new ArrayList<Mat>();
        Core.split(hsvTargetImage, hsv_planes);

        Mat backProj = new Mat();
        final MatOfFloat range = new MatOfFloat(0f, 256f);

        Imgproc.calcBackProject(hsv_planes, new MatOfInt(0), hue_histogram, backProj, range, 4);

        Highgui.imwrite("img-backProj.png", backProj);

        return backProj;
    }

    public Mat meanShift(Mat image) {
        Mat map = new Mat();
        Rect rect = new Rect();
        TermCriteria term = new TermCriteria();

        term.maxCount = 100;
        term.type = TermCriteria.EPS;
        term.epsilon = 0.1;

        Imgproc.pyrMeanShiftFiltering(image, map, 0.5, 0.5, 5, term);

        Highgui.imwrite("img-meanshift.png", map);
        return map;
    }

    public MatOfDMatch filterMatches(Mat img1, Mat img2) {

        FeatureDetector detector = FeatureDetector.create(FeatureDetector.SIFT);
        DescriptorExtractor descriptor = DescriptorExtractor.create(DescriptorExtractor.BRISK);
        DescriptorMatcher matcher = DescriptorMatcher.create(DescriptorMatcher.BRUTEFORCE_HAMMING);

        // First photo
        //Imgproc.cvtColor(img1, img1, Imgproc.COLOR_RGB2GRAY);
        Mat descriptors1 = new Mat();
        MatOfKeyPoint keypoints1 = new MatOfKeyPoint();

        detector.detect(img1, keypoints1);
        descriptor.compute(img1, keypoints1, descriptors1);

        // Second photo
        //Imgproc.cvtColor(img2, img2, Imgproc.COLOR_RGB2GRAY);
        Mat descriptors2 = new Mat();
        MatOfKeyPoint keypoints2 = new MatOfKeyPoint();

        detector.detect(img2, keypoints2);
        descriptor.compute(img2, keypoints2, descriptors2);

        // Matching
        MatOfDMatch matches = new MatOfDMatch();
        MatOfDMatch filteredMatches = new MatOfDMatch();
        matcher.match(descriptors1, descriptors2, matches);

        List<DMatch> matchesList = matches.toList();
        Double max_dist = Double.MIN_VALUE;
        Double min_dist = Double.POSITIVE_INFINITY;

        for (DMatch matchesList1 : matchesList) {
            Double dist = (double) matchesList1.distance;
            if (dist < min_dist) {
                min_dist = dist;
            }
            if (dist > max_dist) {
                max_dist = dist;
            }
        }

        LinkedList<DMatch> good_matches = new LinkedList<DMatch>();
        for (DMatch matchesList1 : matchesList) {
            if (matchesList1.distance <= (1.5 * min_dist)) {
                good_matches.addLast(matchesList1);
            }
        }

        MatOfDMatch goodMatches = new MatOfDMatch();
        //goodMatches.fromList(good_matches);
        List<DMatch> newGood_Matches = subListGoodMatches(good_matches);
        goodMatches.fromList(newGood_Matches);

        //put keypoints mats into lists
        List<KeyPoint> keypoints1_List = keypoints1.toList();
        List<KeyPoint> keypoints2_List = keypoints2.toList();

        //put keypoints into point2f mats so calib3d can use them to find homography
        LinkedList<Point> objList = new LinkedList<Point>();
        LinkedList<Point> sceneList = new LinkedList<Point>();
        for (int i = 0; i < newGood_Matches.size(); i++) {
            objList.addLast(keypoints2_List.get(newGood_Matches.get(i).trainIdx).pt);
            sceneList.addLast(keypoints1_List.get(newGood_Matches.get(i).queryIdx).pt);
        }
        MatOfPoint2f obj = new MatOfPoint2f();
        MatOfPoint2f scene = new MatOfPoint2f();
        obj.fromList(objList);
        scene.fromList(sceneList);

        System.out.println(matches.size() + " " + goodMatches.size());

        //output image
        Mat outputImg = new Mat();
        MatOfByte drawnMatches = new MatOfByte();
        Features2d.drawMatches(img1, keypoints1, img2, keypoints2, goodMatches, outputImg, Scalar.all(-1), Scalar.all(-1), drawnMatches, Features2d.NOT_DRAW_SINGLE_POINTS);

        Highgui.imwrite("img-matches.png", outputImg);
        drawWithRect(img1, img2, obj, scene, outputImg);

        keypointers1 = keypoints1;
        keypointers2 = keypoints2;

        return goodMatches;
    }

    public MatOfDMatch filterMatchesByHomography(MatOfDMatch matches) {
        MatOfKeyPoint keypoints1 = keypointers1;
        MatOfKeyPoint keypoints2 = keypointers2;

        List<Point> lp1 = new ArrayList<Point>();
        List<Point> lp2 = new ArrayList<Point>();

        KeyPoint[] k1 = keypoints1.toArray();
        KeyPoint[] k2 = keypoints2.toArray();

        List<DMatch> matches_original = matches.toList();

        if (matches_original.size() < 4) {
            MatOfDMatch mat = new MatOfDMatch();
            return mat;
        }

        // Add matches keypoints to new list to apply homography
        for (DMatch match : matches_original) {
            Point kk1 = k1[match.queryIdx].pt;
            Point kk2 = k2[match.trainIdx].pt;
            lp1.add(kk1);
            lp2.add(kk2);
        }

        //srcPoints = new MatOfPoint2f(lp1.toArray(new Point[0]));
        //dstPoints = new MatOfPoint2f(lp2.toArray(new Point[0]));

        Mat mask = new Mat();
        //Mat homography = Calib3d.findHomography(srcPoints, dstPoints, Calib3d.LMEDS, 0.2, mask);
        List<DMatch> matches_homo = new ArrayList<DMatch>();
        int size = (int) mask.size().height;
        for (int i = 0; i < size; i++) {
            if (mask.get(i, 0)[0] == 1) {
                DMatch d = matches_original.get(i);
                matches_homo.add(d);
            }
        }

        MatOfDMatch mat = new MatOfDMatch();
        mat.fromList(matches_homo);

        //Highgui.imwrite("img-matchesWithRect.png", mat);
        return mat;
    }

    public void drawMatches(Mat img1, Mat img2, MatOfDMatch matches, boolean imageOnly) {
        Mat out = new Mat();

        MatOfKeyPoint key2 = keypointers2;
        MatOfKeyPoint key1 = keypointers1;

        //Imgproc.cvtColor(img1, im1, Imgproc.COLOR_BGR2RGB);
        //Imgproc.cvtColor(img2, im2, Imgproc.COLOR_BGR2RGB);
        if (imageOnly) {
            MatOfDMatch emptyMatch = new MatOfDMatch();
            MatOfKeyPoint emptyKey1 = new MatOfKeyPoint();
            MatOfKeyPoint emptyKey2 = new MatOfKeyPoint();
            Features2d.drawMatches(img1, emptyKey1, img2, emptyKey2, emptyMatch, out);
        } else {
            Features2d.drawMatches(img1, key1, img2, key2, matches, out);
        }

        //Imgproc.cvtColor(out, out, Imgproc.COLOR_BGR2RGB);
        Core.putText(out, "FRAME", new Point(img1.width() / 2, 30), Core.FONT_HERSHEY_PLAIN, 2, new Scalar(0, 255, 255), 3);
        Core.putText(out, "MATCHED", new Point(img1.width() + img2.width() / 2, 30), Core.FONT_HERSHEY_PLAIN, 2, new Scalar(255, 0, 0), 3);

        Highgui.imwrite("img-drawnMatches.png", out);
    }

    public void drawWithRect(Mat img1, Mat img2, MatOfPoint2f obj, MatOfPoint2f scene, Mat outputImg){
        //run homography on object and scene points
        Mat H = Calib3d.findHomography(obj, scene, Calib3d.RANSAC, 5);
        Mat tmp_corners = new Mat(4, 1, CvType.CV_32FC2);
        Mat scene_corners = new Mat(4, 1, CvType.CV_32FC2);

        //get corners from object
        tmp_corners.put(0, 0, new double[]{0, 0});
        tmp_corners.put(1, 0, new double[]{img2.cols(), 0});
        tmp_corners.put(2, 0, new double[]{img2.cols(), img2.rows()});
        tmp_corners.put(3, 0, new double[]{0, img2.rows()});

        Core.perspectiveTransform(tmp_corners, scene_corners, H);

        Core.line(outputImg, new Point(scene_corners.get(0, 0)), new Point(scene_corners.get(1, 0)), new Scalar(0, 255, 0), 4);
        Core.line(outputImg, new Point(scene_corners.get(1, 0)), new Point(scene_corners.get(2, 0)), new Scalar(0, 255, 0), 4);
        Core.line(outputImg, new Point(scene_corners.get(2, 0)), new Point(scene_corners.get(3, 0)), new Scalar(0, 255, 0), 4);
        Core.line(outputImg, new Point(scene_corners.get(3, 0)), new Point(scene_corners.get(0, 0)), new Scalar(0, 255, 0), 4);

        Highgui.imwrite("img-matchesWithRect.png", outputImg);
    }

主要方法:

public static void main(String args[]) {
        System.load(new File("/usr/local/Cellar/opencv/2.4.9/share/OpenCV/java/libopencv_java249.dylib").getAbsolutePath());

        Mat img1 = Highgui.imread(scenesD);
        Mat img2 = Highgui.imread(objectD);

        MeanShift Tester = new MeanShift();
        List<Mat> histogramsList;
        Mat hue_histogram;
        Mat saturationChannel;
        Mat getBackProjOfHueTemp;

        //Calulate Histogram of Object
        histogramsList = Tester.calculateHistograms(img2);

        //Get saturation channel of scene
        saturationChannel = Tester.identifyLowSat(img1);

        //Get hue of calculated object histogram
        hue_histogram = histogramsList.get(0);

        //Get back projection of object from calculated hue histogram template
        getBackProjOfHueTemp = Tester.getBackProjOfHueTemplate(img2, hue_histogram);

        //Filtering matches
        MatOfDMatch matches = Tester.filterMatches(saturationChannel, getBackProjOfHueTemp);
        MatOfDMatch homo_matches = Tester.filterMatchesByHomography(matches);

        //Draw img unto screen;
        Tester.drawMatches(saturationChannel, getBackProjOfHueTemp, homo_matches, false);
    }

到目前为止,这是我得到的最终图像(img-matches.png) 在此处输入图片说明

并尝试从图像中获取直肠给我这个(img-matchesWithRect.png) 在此处输入图片说明

===============>>#1 票数:-1

好的,因此您在原始图像中具有Point ,发现目标图像中有Point 这些点都具有xy坐标-要找到“子图像”(或图像中的矩形),您要做的就是取所有x的最小值以获取左上角的x坐标,即最小值y s获取左上y坐标, x s最大值获取右下x坐标, y s最大值获取右下y坐标。

然后使用它们可以创建一个Recthttp://docs.opencv.org/java/org/opencv/core/Rect.html )并使用它来访问子图像:image(Rect)(假设您有一个先前的变量) imageMat ):

Rect sub_rect = new Rect(min_x, min_y, max_x - min_x, max_y - min_y);
Mat sub_region = image(sub_rect);

现在, sub_region将在其中包含您的子区域。

  ask by Daniel translate from so

未解决问题?本站智能推荐:

1回复

使用opencv java检测图像中文档的边界

我想在android中检测文档的4个角。 我使用opencv库。 Iam使用以下方法 - (1)灰度图像(2)应用中值模糊(3)应用自适应阈值(4)Canny边缘检测(5)找到轮廓(6)找到最大轮廓(7)得到边缘和角点最大的轮廓 我的代码是 在精确边缘检测之后,许多点处的轮
1回复

需要开放式简历算法书吗? [关闭]

嗨,大家好, 目前,我正在为Android开发图像处理库,我需要一本书/ pdf文档,其中包含在开放Cv中实现的所有算法。 谢谢!!
2回复

Android中的乐谱图像上的线条检测

我正在从事有关光学音乐识别的Android项目。 我通过移动相机拍摄了乐谱的照片,并尝试识别音符和符号。 我对预处理后的方法学非常熟悉,但是这类工作通常是在扫描仪的帮助下完成的。 (相反,我必须使用移动相机) 直观地讲,我先使用hough变换检测梯级(谱线),然后计算它们与水平轴之间
1回复

在android中使用边缘检测选择区域后裁剪图像

我想自动选择要稍后裁剪的页面区域。 我认为边缘检测可能是有用的,并使用canny边缘检测来查找图像的边缘。 现在我有这个形象! 但我不清楚选择页面区域为矩形。 任何人都可以建议这个问题的方法或实现? 我真正想要做的是选择页面区域如下。 有没有其他方法可以做到这一点? 我还在使用m
1回复

如何使用Opencv检测具有不同对比度和背景色的图像边缘?

我正在开发一个Android应用程序,以检测所有图像轮廓并使用Opencv绘制它们。 我正在同一张图像上进行测试,并且一切正常。 但是,一旦我更改了同一图像但对比度不同,检测就会失败。 另外,我更改了另一个具有较暗背景的示例图像,并且再次失败。 这是代码: 这是第
1回复

如何在Android中使用Opencv将Canny边缘检测器有效地应用于图像?

我正在制作一个Android应用程序以从图像中检测多个对象,然后处理这些对象并将它们与参考对象进行比较以检测异常。 我在python中测试了不同的图像边缘检测器,Prewitt运算符为我提供了最佳结果,如下所示:https://i.imgur.com/4iwOx9s.png对于android,
2回复

OpenCV检测钻孔

我正在一个项目中,我必须检测表面上的钻孔。 (顶部两个孔,仅用于定向目的) 在检测到孔之后,图案将判断孔的位置并给出结果。 我已经创建了一个覆盖网格布局,并将其放置在camera2api预览上,以便用户可以对齐孔并进行扫描(真正的测试不会是LCD屏幕上的图片,如屏幕截图所示)
3回复

使用OpenCV进行椭圆检测

我想用OpenCV for Android检测省略号,使用OpenCV 2.4.1包中的Tutorial 2-Basic作为起点。 请注意,我的椭圆将是一个完美的Photoshop。 根据我的理解,使用“HoughCircles”只会找到完美(或如此)的圆圈,从而留下椭圆。 任何帮
1回复

OpenCV颜色检测为黄色

这是来自OpenCV ColorBlobDetectionActivity.java示例的程序,我试图对其进行修改,以便在触摸屏幕时它可以检测到黄色物体,但是即使我将颜色Scalar指定为黄色,它也始终可以检测到黑色物体。 我在我认为相关的地方发表了“注意”的评论。 任何帮助,将不胜感
1回复

如何在Android OpenCV中检测轮廓的宽度和高度

我创建了轮廓并绘制了一个矩形。 现在需要检测我的矩形的宽度和高度怎么办?