Ask Your Question
0

How can I get the corner points of the largest contour (in Java/Android preferably)

asked 2017-08-30 01:48:06 -0600

gurankas gravatar image

I Convert an image into a Mat, differentiate the foreground from the background, apply cvtcolor and canny, then find all the contours and select the largest contour among them (The page boundary for for the purpose of scanning app). Now I want to establish 4 corners of the boundary to apply perspective transform but am unable to find them. Any help would be appreciated.

My code till now is as follows![public class MyAsyncTask extends android.os.AsyncTask { private static final String TAG = "AsyncTask"; Bitmap bitmap1; Context context;

    //constructor initializing the context field
    public MyAsyncTask(Context context){
        this.context=context;
    }


    //Main method for the computation of the image
    @Override
    protected Bitmap doInBackground(Object[] objects)
    {

        //set-up of the image in the desired format for k-means clustering
        Mat samples = new Mat(((LensActivity)context).src.rows() * ((LensActivity)context).src.cols(), 3, CvType.CV_32F);
        for( int y = 0; y < ((LensActivity)context).src.rows(); y++ )
        {
            for( int x = 0; x < ((LensActivity)context).src.cols(); x++ )
            {
                for( int z = 0; z < 3; z++)
                {
                    samples.put(x + y*((LensActivity)context).src.cols(), z, ((LensActivity)context).src.get(y,x)[z]);
                }
            }
        }

        //applying k-means clustering
        int clusterCount = 2;
        Mat labels = new Mat();
        int attempts = 5;
        Mat centers = new Mat();
        Core.kmeans(samples, clusterCount, labels, new TermCriteria(TermCriteria.MAX_ITER |
                        TermCriteria.EPS, 10000, 0.0001), attempts,
                Core.KMEANS_PP_CENTERS, centers);


        //The image with the colour nearest to white will be considered as foreground
        double dstCenter0 = calcWhiteDist(centers.get(0, 0)[0], centers.get(0, 1)[0], centers.get(0, 2)[0]);
        double dstCenter1 = calcWhiteDist(centers.get(1, 0)[0], centers.get(1, 1)[0], centers.get(1, 2)[0]);
        int paperCluster = (dstCenter0 < dstCenter1)?0:1;


        //definition of 2 Mat objects needed for next step
        Mat srcRes = new Mat( ((LensActivity)context).src.size(), ((LensActivity)context).src.type() );
        Mat srcGray = new Mat();


        //Performing Segmentation ie displaying all foreground pixels as white and all background pixels as black
        for( int y = 0; y < ((LensActivity)context).src.rows(); y++ )
        {
            for( int x = 0; x < ((LensActivity)context).src.cols(); x++)
            {
                int cluster_idx = (int)labels.get(x + y*((LensActivity)context).src.cols(),0)[0];
                if(cluster_idx != paperCluster)
                {
                    srcRes.put(y,x, 0, 0, 0, 255);
                }
                else
                {
                    srcRes.put(y,x, 255, 255, 255, 255);
                }
            }
        }


        //Apply canny edge detection and then find contours
        Imgproc.cvtColor(((LensActivity)context).src, srcGray, Imgproc.COLOR_BGR2GRAY);
        Imgproc.Canny(srcGray, srcGray, 50, 150);
        List<MatOfPoint> contours = new ArrayList<MatOfPoint>();
        Mat hierarchy = new Mat();
        Imgproc.findContours(srcGray, contours, hierarchy, Imgproc.RETR_CCOMP, Imgproc.CHAIN_APPROX_SIMPLE);



        //Finding the biggest contour corresponding to the page in the image
        int index = 0;
        double maxim = Imgproc.contourArea(contours.get(0));

        for (int contourIdx = 1; contourIdx < contours.size();contourIdx++)
        {
            double temp;
            temp=Imgproc.contourArea(contours.get(contourIdx));
            if(maxim<temp)
            {
                maxim=temp;
                index=contourIdx;
            }
        }
        Mat drawing = Mat.zeros(srcRes.size(), CvType.CV_8UC1);
        Log.d(TAG,"number of contours " +contours.get(index));

        Imgproc.drawContours(drawing, contours, index, new Scalar(255), 1);



        //lines corresponding to the biggest contours used to find the intersection points of these lines to find the corners ...
(more)
edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-08-30 05:38:33 -0600

Ziri gravatar image

You'are looking for minAreaRect

(Java) RotatedRect box = Imgproc.minAreaRect(LargestContourPoints);

Then get your points coordinates from "box".

edit flag offensive delete link more

Comments

I tried minAreaRect. That does enclose the largest contour and give me corners to perform the perspective transformation, but the problem is that it does not provide corners of the contour, it provides the corners of the rectangle which encloses the contour. So, when I supply these corners to perspective transformation, the rectangle area gets transformed and not the contour detected

gurankas gravatar imagegurankas ( 2017-08-31 00:07:56 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2017-08-30 01:45:33 -0600

Seen: 2,180 times

Last updated: Aug 30 '17