Ask Your Question
-1

Detect all Countour not an only Rectangle

asked 2019-06-20 02:34:30 -0600

Jayapriya gravatar image

updated 2019-12-10 01:09:03 -0600

Akhil Patel gravatar image

1.apply Gaussian blur 2.then canny edge detection 3.find contours 4.find largest contours of rectangle 5.it Detect all Countours All

Question 1.But it detect all Contour . 2. In case Edge not Closed, Contour are also not Closed.But When detect document

My code

 int maxId = -1;
int maxAreaIdx = -1;double maxArea = -1;;
List<MatOfPoint> contours = new ArrayList<MatOfPoint>();


private Mat findRectangle3(Mat src) throws Exception {
    Mat blurred = src.clone();
    Imgproc.medianBlur(src, blurred, 9);

    Mat gray0 = new Mat(blurred.size(), CvType.CV_8U), gray = new Mat();


    List<Mat> blurredChannel = new ArrayList<Mat>();
    blurredChannel.add(blurred);
    List<Mat> gray0Channel = new ArrayList<Mat>();
    gray0Channel.add(gray0);

    MatOfPoint2f approxCurve;



    for (int c = 0; c < 3; c++) {
        int ch[] = { c, 0 };
        Core.mixChannels(blurredChannel, gray0Channel, new MatOfInt(ch));

        int thresholdLevel = 1;
        for (int t = 0; t < thresholdLevel; t++) {
            if (t == 0) {
                Imgproc.Canny(gray0, gray, 10, 20, 3, true); // true ?
                Imgproc.dilate(gray, gray, new Mat(), new Point(-1, -1), 1); // 1
                // ?
            } else {
                Imgproc.adaptiveThreshold(gray0, gray, thresholdLevel,
                        Imgproc.ADAPTIVE_THRESH_GAUSSIAN_C,
                        Imgproc.THRESH_BINARY,
                        (src.width() + src.height()) / 200, t);
            }

            Imgproc.findContours(gray, contours, new Mat(),
                    Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

            for (MatOfPoint contour : contours) {
                MatOfPoint2f temp = new MatOfPoint2f(contour.toArray());

                double area = Imgproc.contourArea(contour);
                approxCurve = new MatOfPoint2f();
                Imgproc.approxPolyDP(temp, approxCurve,
                        Imgproc.arcLength(temp, true) * 0.02, true);

                if (approxCurve.total() == 4 && area >= maxArea&&area>=100) {
                    double maxCosine = 0;

                    List<Point> curves = approxCurve.toList();
                    for (int j = 2; j < 5; j++) {

                        double cosine = Math.abs(angle(curves.get(j % 4), curves.get(j - 2), curves.get(j - 1)));
                        maxCosine = Math.max(maxCosine, cosine);
                    }

                    if (maxCosine < 0.3) {
                        maxArea = area;
                        maxId = contours.indexOf(contour);
                    }
                }
            }
        }
    }

    if (maxId >= 0) {
        Log.d("maxmiumId","====="+maxId);
        Imgproc.drawContours(src, contours, maxId, new Scalar(255, 0, 0,
                .8), 2);

    }
    return src;
}
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2019-06-21 22:35:01 -0600

Akhil Patel gravatar image

updated 2019-11-23 02:06:29 -0600

Please visit the following link :

I have snippet of code which can help you to find the largest contour area of rectangle.

protected Bitmap findEdges(Bitmap rotatedBitmap) {

 Mat rgba = new Mat();
 Utils.bitmapToMat(rotatedBitmap, rgba);

 Mat edges = new Mat(rgba.size(), CV_8UC1);
 Imgproc.cvtColor(rgba, edges, Imgproc.COLOR_RGB2GRAY, 4);
 Canny(edges, edges, 80, 100);

 Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888);
 Utils.matToBitmap(edges, resultBitmap);

 // https://github.com/daisygao/ScannerLites
 Mat rgbMat = new Mat();
 Mat grayMat = new Mat();
 Mat cannyMat;
 Mat linesMat = new Mat();
 BitmapFactory.Options o = new BitmapFactory.Options();


 // define the destination image size: A4 - 200 PPI
 int w_a4 = 1654, h_a4 = 2339;

 // TODO: 29/08/2016  May need to check sample size https://developer.android.com/training/displaying-bitmaps/load-bitmap.html
 o.inSampleSize = 4;
 o.inDither = false;


 ByteArrayOutputStream baos = new ByteArrayOutputStream();
 rotatedBitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
 byte[] b = baos.toByteArray();

 try {
     // resize
     rotatedBitmap = BitmapFactory.decodeByteArray(b, 0, b.length);
 } catch (OutOfMemoryError error) {
     error.printStackTrace();
 }


 int w = rotatedBitmap.getWidth();

 int h = rotatedBitmap.getHeight();
 int min_w = 800;
 double scale = Math.min(10.0, w * 1.0 / min_w);
 int w_proc = (int)(w * 1.0 / scale);
 int h_proc = (int)(h * 1.0 / scale);
 Bitmap srcBitmap = Bitmap.createScaledBitmap(rotatedBitmap, w_proc, h_proc, false);

 Utils.bitmapToMat(srcBitmap, rgbMat); //convert original bitmap to Mat, R G B.

 // grayscale
 Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY); //rgbMat to gray grayMat

 // canny
 cannyMat = getCanny(grayMat);

 // HoughLinesP

 Imgproc.HoughLinesP(cannyMat, linesMat, 1, Math.PI / 280, w_proc / 12, w_proc / 12, 20);

 // Calculate horizontal lines and vertical lines
 Log.e("opencv", "lines.cols " + linesMat.cols() + " w_proc/3: " + w_proc / 3);
 List < Line > horizontals = new ArrayList < > ();
 List < Line > verticals = new ArrayList < > ();
 for (int x = 0; x < linesMat.rows(); x++) {
     double[] vec = linesMat.get(x, 0);
     double x1 = vec[0],
         y1 = vec[1],
         x2 = vec[2],
         y2 = vec[3];
     Point start = new Point(x1, y1);
     Point end = new Point(x2, y2);
     Line line = new Line(start, end);
     if (Math.abs(x1 - x2) > Math.abs(y1 - y2)) {
         horizontals.add(line);
     } else {
         verticals.add(line);
     }

     // for visualization in debug mode
     if (BuildConfig.DEBUG) {}
 }

 Log.e("HoughLines", "completed HoughLines");
 Log.e("HoughLines", "linesMat size: " + linesMat.size());
 Log.e("Lines Detected", Integer.toString(linesMat.rows()));


 // if we don't have at least 2 horizontal lines or vertical lines
 if (horizontals.size() < 2) {
     if (horizontals.size() == 0 || horizontals.get(0)._center.y > h_proc / 2) {
         horizontals.add(new Line(new Point(0, 0), new Point(w_proc - 1, 0)));
     }
     if (horizontals.size() == 0 || horizontals.get(0)._center.y <= h_proc / 2) {
         horizontals.add(new Line(new Point(0, h_proc - 1), new Point(w_proc - 1, h_proc - 1)));
     }
 }
 if (verticals.size() < 2) {
     if (verticals.size() == 0 || verticals.get(0)._center.x > w_proc / 2) {
         verticals.add(new Line(new Point(0, 0), new Point(h_proc - 1, 0)));
     }
     if (verticals.size() == 0 || verticals.get(0)._center.x <= w_proc / 2) {
         verticals.add(new Line(new Point(w_proc - 1, 0), new Point(w_proc - 1, h_proc - 1)));
     }
 }

 Collections.sort(horizontals ...
(more)
edit flag offensive delete link more

Comments

above snippet of code drawcontour and detect all contour.

Akhil Patel gravatar imageAkhil Patel ( 2019-12-10 08:40:15 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2019-06-20 02:34:30 -0600

Seen: 698 times

Last updated: Nov 23 '19