在Android中使用OpenCV检测图像中的矩形并绘制轮廓

5

我正在开发一个应用程序,需要检测矩形对象并绘制轮廓。我正在使用Open cv Android库......

我成功地检测了圆并在图像内部绘制了轮廓,但是一遍又一遍地无法检测到正方形或矩形并进行绘制....这是我的圆形代码...

Bitmap imageBmp = BitmapFactory.decodeResource(MainActivityPDF.this.getResources(),R.drawable.loadingplashscreen);

Mat imgSource = new Mat(), imgCirclesOut = new Mat();

Utils.bitmapToMat(imageBmp , imgSource);

    //grey opencv
Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BGR2GRAY);

Imgproc.GaussianBlur( imgSource, imgSource, new Size(9, 9), 2, 2 );
Imgproc.HoughCircles( imgSource, imgCirclesOut, Imgproc.CV_HOUGH_GRADIENT, 1, imgSource.rows()/8, 200, 100, 0, 0 );

float circle[] = new float[3];

for (int i = 0; i < imgCirclesOut.cols(); i++)
{
        imgCirclesOut.get(0, i, circle);
    org.opencv.core.Point center = new org.opencv.core.Point();
    center.x = circle[0];
    center.y = circle[1];
    Core.circle(imgSource, center, (int) circle[2], new Scalar(255,0,0,255), 4);
    }
    Bitmap bmp = Bitmap.createBitmap(imageBmp.getWidth(), imageBmp.getHeight(), Bitmap.Config.ARGB_8888);

    Utils.matToBitmap(imgSource, bmp);


    ImageView frame = (ImageView) findViewById(R.id.imageView1);

    //Bitmap bmp = Bitmap.createBitmap(100, 100, Bitmap.Config.ARGB_8888);
    frame.setImageBitmap(bmp);

有关在安卓设备中检测正方形/矩形的任何帮助......我已经想了2天,每个例子都是用C++编写的,而我无法理解这些编程语言......

谢谢。


你是在寻找轴对齐的矩形还是可以旋转的矩形? - cxyzs7
谢谢回复。请给我关于轴对齐矩形的想法。 - Deepankar Baghel
当然,例如http://jamessadlier.files.wordpress.com/2012/01/aligned.png,蓝色的是轴对齐的,红色的则不是。 - cxyzs7
谢谢你解决我的疑惑,实际上我的问题是,如果我从相机中拍摄一张图片,然后需要检测任意位置的长方形,例如对齐或旋转...你有相关的链接或示例吗?针对Android系统的...感谢。 - Deepankar Baghel
@Deepankar Baghel:你找到解决问题的方法了吗? - Sohaib
2个回答

1

使用OpenCV检测矩形有多种方法,最适合的方法是在应用Canny边缘检测后查找轮廓。

步骤如下: 1.将图像转换为MAT格式

  1. 将图像转换为灰度图像

3.应用高斯模糊

4.如果有空洞,则应用形态学填充

5.应用Canny检测

6.查找图像的轮廓

7.找到其余轮廓中最大的轮廓

8.绘制最大轮廓。

代码如下 - 1.将图像转换为MAT格式

Utils.bitmapToMat(image,src)

将图像转为灰度。
val gray = Mat(src.rows(), src.cols(), src.type())
  Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY)

3.应用高斯模糊
Imgproc.GaussianBlur(gray, gray, Size(5.0, 5.0), 0.0)

4.如果有空洞,请应用形态学填充,并膨胀图像。

       val kernel = Imgproc.getStructuringElement(
           Imgproc.MORPH_ELLIPSE, Size(
               5.0,
               5.0
           )
       )
       Imgproc.morphologyEx(
           gray,
           gray,
           Imgproc.MORPH_CLOSE,
           kernel
       ) // fill holes
       Imgproc.morphologyEx(
           gray,
           gray,
           Imgproc.MORPH_OPEN,
           kernel
       ) //remove noise
       Imgproc.dilate(gray, gray, kernel)

5.应用Canny检测

   val edges = Mat(src.rows(), src.cols(), src.type())
   Imgproc.Canny(gray, edges, 75.0, 200.0)

6.查找图像的轮廓

   val contours = ArrayList<MatOfPoint>()
        val hierarchy = Mat()
        Imgproc.findContours(
            edges, contours, hierarchy, Imgproc.RETR_LIST,
            Imgproc.CHAIN_APPROX_SIMPLE
        )

7.找到其余部分中最大的轮廓

  public int findLargestContour(ArrayList<MatOfPoint> contours) {

        double maxVal = 0;
        int maxValIdx = 0;
        for (int contourIdx = 0; contourIdx < contours.size(); contourIdx++) {
            double contourArea = Imgproc.contourArea(contours.get(contourIdx));
            if (maxVal < contourArea) {
                maxVal = contourArea;
                maxValIdx = contourIdx;
            }
        }


        return maxValIdx;

    }

8.绘制最大的轮廓,即矩形

  Imgproc.drawContours(src, contours, idx, Scalar(0.0, 255.0, 0.0), 3)

你已经找到了矩形。 如果在过程中出现任何错误,请尝试将源图像的高度和宽度缩小一半。
请查看以下链接以获取上述内容的适当Java代码 https://github.com/dhananjay-91/DetectRectangle 另外, https://github.com/aashari/android-opencv-rectangle-detector

0

使用Hough变换是正确的方法。不要使用Hough圆,而是使用Hough线,并检查所得到的线是否相交。如果你真的需要找到矩形(而不是四边形),你应该寻找具有相同角度(±一个小偏移量)的线条,如果你至少找到一对这样的线条,你就必须寻找垂直于此的线条,再找到一对并检查它们的交点。使用向量(端点-起点)和线条执行角度和交点测试不应该是什么大问题。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接