温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

OpenCV4Android中怎么获取卡号轮廓显示

发布时间:2021-12-15 18:07:44 来源:亿速云 阅读:136 作者:柒染 栏目:大数据

本篇文章为大家展示了OpenCV4Android中怎么获取卡号轮廓显示,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

我们在OpenCVCaremaActivity中的ImgView里面加入拍照事件

首先加一个boolean的变量,这样在按钮的时候实时动态显示先不进行处理了

OpenCV4Android中怎么获取卡号轮廓显示

按钮事件流程

  1. 将获取的Mat图像进行处理,处理方法我们都写在了OpenCvUtil里面了,一会儿说GetAreaMat的方法

  2. 然后将处理好的Mat转成bitmap的图像.

  3. 再把bitmap的图像转为byte的数组,传递到我们的主页界面

  4. 关闭本页面.

  5. 最后主页面的onActivityResulty的方法把byte的数组转回成bmp显示在页面上

Mat图像处理方法

我们摄像头获取卡号时,拍下的照片进行处理,把多余部分尽量去掉,获取一个完整的卡片信息,以便于我们后序的图像识别.

获取卡片图像的操作原理

  1. 原图像的梯度求取

  2. 然后把梯度图像进行二值化处理

  3. 然后在轮廓的发现与过滤

  4. 返回图像


OpenCvUtils里的GetAreaMat方法,就是按照我们上面的原理流程写出的处理方法,直接贴出来,里面的Matgradient方法是图像梯度化的方法,仔细看了下就是整个流程:

public class OpenCvUtils {

    //获取需要的区域
    public static Mat GetAreaMat(Mat src) {
        Mat dst = new Mat();
        Mat area = new Mat();

        src.copyTo(dst);

        //首先将资源梯度化
        Matgradient(dst);
        //先改为灰度图像
        Imgproc.cvtColor(dst, dst, Imgproc.COLOR_BGR2GRAY);
        //二值化图像处理
        Imgproc.threshold(dst, dst, 40, 255, Imgproc.THRESH_BINARY);
        //对图像进行开操作(先腐蚀后膨胀)
        Mat strElement = Imgproc.getStructuringElement(Imgproc.MORPH_RECT, new Size(3, 3));
        Imgproc.morphologyEx(dst, dst, Imgproc.MORPH_OPEN, strElement);

        //寻找轮廓
        List<MatOfPoint> contours = new ArrayList<>();
        Mat hireachy = new Mat();
        /**
         * Imgproc.RETR_EXTERNAL代表寻找轮廓外层最大的轮廓
         */
        Imgproc.findContours(dst, contours, hireachy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE, new Point(0, 0));
        /**
         * 获取宽和高
         * 用于除2是为了占总图像一半,用于分析想找到的区域
         */
        int hw = dst.cols()/2;
        Rect roi = new Rect();
        for(int i=0;i<contours.size();i++) {
            Rect rect = Imgproc.boundingRect(contours.get(i));
            if (rect.width > hw ) {
                roi.x = rect.x;
                roi.y = rect.y;
                roi.width = rect.width;
                roi.height = rect.height;
                break;
            }
        }

        //为0说明未找到区域
        if (roi.width == 0 || roi.height == 0) {
            src.copyTo(area);
        } else {
            src.submat(roi).copyTo(area);
        }
        dst.release();
        return area;
    }

    //将Mat对象梯度化
    private static void Matgradient(Mat src) {
        //先计算梯度
        Mat grad_x = new Mat();
        Mat grad_y = new Mat();
        Mat abs_grad_x = new Mat();
        Mat abs_grad_y = new Mat();
        //先把X方向梯度化
        Imgproc.Scharr(src, grad_x, CvType.CV_32F, 1, 0);
        //再把Y方向梯度化
        Imgproc.Scharr(src, grad_y, CvType.CV_32F, 0, 1);
        //绝对值
        /**
         * 因为获取的grad_x和grad_y有可能是负值,我们要求的是0-255之间的数值
         * 所以需要把原来的梯度化的生成绝对值
         */
        Core.convertScaleAbs(grad_x, abs_grad_x);
        Core.convertScaleAbs(grad_y, abs_grad_y);
        grad_x.release();  //处理完记得及时释放节省资源
        grad_y.release();  //处理完记得及时释放节省资源
        //梯度图像
        /**
         * 根据最后获取的两个绝对值,把图像重新合并,两个0.5的参数就是图像的比重
         */
        Core.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0, src);
        abs_grad_x.release();  //处理完记得及时释放节省资源
        abs_grad_y.release();  //处理完记得及时释放节省资源
    }
}

上述内容就是OpenCV4Android中怎么获取卡号轮廓显示,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注亿速云行业资讯频道。

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI