Java Code Examples for org.opencv.imgproc.Imgproc#approxPolyDP()

The following examples show how to use org.opencv.imgproc.Imgproc#approxPolyDP() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: CVProcessor.java    From CVScanner with GNU General Public License v3.0 6 votes vote down vote up
static public Quadrilateral getQuadrilateral(List<MatOfPoint> contours, Size srcSize){
    double ratio = getScaleRatio(srcSize);
    int height = Double.valueOf(srcSize.height / ratio).intValue();
    int width = Double.valueOf(srcSize.width / ratio).intValue();
    Size size = new Size(width,height);

    for ( MatOfPoint c: contours ) {
        MatOfPoint2f c2f = new MatOfPoint2f(c.toArray());
        double peri = Imgproc.arcLength(c2f, true);
        MatOfPoint2f approx = new MatOfPoint2f();
        Imgproc.approxPolyDP(c2f, approx, 0.02 * peri, true);

        Point[] points = approx.toArray();
        Log.d("SCANNER", "approx size: " + points.length);

        // select biggest 4 angles polygon
        if (points.length == 4) {
            Point[] foundPoints = sortPoints(points);

            if (isInside(foundPoints, size) && isLargeEnough(foundPoints, size, 0.25)) {
                return new Quadrilateral( c , foundPoints );
            }
            else{
                //showToast(context, "Try getting closer to the ID");
                Log.d("SCANNER", "Not inside defined area");
            }
        }
    }

    //showToast(context, "Make sure the ID is on a contrasting background");
    return null;
}
 
Example 2
Source File: MainActivity.java    From SimpleDocumentScanner-Android with MIT License 6 votes vote down vote up
/**
 * Find the largest 4 point contour in the given Mat.
 *
 * @param src A valid Mat
 * @return The largest contour as a Mat
 */
private MatOfPoint2f findLargestContour(Mat src) {
    List<MatOfPoint> contours = new ArrayList<>();
    Imgproc.findContours(src, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

    // Get the 5 largest contours
    Collections.sort(contours, new Comparator<MatOfPoint>() {
        public int compare(MatOfPoint o1, MatOfPoint o2) {
            double area1 = Imgproc.contourArea(o1);
            double area2 = Imgproc.contourArea(o2);
            return (int) (area2 - area1);
        }
    });
    if (contours.size() > 5) contours.subList(4, contours.size() - 1).clear();

    MatOfPoint2f largest = null;
    for (MatOfPoint contour : contours) {
        MatOfPoint2f approx = new MatOfPoint2f();
        MatOfPoint2f c = new MatOfPoint2f();
        contour.convertTo(c, CvType.CV_32FC2);
        Imgproc.approxPolyDP(c, approx, Imgproc.arcLength(c, true) * 0.02, true);

        if (approx.total() == 4 && Imgproc.contourArea(contour) > 150) {
            // the contour has 4 points, it's valid
            largest = approx;
            break;
        }
    }

    return largest;
}
 
Example 3
Source File: NativeClass.java    From AndroidDocumentScanner with MIT License 4 votes vote down vote up
public List<MatOfPoint2f> getPoints(Mat src) {

        // Blur the image to filter out the noise.
        Mat blurred = new Mat();
        Imgproc.medianBlur(src, blurred, 9);

        // Set up images to use.
        Mat gray0 = new Mat(blurred.size(), CvType.CV_8U);
        Mat gray = new Mat();

        // For Core.mixChannels.
        List<MatOfPoint> contours = new ArrayList<>();
        List<MatOfPoint2f> rectangles = new ArrayList<>();

        List<Mat> sources = new ArrayList<>();
        sources.add(blurred);
        List<Mat> destinations = new ArrayList<>();
        destinations.add(gray0);

        // To filter rectangles by their areas.
        int srcArea = src.rows() * src.cols();

        // Find squares in every color plane of the image.
        for (int c = 0; c < 3; c++) {
            int[] ch = {c, 0};
            MatOfInt fromTo = new MatOfInt(ch);

            Core.mixChannels(sources, destinations, fromTo);

            // Try several threshold levels.
            for (int l = 0; l < THRESHOLD_LEVEL; l++) {
                if (l == 0) {
                    // HACK: Use Canny instead of zero threshold level.
                    // Canny helps to catch squares with gradient shading.
                    // NOTE: No kernel size parameters on Java API.
                    Imgproc.Canny(gray0, gray, 10, 20);

                    // Dilate Canny output to remove potential holes between edge segments.
                    Imgproc.dilate(gray, gray, Mat.ones(new Size(3, 3), 0));
                } else {
                    int threshold = (l + 1) * 255 / THRESHOLD_LEVEL;
                    Imgproc.threshold(gray0, gray, threshold, 255, Imgproc.THRESH_BINARY);
                }

                // Find contours and store them all as a list.
                Imgproc.findContours(gray, contours, new Mat(), Imgproc.RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);

                for (MatOfPoint contour : contours) {
                    MatOfPoint2f contourFloat = MathUtils.toMatOfPointFloat(contour);
                    double arcLen = Imgproc.arcLength(contourFloat, true) * 0.02;

                    // Approximate polygonal curves.
                    MatOfPoint2f approx = new MatOfPoint2f();
                    Imgproc.approxPolyDP(contourFloat, approx, arcLen, true);

                    if (isRectangle(approx, srcArea)) {
                        rectangles.add(approx);
                    }
                }
            }
        }

        return rectangles;

    }
 
Example 4
Source File: PrimitiveDetection.java    From FTCVision with MIT License 4 votes vote down vote up
/**
 * 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 by halving then doubling size
    Filter.downsample(gray, 2);
    Filter.upsample(gray, 2);

    //Mat is short for Matrix, and here is used to store an image.
    //it is n-dimensional, but as an image, is two-dimensional
    Mat cacheHierarchy = new Mat();
    Mat grayTemp = new Mat();
    List<Rectangle> rectangles = new ArrayList<>();
    List<Contour> contours = new ArrayList<>();

    //This finds the edges using a Canny Edge Detector
    //It is sent the grayscale Image, a temp Mat, the lower detection threshold for an edge,
    //the higher detection threshold, the Aperture (blurring) of the image - higher is better
    //for long, smooth edges, and whether a more accurate version (but time-expensive) version
    //should be used (true = more accurate)
    //Note: the edges are stored in "grayTemp", which is an image where everything
    //is black except for gray-scale lines delineating the edges.
    Imgproc.Canny(gray, grayTemp, 0, THRESHOLD_CANNY, APERTURE_CANNY, true);
    //make the white lines twice as big, while leaving the image size constant
    Filter.dilate(gray, 2);

    List<MatOfPoint> contoursTemp = new ArrayList<>();
    //Find contours - the parameters here are very important to compression and retention
    //grayTemp is the image from which the contours are found,
    //contoursTemp is where the resultant contours are stored (note: color is not retained),
    //cacheHierarchy is the parent-child relationship between the contours (e.g. a contour
    //inside of another is its child),
    //Imgproc.CV_RETR_LIST disables the hierarchical relationships being returned,
    //Imgproc.CHAIN_APPROX_SIMPLE means that the contour is compressed from a massive chain of
    //paired coordinates to just the endpoints of each segment (e.g. an up-right rectangular
    //contour is encoded with 4 points.)
    Imgproc.findContours(grayTemp, contoursTemp, cacheHierarchy, Imgproc.CV_RETR_LIST, Imgproc.CHAIN_APPROX_SIMPLE);
    //MatOfPoint2f means that is a MatofPoint (Matrix of Points) represented by floats instead of ints
    MatOfPoint2f approx = new MatOfPoint2f();
    //For each contour, test whether the contour is a rectangle
    //List<Contour> contours = new ArrayList<>()
    for (MatOfPoint co : contoursTemp) {
        //converting the MatOfPoint to MatOfPoint2f
        MatOfPoint2f matOfPoint2f = new MatOfPoint2f(co.toArray());
        //converting the matrix to a Contour
        Contour c = new Contour(co);

        //Attempt to fit the contour to the best polygon
        //input: matOfPoint2f, which is the contour found earlier
        //output: approx, which is the MatOfPoint2f that holds the new polygon that has less vertices
        //basically, it smooths out the edges using the third parameter as its approximation accuracy
        //final parameter determines whether the new approximation must be closed (true=closed)
        Imgproc.approxPolyDP(matOfPoint2f, approx,
                c.arcLength(true) * EPLISON_APPROX_TOLERANCE_FACTOR, true);

        //converting the MatOfPoint2f to a contour
        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
            //Done by comparing the three points constituting the angle of each corner
            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);
}
 
Example 5
Source File: CropImage.java    From reader with MIT License 4 votes vote down vote up
private void makeDefault() {
            HighlightView hv = new HighlightView(mImageView);

            int width = mBitmap.getWidth();
            int height = mBitmap.getHeight();

            Rect imageRect = new Rect(0, 0, width, height);

            // make the default size about 4/5 of the width or height
//            int cropWidth = Math.min(width, height) * 4 / 5;
//            int cropHeight = cropWidth;
            int cropWidth = width;
            int cropHeight = height;

            if (mAspectX != 0 && mAspectY != 0) {
                if (mAspectX > mAspectY) {
                	// �����辩缉���
                    cropHeight = cropWidth * mAspectY ;// mAspectX;
                } else {
                    cropWidth = cropHeight * mAspectX ;// mAspectY;
                }
            }

            int x = (width - cropWidth) / 2;
            int y = (height - cropHeight) / 2;
            
            Mat imgSource = new Mat();
            Utils.bitmapToMat(mBitmap, imgSource);
            //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  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;
           float x1, y1, x2, y2;
           temp_double = approxCurve.get(0,0);       
           Point p1 = new Point(temp_double[0], temp_double[1]);
           x1 = (float)temp_double[0];
           y1 = (float)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]);
           x2 = (float)temp_double[0];
           y2 = (float)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]);

            RectF cropRect = new RectF(x, y, x + cropWidth, y + cropHeight);
            //RectF cropRect = new RectF(x1, y1, x2, y2);
         // �����辩缉���
            
            hv.setup(mImageMatrix, imageRect, cropRect, mCircleCrop,false
                     /*mAspectX != 0 && mAspectY != 0*/);
            mImageView.add(hv);
        }
 
Example 6
Source File: ContoursUtils.java    From super-cloudops with Apache License 2.0 3 votes vote down vote up
/**
 * 利用函数approxPolyDP来对指定的点集进行逼近 精确度设置好,效果还是比较好的
 *
 * @param cannyMat
 * @param threshold
 *            阀值(精确度)
 * @return
 */
public static Point[] useApproxPolyDPFindPoints(Mat cannyMat, double threshold) {

	MatOfPoint maxContour = findMaxContour(cannyMat);

	MatOfPoint2f approxCurve = new MatOfPoint2f();
	MatOfPoint2f matOfPoint2f = new MatOfPoint2f(maxContour.toArray());

	// 原始曲线与近似曲线之间的最大距离设置为0.01,true表示是闭合的曲线
	Imgproc.approxPolyDP(matOfPoint2f, approxCurve, threshold, true);

	Point[] points = approxCurve.toArray();

	return points;
}