VS2013+OpenCV3.0 之身份证分割算法

前言

本人c++小白,主要是做android这块的,底层涉及甚少,c++上学的时候自学过一点,还算有点基础。
之前有提过身份证识别的需求,考虑到用三方的需要收费,于是就自己研究下身份证识别喽。
有2个思路:

  1. 安卓ndk层调用opencv,手机识别
  2. c++实现,java调c,java封装接口,供手机调用

有个想法:就是用vs集成opencv,做个可以识别身份证的可执行文件.exe的东东,然后用java调用exe,封装一个http接口,android端上传身份证照片,后台识别返回结果,不知道能不能做,先慢慢来了

步骤1 配置开发环境##

参考大神博客:VS2013+OpenCV开源库使用入门

步骤2

了解身份证识别的算法:(个人理解)
从网上找的图片 百度找的图片

  • 图片灰度化:就是把彩色照片变为黑白照片,为什么要这样做呢?颜色是rgb3种颜色组成的,变为黑白就是简化颜色矩阵,提高运算速率。效果图:
    这里写图片描述

  • 二值化:就是将图像上的像素点的灰度值设置为0或255,也就是将整个图像呈现出明显的只有黑和白的视觉效果,就是有个阀值,这里取120到220
    这里写图片描述

  • 腐蚀:腐蚀就是把像素点放大,如把x,y坐标都扩大15个像素,这样原来的一个点就变为了一个像素块,这样做就是为了把文字连成一块,这样可以好识别
    这里写图片描述

  • 轮廓检测:对腐蚀后的图片进行轮廓检测,用到findContours函数,分割为多块

这里写图片描述

这里写图片描述
这里写图片描述

下面贴出个人调试源码

// cv.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

#include<iostream>

#include<opencv2\opencv.hpp>

using namespace std;
using namespace cv;

int _tmain(int argc, _TCHAR* argv[])
{
	Mat img = imread("card.png");
	namedWindow("原图");
	imshow("原图", img);
	
	Mat temp, temp2, temp3;

	//灰度化
	cvtColor(img, temp, COLOR_BGR2GRAY); 
	cvtColor(temp, img, COLOR_GRAY2BGRA);
	namedWindow("灰度化");
	imshow("灰度化", temp);
	
	

	//二值化
	threshold(temp, temp2, 100, 200, CV_THRESH_BINARY);
	namedWindow("二值化");
	imshow("二值化", temp2);

	//腐蚀
	Mat erodeElement = getStructuringElement(MORPH_RECT, Size(13, 13));
	erode(temp2, temp3, erodeElement);
	namedWindow("腐蚀");
	imshow("腐蚀", temp3);
	

	//轮廓检测
	vector<vector<Point> > contours;  //定义一个容器来存储所有检测到的轮廊
	vector<Vec4i> hierarchy;
	//轮廓检测函数
	Mat conv(temp3.size(), CV_8UC1);
	temp3.convertTo(conv, CV_8UC1);
	findContours(conv, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cvPoint(0, 0));
	int index = 0;
	long max_Index = static_cast<long>(contours.size());
	if (index < max_Index - 1) {
		++index;
	}
	//取出身份证号码区域
	vector<Rect> rects;
	Rect numberRect = Rect(0, 0, 0, 0);
	vector<vector<Point> >::const_iterator itContours = contours.begin();



	for (int i = 0; i <max_Index; ++i) {
		Rect rect = boundingRect(itContours[i]);
		numberRect = rect;
		
		Mat dst(numberRect.height, numberRect.width, CV_8UC4, numberRect.area());
		dst = img(numberRect);
		for (int i = 0; i <max_Index; ++i) {
		Rect rect = boundingRect(itContours[i]);
		numberRect = rect;

		Mat dst(numberRect.height, numberRect.width, CV_8UC4, numberRect.area());
		dst = img(numberRect);
		
		if (rect.y > img.rows / 2 && rect.width / rect.height > 6){
			
			imshow("身份证号:", dst);
		}
	}
	
	}

	waitKey(0);
	cout << CV_MAJOR_VERSION << endl;
	return 0;
}


总结

c这块小白一枚,我再去看看c++基础,opencv也是刚看,如果错误,请各位大神指点!

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值