How to detect rectangle from image and crop from it's four edges?

asked 2018-05-10 01:26:03 -0500

Akhil Patel gravatar image

updated 2018-05-10 02:47:36 -0500

Hello all,

I am developing an application for detect driving license and capture image of driving license using surface view and detect driving license and crop from those it's four corner using openCV.

so right now i am using canny edge detection and find the edges but i am not able to crop the image because canny edge detection return black and white image i am crop my original license image from it's edges.

Please suggest any best solution.

Here is my code snippet

public Bitmap findEdges(Bitmap img)
{

    Mat rgba = new Mat();
    Utils.bitmapToMat(img, rgba);


    Mat edges = new Mat(rgba.size(), CvType.CV_8UC1);
    Imgproc.cvtColor(rgba, edges, Imgproc.COLOR_RGB2GRAY, 4);
    Imgproc.Canny(edges, edges, 40, 40);

    Bitmap resultBitmap = Bitmap.createBitmap(edges.cols(), edges.rows(), Bitmap.Config.ARGB_8888);
    Utils.matToBitmap(edges, resultBitmap);

    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();
    resultBitmap.compress(Bitmap.CompressFormat.PNG, 75, baos);
    byte[] b = baos.toByteArray();


    resultBitmap = BitmapFactory.decodeByteArray(b, 0, b.length);

    int w = resultBitmap.getWidth();
    int h = resultBitmap.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(resultBitmap, w_proc, h_proc, false);
    Bitmap grayBitmap = Bitmap.createBitmap(w_proc, h_proc, Bitmap.Config.RGB_565);
    Bitmap cannyBitmap = Bitmap.createBitmap(w_proc, h_proc, Bitmap.Config.RGB_565);
    Bitmap linesBitmap = Bitmap.createBitmap(w_proc, h_proc, Bitmap.Config.RGB_565);


    Utils.bitmapToMat(srcBitmap, rgbMat);//convert original bitmap to Mat, R G B.


    Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//rgbMat to gray grayMat


    cannyMat = getCanny(grayMat);


    Imgproc.HoughLinesP(cannyMat, linesMat, 1, Math.PI / 180, 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);
    Log.e("opencv", "lines.rows" + linesMat.rows() + " w_proc/3: " + w_proc / 3);

    List<EdgesLine> horizontals = new ArrayList<>();
    List<EdgesLine> 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);

        EdgesLine line = new EdgesLine(start, end);
        if (Math.abs(x1 - x2) > Math.abs(y1 - y2)) {
            horizontals.add(line);
        } else {
            verticals.add(line);
        }

        if (BuildConfig.DEBUG) {
        }
    }

    Log.e("HoughLines", "completed HoughLines");
    Log.e("HoughLines", "linesMat size: " + linesMat.size());
    Log.e("HoughLines", "linesBitmap size: " + Integer.toString(linesBitmap.getHeight()) + " x " + Integer.toString(linesBitmap.getWidth()));
    Log.e("Lines Detected", Integer.toString(linesMat.rows()));

    if (linesMat.rows() > 400) {
        Context context = getApplicationContext();
        int duration = Toast.LENGTH_SHORT;
        Toast toast = Toast.makeText(context, "Please use a cleaner background", duration);
        toast.show();
    }

    if (horizontals.size() < 2) {
        if (horizontals.size() == 0 || horizontals.get(0)._center.y > h_proc / 2 ...
(more)
edit retag flag offensive close merge delete

Comments

1

@berak

give me solution for this issue.

Akhil Patel gravatar imageAkhil Patel ( 2018-05-10 02:42:07 -0500 )edit
1

@berak

if you want to output for this source code i will provide you but please review this code and help me how can i solve.

Akhil Patel gravatar imageAkhil Patel ( 2018-05-10 02:43:48 -0500 )edit
4

Please do not abuse the at-sign notification on OpenCV Answers forum. Nobody, not even moderators, are obliged to give answers to questions. Anyone is welcome to give answers as they are free to do so. Forcing or pressuring another person into writing an answer is not allowed here.

rwong gravatar imagerwong ( 2018-05-10 03:10:00 -0500 )edit
3

Please explain, step by step, whether each step produces the correct output. To understand whether the lines are detected correctly by HoughLinesP, you may want to plot (overlay) the lines on top of the original image, and then judge the results by yourself (by viewing the image on your computer screen). Likewise, please manually judge whether the outputs from all steps are correct.

rwong gravatar imagerwong ( 2018-05-10 03:13:44 -0500 )edit
1

@rwong

First step is capture driving license image using surfaceview second step rotate the image if needed third step : i have call findedges(bitmap) method. in this method images convert into mat than convert into grayscale and than detect edges using canny edge detection and after detecting edge i have create new bitmap using canny edge image height and width but main problem is that i want x and y coordinate of canny edge image. i mean starting position of edge and ending position of edge.

Akhil Patel gravatar imageAkhil Patel ( 2018-05-10 03:47:19 -0500 )edit
1

Bitmap crop = Bitmap.createBitmap(rotateandscalebitmap, 0, 0, dstBitmap.getWidth(), dstBitmap.getHeight());

see i want x and y coordinate replace of 0,0

dstBitmap.getWidth() : when canny edge convert and crop image edges to edges of license card i have get this width from this converted image.

dstBitmap.getHeight() : when canny edge convert and crop image edges to edges of license card i have get this height from this converted image.

Akhil Patel gravatar imageAkhil Patel ( 2018-05-10 03:48:17 -0500 )edit
2

@Akhil Patel , you can't command ppl to solve your problem here.

berak gravatar imageberak ( 2018-05-10 03:48:56 -0500 )edit

@berak

how to solve my problem please tell me the correct way or procedure to solve my issue because i am new on OpenCV and i have not work before on OpenCV i have work only pure android. so it is difficult for me for work on OpenCV and yes speically image processing it's complex task for me.

Akhil Patel gravatar imageAkhil Patel ( 2018-05-10 04:03:58 -0500 )edit