OpenCV中的Andr​​oid制作新的图像使用最大轮廓的边缘 [英] OpenCV Android Create New Image Using the Edges of the Largest Contour

查看:537
本文介绍了OpenCV中的Andr​​oid制作新的图像使用最大轮廓的边缘的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我能够识别图像中的最大的正方形/长方形(绿色)。然而,我想在图像中检测到的最大的正方形/矩形转换成新的图像(要被存储在新的垫)。

I am able to detect the largest square/rectangle (in green) in an image. However, I want to convert the largest square/rectangle detected in the image into a new image (to be stored in a new Mat).

下面是这个函数上有最大的矩形/平方米的返回图像: HTTP ://img153.imageshack.us/img153/9308/nn4w.png

Here's the return image of this function that has the largest rectangle/square on it: http://img153.imageshack.us/img153/9308/nn4w.png

下面是我的code迄今:

Here is my code so far:

private Mat findLargestRectangle(Mat original_image) {
    Mat imgSource = original_image;

    //convert the image to black and white
    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);

    //convert the image to black and white does (8 bit)
    Imgproc.Canny(imgSource, imgSource, 50, 50);

    //apply gaussian blur to smoothen lines of dots
    Imgproc.GaussianBlur(imgSource, imgSource, new Size(5, 5), 5);

    //find the contours
    List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
    Imgproc.findContours(imgSource, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    double maxArea = -1;
    int maxAreaIdx = -1;
    MatOfPoint temp_contour = contours.get(0); //the largest is at the index 0 for starting point
    MatOfPoint2f approxCurve = new MatOfPoint2f();
    Mat largest_contour = contours.get(0);
    List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>();
    for (int idx = 0; idx < contours.size(); idx++) {
        temp_contour = contours.get(idx);
        double contourarea = Imgproc.contourArea(temp_contour);
        //compare this contour to the previous largest contour found
        if (contourarea > maxArea) {
            //check if this contour is a square
            MatOfPoint2f new_mat = new MatOfPoint2f( temp_contour.toArray() );
            int contourSize = (int)temp_contour.total();
            Imgproc.approxPolyDP(new_mat, approxCurve, contourSize*0.05, true);
            if (approxCurve.total() == 4) {
                maxArea = contourarea;
                maxAreaIdx = idx;
                largest_contours.add(temp_contour);
                largest_contour = temp_contour;
            }
        }
    }
    MatOfPoint temp_largest = largest_contours.get(largest_contours.size()-1);
    largest_contours = new ArrayList<MatOfPoint>();
    largest_contours.add(temp_largest);

    Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BayerBG2RGB);
    Imgproc.drawContours(imgSource, largest_contours, -1, new Scalar(0, 255, 0), 1);

    //create the new image here using the largest detected square

    Toast.makeText(getApplicationContext(), "Largest Contour: ", Toast.LENGTH_LONG).show();

    return imgSource;
}

变量 largest_contours 是MatOfPoint的名单,但只包含了最大的轮廓,也存储在 largest_contour 变量。我怎样才能从可能最大的轮廓做一个新的形象?

The variable largest_contours is a list of MatOfPoint but only contains the largest contour, also stored in largest_contour variable. How can I possible make a new image from the largest contour?

我正在使用的Andr​​oid OpenCV的,有用于检测图像的几个教程,但不是在究竟如何使用Imgproc.warpPerspective()

I am using OpenCV in Android and there are few tutorials for detecting images but not exactly on how to use Imgproc.warpPerspective()

谢谢!

推荐答案

所有你需要的是找到这个轮廓的角落。您可以使用极值点方法。

All you need is to find the corners of this contour. You can use extreme points approach.

您应该简单地找出具有最小X和最小Y点(这是你的左上),最小X最大Y(这是你的左下角),依此类推。

You should simply find out the point having minimum x and minimum y (this is your topleft), minimum x maximum y (this is your bottom left), and so on.

在C ++中,有一个名为库的 algoritm 的有最小值/最大值方法。例如 min_element 会帮助你找到最低有X或Y的地步。不要忘记,包括头。

In C++, there is a library named algoritm which has min/max methods. For instance min_element will help you to find the point having minimum x or y. Don't forget to include header.

让你的4分后,您可以使用透视变换。

After having your 4 points, you can use perspective transform.

首先输入您的积分<一个href=\"http://docs.opencv.org/modules/imgproc/doc/geometric_transformations.html#getperspectivetransform\"相对=nofollow>这个方法。目标应该是

First input your points to this method. The destination should be

Point2f dest[4] = {(0,0),(image.width,0),(0,image.height),(image.height,image.width)}

有关你的情况。你从这个方法获得的基质(M)将通过改变你点到目的地另一种方法

for your case. The matrix (M) you obtain from this method will transform your points to destination using another method.

祝你好运。

编辑:在第二个想法;因为你的轮廓不是一个平行四边形,你有你的极值点为最小X = BOTTOMLEFT,最小Y =左上,等等。然后,它比较容易找到最小元素

On the second thought; since your contour is not a parallelogram, you have your extreme points as min x = bottomleft, min y = topleft, and so on. Then it is easier to find the minimum element.

这篇关于OpenCV中的Andr​​oid制作新的图像使用最大轮廓的边缘的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆