/** * 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; }
public static Mat getCCH(Mat image) { ArrayList<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Mat hierarchy = new Mat(); Imgproc.findContours( image, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_NONE); Mat chainHistogram = Mat.zeros(1, 8, CvType.CV_32F); int n = 0; MatOfPoint2f approxCurve = new MatOfPoint2f(); for (MatOfPoint contour : contours) { // get the freeman chain code from the contours int rows = contour.rows(); // System.out.println("\nrows"+rows+"\n"+contour.dump()); int direction = 7; Mat prevPoint = contours.get(0).row(0); n += rows - 1; for (int i = 1; i < rows; i++) { // get the current point double x1 = contour.get(i - 1, 0)[1]; double y1 = contour.get(i - 1, 0)[0]; // get the second point double x2 = contour.get(i, 0)[1]; double y2 = contour.get(i, 0)[0]; if (x2 == x1 && y2 == y1 + 1) direction = 0; else if (x2 == x1 - 1 && y2 == y1 + 1) direction = 1; else if (x2 == x1 - 1 && y2 == y1) direction = 2; else if (x2 == x1 - 1 && y2 == y1 - 1) direction = 3; else if (x2 == x1 && y2 == y1 - 1) direction = 4; else if (x2 == x1 + 1 && y2 == y1 - 1) direction = 5; else if (x2 == x1 + 1 && y2 == y1) direction = 6; else if (x2 == x1 + 1 && y2 == y1 + 1) direction = 7; else System.out.print("err"); double counter = chainHistogram.get(0, direction)[0]; chainHistogram.put(0, direction, ++counter); System.out.print(direction); } } System.out.println("\n" + chainHistogram.dump()); Scalar alpha = new Scalar(n); // the factor Core.divide(chainHistogram, alpha, chainHistogram); System.out.println("\nrows=" + n + " " + chainHistogram.dump()); return chainHistogram; }
public static Point getFirstPoint(MatOfPoint o) { Point zero = new Point(0, 0); Point first = new Point(Double.MAX_VALUE, Double.MAX_VALUE); double minDist = Double.MAX_VALUE; for (Point point : o.toList()) { double dist = Util.euclideanDist(zero, point); if (dist < minDist) { first = point; minDist = dist; } } return first; }
/** * 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 static int identify_R_U(Mat binary) { // 0: hull points identified < 2 // 1: R // 2: U List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); List<MatOfPoint> hullPoints = new ArrayList<MatOfPoint>(); List<Point> hullPointList = new ArrayList<Point>(); List<Point> filteredPointList = new ArrayList<Point>(); MatOfPoint hullPointMat = new MatOfPoint(); MatOfInt hull = new MatOfInt(); Mat hierarchy = new Mat(); // Find contour Imgproc.findContours( binary, contours, hierarchy, Imgproc.RETR_TREE, Imgproc.CHAIN_APPROX_SIMPLE); // Find convex hull for (int k = 0; k < contours.size(); k++) { Imgproc.convexHull(contours.get(k), hull); for (int j = 0; j < hull.toList().size(); j++) { hullPointList.add(contours.get(k).toList().get(hull.toList().get(j))); } hullPointMat.fromList(hullPointList); hullPoints.add(hullPointMat); } // Filter hull points. Only hull points relevant to hull classification // will remain. // Also, count the number of filtered hull points in left and right. for (int l = 0; l < hullPointList.size(); l++) { if (hullPointList.get(l).y < binary.rows() * 0.25) { if (l != hullPointList.size() - 1) { if (Math.hypot( hullPointList.get(l).x - hullPointList.get(l + 1).x, hullPointList.get(l).y - hullPointList.get(l + 1).y) / binary.cols() > 0.08) { filteredPointList.add(hullPointList.get(l)); // Core.circle(rgb, // new Point(UL.x + hullPointList.get(l).x, UL.y // + hullPointList.get(l).y), 5, // new Scalar(0, 255, 0)); } } } } // Sort points by x axis, increasing if (filteredPointList.size() > 1) { if (filteredPointList.get(0).x > filteredPointList.get(1).x) { Point temp = filteredPointList.get(0); filteredPointList.set(0, filteredPointList.get(1)); filteredPointList.set(1, temp); } if (filteredPointList.get(0).y > filteredPointList.get(1).y) return 1; // R else return 2; // U } return 0; }
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 Point findLaser(Mat inputFrame) { Mat mHsv = new Mat(); Imgproc.cvtColor(inputFrame, mHsv, Imgproc.COLOR_RGB2HSV); // Find laser center Mat center = new Mat(); Core.inRange(mHsv, new Scalar(0, 0, 250), new Scalar(180, 16, 255), center); Mat h = new Mat(); List<MatOfPoint> contours = new ArrayList<MatOfPoint>(); Imgproc.findContours(center, contours, h, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); center.release(); Mat center_mask = Mat.zeros(inputFrame.rows(), inputFrame.cols(), CvType.CV_8U); if (contours.size() > 0) { for (int i = 0; i < contours.size(); i++) { int radius = 10; // Point[] cont_pos = contours.get(i).toArray(); Moments m = Imgproc.moments(contours.get(i)); Point p = new Point(); p.x = m.get_m10() / m.get_m00(); p.y = m.get_m01() / m.get_m00(); Core.circle(center_mask, p, radius * 2, new Scalar(255), -1); } } // Find halo Mat ranged = new Mat(); Core.inRange(mHsv, new Scalar(100, 32, 225), new Scalar(150, 255, 255), ranged); mHsv.release(); // Mat f_frame =ranged.clone(); // Find halo around bright dot Core.bitwise_and(ranged, center_mask, ranged); center_mask.release(); // Find biggest resulting contour for (int i = 1; i < contours.size(); i++) { contours.get(i).release(); } contours.clear(); Imgproc.findContours(ranged, contours, h, Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE); h.release(); ranged.release(); if (contours.size() > 0) { MatOfPoint biggest_cont = contours.get(0); double cont_size = Imgproc.contourArea(biggest_cont); for (int i = 1; i < contours.size(); i++) { MatOfPoint cur = contours.get(i); if (Imgproc.contourArea(cur) > cont_size) { biggest_cont = cur; cont_size = Imgproc.contourArea(cur); } } Moments m = Imgproc.moments(biggest_cont); Point p = new Point(); p.x = m.get_m10() / m.get_m00(); p.y = m.get_m01() / m.get_m00(); for (int i = 1; i < contours.size(); i++) { contours.get(i).release(); } biggest_cont.release(); return p; } else { return null; } }
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; }