/** * Locate rectangles in an image * * @param grayImage Grayscale image * @return Rectangle locations */ public RectangleLocationResult locateRectangles(Mat grayImage) { Mat gray = grayImage.clone(); // Filter out some noise Filter.downsample(gray, 2); Filter.upsample(gray, 2); Mat cacheHierarchy = new Mat(); Mat grayTemp = new Mat(); List<Rectangle> rectangles = new ArrayList<>(); List<Contour> contours = new ArrayList<>(); Imgproc.Canny(gray, grayTemp, 0, THRESHOLD_CANNY, APERTURE_CANNY, true); Filter.dilate(gray, 2); List<MatOfPoint> contoursTemp = new ArrayList<>(); // Find contours - the parameters here are very important to compression and retention Imgproc.findContours( grayTemp, contoursTemp, cacheHierarchy, Imgproc.CV_RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); // For each contour, test whether the contour is a rectangle // List<Contour> contours = new ArrayList<>(); MatOfPoint2f approx = new MatOfPoint2f(); for (MatOfPoint co : contoursTemp) { MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray()); Contour c = new Contour(co); // Attempt to fit the contour to the best polygon Imgproc.approxPolyDP( matOfPoint2f, approx, c.arcLength(true) * EPLISON_APPROX_TOLERANCE_FACTOR, true); Contour approxContour = new Contour(approx); // Make sure the contour is big enough, CLOSED (convex), and has exactly 4 points if (approx.toArray().length == 4 && Math.abs(approxContour.area()) > 1000 && approxContour.isClosed()) { // TODO contours and rectangles array may not match up, but why would they? contours.add(approxContour); // Check each angle to be approximately 90 degrees double maxCosine = 0; for (int j = 2; j < 5; j++) { double cosine = Math.abs( MathUtil.angle( approx.toArray()[j % 4], approx.toArray()[j - 2], approx.toArray()[j - 1])); maxCosine = Math.max(maxCosine, cosine); } if (maxCosine < MAX_COSINE_VALUE) { // Convert the points to a rectangle instance rectangles.add(new Rectangle(approx.toArray())); } } } return new RectangleLocationResult(contours, rectangles); }
private static Mat findLargestRectangle(Mat original_image) { Mat imgSource = original_image.clone(); // 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; MatOfPoint temp_contour = contours.get(0); // the largest is at the // index 0 for starting // point MatOfPoint2f approxCurve = new MatOfPoint2f(); 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; largest_contours.add(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(original_image, largest_contours, -1, new Scalar(0, 255, 0), 10); // Mat perspectiveTransform = new Mat(3, 3, CvType.CV_32FC1); // Imgproc.warpPerspective(original_image, imgSource, // perspectiveTransform, new Size(300,300)); Highgui.imwrite(output, original_image); // create the new image here using the largest detected square // Toast.makeText(getApplicationContext(), "Largest Contour: ", // Toast.LENGTH_LONG).show(); return imgSource; }
/** * Locate ellipses within an image * * @param grayImage Grayscale image * @return Ellipse locations */ public EllipseLocationResult locateEllipses(Mat grayImage) { Mat gray = grayImage.clone(); Filter.downsample(gray, 2); Filter.upsample(gray, 2); Imgproc.Canny(gray, gray, 5, 75, 3, true); Filter.dilate(gray, 2); Mat cacheHierarchy = new Mat(); List<MatOfPoint> contoursTemp = new ArrayList<>(); // Find contours - the parameters here are very important to compression and retention Imgproc.findContours( gray, contoursTemp, cacheHierarchy, Imgproc.CV_RETR_TREE, Imgproc.CHAIN_APPROX_TC89_KCOS); // List contours List<Contour> contours = new ArrayList<>(); for (MatOfPoint co : contoursTemp) { contours.add(new Contour(co)); } // Find ellipses by finding fit List<Ellipse> ellipses = new ArrayList<>(); for (MatOfPoint co : contoursTemp) { contours.add(new Contour(co)); // Contour must have at least 6 points for fitEllipse if (co.toArray().length < 6) continue; // Copy MatOfPoint to MatOfPoint2f MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray()); // Fit an ellipse to the current contour Ellipse ellipse = new Ellipse(Imgproc.fitEllipse(matOfPoint2f)); // Draw ellipse ellipses.add(ellipse); } return new EllipseLocationResult(contours, ellipses); }
public void run() { ArrayList<Geometry.Quad> squares; Mat image = new Mat(); Utils.bitmapToMat(source, image); Mat bwimage = new Mat(); cvtColor(image, bwimage, COLOR_RGB2GRAY); Mat blurred = new Mat(); medianBlur(image, blurred, 9); int width = blurred.width(); int height = blurred.height(); int depth = blurred.depth(); Mat gray0 = new Mat(width, height, depth); blurred.copyTo(gray0); squares = new ArrayList<Geometry.Quad>(); // find squares in every color plane of the image for (int c = 0; c < 3; c++) { Core.mixChannels( Arrays.asList(blurred), Arrays.asList(new Mat[] {gray0}), new MatOfInt(c, 0)); // try several threshold levels int thresholdLevel = 8; for (int l = 0; l < thresholdLevel; l++) { // use canny instead of 0 threshold level // canny helps catch squares with gradient shading Mat gray = new Mat(); if (l == 0) { Canny(gray0, gray, 10.0, 20.0, 3, false); Mat kernel = new Mat(11, 11, CvType.CV_8UC1, new Scalar(1)); dilate(gray, gray, kernel); } else { Mat thresh = new Mat(gray0.rows(), gray0.cols(), gray0.type()); threshold(gray0, thresh, ((double) l) / thresholdLevel * 255, 128, THRESH_BINARY_INV); cvtColor(thresh, gray, COLOR_BGR2GRAY); } // find contours and store them in a list List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); findContours(gray, contours, new Mat(), RETR_LIST, CHAIN_APPROX_SIMPLE); // test contours for (MatOfPoint contour : contours) { // approximate contour with accuracy proportional to the contour perimeter MatOfPoint2f thisContour = new MatOfPoint2f(contour.toArray()); double arclength = 0.02 * arcLength(thisContour, true); MatOfPoint2f approx = new MatOfPoint2f(); approxPolyDP(thisContour, approx, arclength, true); double area = contourArea(approx); boolean isConvex = isContourConvex(new MatOfPoint(approx.toArray())); if (approx.rows() == 4 && Math.abs(area) > SQUARE_SIZE && isConvex) { double maxCosine = 0; Point[] approxArray = approx.toArray(); for (int j = 2; j < 5; j++) { double cosine = Math.abs(angle(approxArray[j % 4], approxArray[j - 2], approxArray[j - 1])); maxCosine = Math.max(maxCosine, cosine); } if (maxCosine > THRESHOLD_COS) { squares.add(new Geometry.Quad(approxArray)); Log.d(TAG, "area = " + area); } } } } } result = new Bundle(); result.putParcelableArrayList("squares", squares); Log.d(TAG, "result created"); finish(); }
public static void getSquare(Mat imgSource) { Mat sourceImage = imgSource.clone(); 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 org.opencv.core.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; // Log.d("size",Integer.toString(contours.size())); MatOfPoint temp_contour = contours.get(0); // the largest is at the // index 0 for starting // point MatOfPoint2f approxCurve = new MatOfPoint2f(); MatOfPoint largest_contour = contours.get(0); // largest_contour.ge List<MatOfPoint> largest_contours = new ArrayList<MatOfPoint>(); // Imgproc.drawContours(imgSource,contours, -1, new Scalar(0, 255, 0), // 1); 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(); MatOfPoint2f approxCurve_temp = new MatOfPoint2f(); Imgproc.approxPolyDP(new_mat, approxCurve_temp, contourSize * 0.05, true); if (approxCurve_temp.total() == 4) { maxArea = contourarea; maxAreaIdx = idx; approxCurve = approxCurve_temp; largest_contour = temp_contour; } } } Imgproc.cvtColor(imgSource, imgSource, Imgproc.COLOR_BayerBG2RGB); double[] temp_double; temp_double = approxCurve.get(0, 0); Point p1 = new Point(temp_double[0], temp_double[1]); // Core.circle(imgSource,p1,55,new Scalar(0,0,255)); // Imgproc.warpAffine(sourceImage, dummy, rotImage,sourceImage.size()); temp_double = approxCurve.get(1, 0); Point p2 = new Point(temp_double[0], temp_double[1]); // Core.circle(imgSource,p2,150,new Scalar(255,255,255)); temp_double = approxCurve.get(2, 0); Point p3 = new Point(temp_double[0], temp_double[1]); // Core.circle(imgSource,p3,200,new Scalar(255,0,0)); temp_double = approxCurve.get(3, 0); Point p4 = new Point(temp_double[0], temp_double[1]); // Core.circle(imgSource,p4,100,new Scalar(0,0,255)); List<Point> source = getCorners(p1, p2, p3, p4); for (Point p : source) { // System.out.println(p); } Mat startM = Converters.vector_Point2f_to_Mat(source); // Imgproc.cvtColor(sourceImage, sourceImage, Imgproc.COLOR_BGR2GRAY); Mat result = warp(sourceImage, startM, 5); // result = warp(result,result,1); // Imgproc.cvtColor(result, result, Imgproc.COLOR_BGR2GRAY); Highgui.imwrite(output, result); // System.out.println("Done"); // return result; }