Ask Your Question

# Detect all Countour not an only Rectangle

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 close merge delete

## 1 answer

Sort by ยป oldest newest most voted

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

## Comments

above snippet of code drawcontour and detect all contour.

( 2019-12-10 08:40:15 -0600 )edit

Official site

GitHub

Wiki

Documentation

## Stats

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

Seen: 668 times

Last updated: Nov 23 '19