JavaOpencv實現答題卡掃描 銀行卡號碼截取,javaopencv答題卡

來源:互聯網
上載者:User

JavaOpencv實現答題卡掃描 銀行卡號碼截取,javaopencv答題卡

項目中需要用到opencv,先瞭解後做仿照別人做了兩個 關於java Opencv 答題卡掃描 銀行卡號碼截取 的 小程式。


Opencv的安裝下載,就不多介紹,主要是貼代碼,希望大家能多多指教。


答題卡

import org.opencv.core.*;import org.opencv.imgcodecs.Imgcodecs;import org.opencv.imgproc.Imgproc;import java.util.*;import static org.opencv.core.CvType.CV_8U;import static org.opencv.imgproc.Imgproc.MORPH_RECT;/** * @author  lsw * @email lsw_demail@163.com */public class OpenCv {    static {        System.loadLibrary(Core.NATIVE_LIBRARY_NAME);    }    public static void main(String []args) {        String sheet = "D://A4.jpg";        //A4 二值化膨脹後產生的圖片路徑        String results = "E://result.jpg";        String msg = rowsAndCols(sheet, results);        System.out.println(msg);    }    public static void Canny(String oriImg, String dstImg, int threshold) {        //裝載圖片        Mat img = Imgcodecs.imread(oriImg);        Mat srcImage2 = new Mat();        Mat srcImage3 = new Mat();        Mat srcImage4 = new Mat();        Mat srcImage5 = new Mat();        //圖片變成灰階圖片        Imgproc.cvtColor(img, srcImage2, Imgproc.COLOR_RGB2GRAY);        //圖片二值化        Imgproc.adaptiveThreshold(srcImage2, srcImage3, 255, Imgproc.ADAPTIVE_THRESH_MEAN_C, Imgproc.THRESH_BINARY_INV, 255, 1);        //確定腐蝕和膨脹核的大小        Mat element = Imgproc.getStructuringElement(MORPH_RECT, new Size(1, 6));        //腐蝕操作        Imgproc.erode(srcImage3, srcImage4, element);        //膨脹操作        Imgproc.dilate(srcImage4, srcImage5, element);        //Imgcodecs.imwrite("E:/picpool/card/enresults.jpg", srcImage4);        //確定每張答題卡的ROI地區        Mat imag_ch1 = srcImage4.submat(new Rect(200, 1065, 1930, 2210));        //識別所有輪廓        Vector<MatOfPoint> chapter1 = new Vector<>();        Imgproc.findContours(imag_ch1, chapter1, new Mat(), 2, 3);        Mat result = new Mat(imag_ch1.size(), CV_8U, new Scalar(255));        Imgproc.drawContours(result, chapter1, -1, new Scalar(0), 2);        Imgcodecs.imwrite("E://result.jpg", result);        //new一個 矩形集合 用來裝 輪廓        List<RectComp> RectCompList = new ArrayList<>();        for (int i = 0; i < chapter1.size(); i++) {            Rect rm = Imgproc.boundingRect(chapter1.get(i));            RectComp ti = new RectComp(rm);            //把輪廓寬度區間在 50 - 80 範圍內的輪廓裝進矩形集合            if (ti.rm.width > 60 && ti.rm.width < 85) {                RectCompList.add(ti);            }        }        //new一個 map 用來儲存答題卡上填的答案 (A\B\C\D)        TreeMap<Integer, String> listenAnswer = new TreeMap<>();        //按 X軸 對listenAnswer進行排序        RectCompList.sort((o1, o2) -> {            if (o1.rm.x > o2.rm.x) {                return 1;            }            if (o1.rm.x == o2.rm.x) {                return 0;            }            if (o1.rm.x < o2.rm.x) {                return -1;            }            return -1;        });            /*            如果精度高,可以通過像素計算          for (RectComp rc : RectCompList) {            int x = RectCompList.get(t).getRm().x - 16;            int y = RectCompList.get(t).getRm().y - 94;            //計算x軸上的分割 如果超過5題,那麼還會有一個大分割            int xSplit = x/85 /5;            //因為第一題 x=21 電腦中題目從0開始算,現實是從1開始 所以+1            int xTitleNum = x/85 + 1;            //由於精度問題  x軸會慢慢遞減  遞減到上一個答案去 如果不跨過兩個答案以上,都沒問題  如果答題卡x軸40題左右 會出問題            if(x%85>20){                System.out.println("x軸遞減程度" + x%85);                xTitleNum++;            }            xTitleNum = xTitleNum - xSplit;            System.out.println(xTitleNum);            }            */        //根據 Y軸 確定被選擇答案 (A\B\C\D)        for (RectComp rc : RectCompList) {            for (int h = 0; h < 7; h++) {                if ((rc.rm.contains(new Point(rc.rm.x + 20, 115 + (320 * h))))) {                    for (int w = 0; w < 4; w++) {                        if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {                            listenAnswer.put(1 + (20 * h) + (5 * w), "A");                        } else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {                            listenAnswer.put(2 + (20 * h) + (5 * w), "A");                        } else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {                            listenAnswer.put(3 + (20 * h) + (5 * w), "A");                        } else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {                            listenAnswer.put(4 + (20 * h) + (5 * w), "A");                        } else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {                            listenAnswer.put(5 + (20 * h) + (5 * w), "A");                        }                    }                } else if ((rc.rm.contains(new Point(rc.rm.x + 20, 165 + (320 * h))))) {                    for (int w = 0; w < 4; w++) {                        if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {                            listenAnswer.put(1 + (20 * h) + (5 * w), "B");                        } else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {                            listenAnswer.put(2 + (20 * h) + (5 * w), "B");                        } else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {                            listenAnswer.put(3 + (20 * h) + (5 * w), "B");                        } else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {                            listenAnswer.put(4 + (20 * h) + (5 * w), "B");                        } else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {                            listenAnswer.put(5 + (20 * h) + (5 * w), "B");                        }                    }                } else if ((rc.rm.contains(new Point(rc.rm.x + 20, 220 + (320 * h))))) {                    for (int w = 0; w < 4; w++) {                        if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {                            listenAnswer.put(1 + (20 * h) + (5 * w), "C");                        } else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {                            listenAnswer.put(2 + (20 * h) + (5 * w), "C");                        } else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {                            listenAnswer.put(3 + (20 * h) + (5 * w), "C");                        } else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {                            listenAnswer.put(4 + (20 * h) + (5 * w), "C");                        } else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {                            listenAnswer.put(5 + (20 * h) + (5 * w), "C");                        }                    }                } else if ((rc.rm.contains(new Point(rc.rm.x + 20, 275 + (320 * h))))) {                    for (int w = 0; w < 4; w++) {                        if (rc.rm.contains(new Point(55 + (500 * w), rc.rm.y))) {                            listenAnswer.put(1 + (20 * h) + (5 * w), "D");                        } else if (rc.rm.contains(new Point(135 + (500 * w), rc.rm.y))) {                            listenAnswer.put(2 + (20 * h) + (5 * w), "D");                        } else if (rc.rm.contains(new Point(215 + (500 * w), rc.rm.y))) {                            listenAnswer.put(3 + (20 * h) + (5 * w), "D");                        } else if (rc.rm.contains(new Point(300 + (500 * w), rc.rm.y))) {                            listenAnswer.put(4 + (20 * h) + (5 * w), "D");                        } else if (rc.rm.contains(new Point(380 + (500 * w), rc.rm.y))) {                            listenAnswer.put(5 + (20 * h) + (5 * w), "D");                        }                    }                }            }        }        Iterator iter = listenAnswer.entrySet().iterator();        while (iter.hasNext()) {            Map.Entry entry = (Map.Entry) iter.next();            Object key = entry.getKey();            Object val = entry.getValue();            System.out.println("第" + key + "題,分數:" + val);        }    }    public static String rowsAndCols(String oriImg, String dstImg) {        String msg = "";        Canny(oriImg, dstImg, 50);        Mat mat = Imgcodecs.imread(dstImg);        msg += "\n行數:" + mat.rows();        msg += "\n列數:" + mat.cols();        msg += "\nheight:" + mat.height();        msg += "\nwidth:" + mat.width();        msg += "\nelemSide:" + mat.elemSize();        //CvType contourSeq = null;        return msg;    }}

核心代碼如: 還有另外一個類,也很簡單  我就不貼出來了,大家可以去我的github上面找得到  通過核心代碼就能理解出大概的思路。

github地址 : https://github.com/shiwenlin/opencv


銀行卡也很簡單最後是也在github上   項目中截取到銀行卡的圖片,我們也可以用別的外掛程式轉成數字,




   
1
0
查看評論

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.