opencv C++ 模板匹配----银行卡号识别

图片过程

模板图像
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
模板图库制作

	Mat image, gray_image, threshold_image;
	image = imread("C:/Users/clg2021/Desktop/ocr_a_reference.png");
	if (!image.data) {cout << "failed to read" << endl;system("pause");}
	show("image", image);
	cvtColor(image, gray_image, CV_BGR2GRAY);
	show("gray_image", gray_image);
	threshold(gray_image, threshold_image, 10, 255, CV_THRESH_BINARY_INV);
	show("threshold_image", threshold_image);
	//-----------------------------------------------------------------------
    vector<vector<Point>> contours;
    vector<Vec4i> hierarcy;
    findContours(threshold_image.clone(), contours, hierarcy, CV_RETR_EXTERNAL, CHAIN_APPROX_NONE); //查找轮廓
	drawContours(image, contours, -1, Scalar(0, 255, 0), 3);
	imshow("draw_image", image);
	cout << contours.size() << endl;
	vector<Rect>srcRect(contours.size());
	for (unsigned int i = 0; i < contours.size(); ++i)
	{
		srcRect[i] = boundingRect(contours[i]);
	}
	sorted_image(srcRect, contours.size());
	vector<Mat>image_roi; 
	Mat roi;
	for (unsigned int i = 0; i < contours.size(); ++i)
	{
		roi = threshold_image(Rect(srcRect[i].x, srcRect[i].y, srcRect[i].width, srcRect[i].height));
		resize(roi, roi, Size(57, 88));
		image_roi.push_back(roi);
		//---------------------------------
		char window[220];
		sprintf_s(window, "%s%d%s", "C:\\Users\\clg2021\\Desktop\\temple\\", i, ".jpg");   //指定保存路径//"..\\Image\\image",
		imwrite(window, roi);

	}
	//显示模板图像
	for (int i = 0; i < image_roi.size(); ++i)
	{
		imshow("images", image_roi[i]);
		waitKey(0);
	}

加载测试图片

//导入测试图片
	Mat bank_image, bank_gray, bank_tophat;
	bank_image = imread("C:/Users/clg2021/Desktop/images/credit_card_01.png");
	if (!bank_image.data) { cout << "failed to read" << endl; system("pause"); }
	resize(bank_image, bank_image, Size(300, bank_image.rows));
	show("bane_image", bank_image);
	cvtColor(bank_image, bank_gray, CV_BGR2GRAY);
	Mat element1 = getStructuringElement(MORPH_RECT, Size(9, 3));
	Mat element2 = getStructuringElement(MORPH_RECT, Size(7, 5));
	morphologyEx(bank_gray, bank_tophat, MORPH_TOPHAT, element1);
	show("bank_tophat", bank_tophat);
	Mat grad_x,close_image,th_image;
	Sobel(bank_tophat, grad_x, CV_16S, 1, 0, 3);
	convertScaleAbs(grad_x, grad_x);
	show("absgrad_x", grad_x);
	morphologyEx(grad_x, close_image, MORPH_CLOSE, element1);
	morphologyEx(close_image, close_image, MORPH_CLOSE, element2);
	threshold(close_image, th_image, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
	imshow("th_image", th_image);
	//绘制轮廓
	vector<vector<Point>>contoures; vector<Vec4i>hierarchy1;
	findContours(th_image.clone(), contoures, hierarchy1, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
	float rate;vector<vector<Point>>::iterator itr;
	itr = contoures.begin(); Rect srcRect1;
	while (itr != contoures.end())
	{
		srcRect1 = boundingRect(*itr);
		rate = srcRect1.width / float(srcRect1.height);
		if (rate < 1.72 || rate > 1.8)
		{
			if (srcRect1.width < 45 || srcRect1.width > 55 || srcRect1.height<25 || srcRect1.height > 33)
			{
				itr = contoures.erase(itr);
			}
		}
		else { itr++; }
	}
	Mat new_image=bank_image,clone();
	drawContours(new_image, contoures, -1, Scalar(0, 0, 255), 1);
	imshow("new_image", new_image);
	//-------------------------------------------------------------
	vector<Mat>image_roi1; Mat roi1; vector<Rect>srcRect2(contoures.size());
	Mat roi_th;
	for (unsigned int i = 0; i < contoures.size(); ++i)
	{
		srcRect2[i] = boundingRect(contoures[i]);
		roi1 = bank_gray(Rect(srcRect2[i].x, srcRect2[i].y, srcRect2[i].width, srcRect2[i].height));
		threshold(roi1, roi_th, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
		show("roi_th", roi_th);
		vector<vector<Point>>c; vector<Vec4i>h;
		findContours(roi_th, c, h, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
		vector<Rect>R(c.size()); Mat small_roi; int serise_unm = 0;
        vector<int>num123;
		for (unsigned int j = 0; j < c.size(); ++j)
		{
			R[j] = boundingRect(c[j]);
			small_roi = roi_th(Rect(R[j].x, R[j].y, R[j].width, R[j].height));
			resize(small_roi, small_roi, Size(57, 88));
			show("small_roi", small_roi);
			//模板匹配
			serise_unm=temple_image(small_roi);
			num123.push_back(serise_unm);
		}
		char groupOutput[300];
		for (int t = 0; t < num123.size(); ++t)
		{
			cout << num123.at(t) << " ";
		}
		putText(bank_image, groupOutput, Point(srcRect2[i].x, srcRect2[i].y - 20),
			FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2);
		show("putText", bank_image);
		num123.clear();
	}

其他的辅助函数

void show(string name, Mat img)//显示函数
{
	imshow(name, img);
	waitKey(0);
	destroyAllWindows();
}
void sorted_image(vector<Rect>&img, unsigned int n)//轮廓排序
{
	Rect temp;
	bool flage;
	for (unsigned int i = 0; i < n - 1; ++i)
	{
		flage = false;
		for (unsigned int j = 0; j < n - i - 1; ++j)
		{
			if (img[j].x > img[j + 1].x)
			{
				temp = img[j]; img[j] = img[j + 1]; img[j + 1] = temp;
				flage = true;
			}
		}
		if (flage)
		{
			flage = false;
			for (unsigned int t = n - i - 2; t > 0; t--)
			{
				if (img[t-1].x > img[t].x)
				{
					temp = img[t-1]; img[t-1] = img[t]; img[t] = temp;
					flage = true;
				}
			}
		}
		if (flage == false) { break; }
	}
}
Mat substract(Mat &src, Mat&dst)//两幅图像相减
{
	int sum = 0; Mat result = Mat::zeros(src.rows, src.cols, CV_8UC1);
	for (int i = 0; i < src.rows; ++i)
	{
		uchar *data1 = src.ptr<uchar>(i);
		uchar*data2 = dst.ptr<uchar>(i);
		uchar*data3 = result.ptr<uchar>(i);
		for (int j = 0; j < src.cols; ++j)
		{
			data3[j] = abs(data1[j] - data2[j]);
		}

	}
	return result;
}
int get_One(Mat image)
{
	threshold(image, image, 0, 255, CV_THRESH_BINARY|CV_THRESH_OTSU);
	int sum_one = 0;
	for (int i = 0; i < image.rows; ++i)
	{
		uchar*data = image.ptr<uchar>(i);
		for (int j = 0; j < image.cols; ++j)
		{
			if (data[j] > 0) { sum_one += 1; }

		}
	}return sum_one;
}
//-----------------------------------------------------
int temple_image(Mat img)//模板匹配
{
	Mat src_image; int temp = 0; float sum = 0; float max = 200000000; int seriesNum = 0;
	float c = 0.0; float n1 = 0.0; float n2 = 0.0; Mat result;
	for (int i = 0; i < 10; ++i)
	{
		char name[520];
		sprintf_s(name, "C:\\Users\\clg2021\\Desktop\\temple\\%d.jpg", i);
		src_image = imread(name);
		if (!src_image.data) { cout << "failed to read" << endl; system("pause"); }
		//n2 = get_One(img)+get_One(src_image);
		//n1=substract(img, src_image);
		//c = n1 / n2;
		result = substract(img, src_image);
		c = get_One(result);
		if (c < max) {
			max = c; seriesNum
				= i;
		}
	}
	return seriesNum;
}
  • 4
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

沐雨清风 จุ๊บ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值