Deepankar Baghel
Deepankar Baghel

Reputation: 51

Detect Rectangle in image and draw outline using open cv in android

I am developing application in which I have to detect rectangular object and draw outline I am using Open cv android library....

I succesfully detect Circle and draw outline inside image but repeatedly fail to detect Square or rectangle and draw....Here is my code to for circle..

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

any help for detect square/rectangle for android ......I am wondering from 2 days ..every example are in either C++ or in C++ and I can't get through that languages...

Thanks.

Upvotes: 5

Views: 8689

Answers (2)

Karunesh Palekar
Karunesh Palekar

Reputation: 2345

There are many ways of detecting a rectangle using opencv, the most appropriate way of doing this is by finding the contours after applying Canny Edge Detection.

Steps are as follows :- 1.Convert the image to MAT

  1. Grayscale the image

3.Apply Gausian Blur

4.Apply Morphology for filling the holes if any

5.Apply Canny Detection

6.Find Contours of the image

7.Find the largest contour of the rest

8.Draw the largest contour.

Code is as follows - 1.Convert the image to MAT

Utils.bitmapToMat(image,src)
  1. Grayscale the image
val gray = Mat(src.rows(), src.cols(), src.type())
  Imgproc.cvtColor(src, gray, Imgproc.COLOR_BGR2GRAY)

3.Apply Gausian Blur

Imgproc.GaussianBlur(gray, gray, Size(5.0, 5.0), 0.0)

4.Apply Morphology for filling the holes if any and also dilate the image

       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.Apply Canny Detection

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

6.Find Contours of the image

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

7.Find the largest contour of the rest

  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.Draw the largest contour which is the rectangle

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

There you go you have found the rectangle . If any error persist in getting the process .Try resizing the source Image to half of its height and width.

Have a look at the below link for proper Java code of the above explained https://github.com/dhananjay-91/DetectRectangle Also, https://github.com/aashari/android-opencv-rectangle-detector

Upvotes: 1

00zetti
00zetti

Reputation: 114

You are on the right way by using the Houghtransformation. Instead of using Houghcircles you have to use Houghlines and check the obtained lines for intersections. If you really have to find rectangles (and not 4 edged polygones) - you should look for lines with the same angle(+- a small offset) and if you found at least a pair of these lines you have to look for lines that lay perpendicular to this, find a pair as well and check for intersections. It should not be a big deal using vectors(endpoint - startpoint) and lines to perform the angle and intersection tests.

Upvotes: 0

Related Questions