|
本帖最后由 xrea 于 2023-8-24 16:51 编辑
1.思路
通过已有的数字字体模板,一个个的去匹配银行卡中的数字。
2.代码
<火山程序 类型 = "通常" 版本 = 1 />
类 启动类 <公开 基础类 = 程序类>
{
方法 启动方法 <公开 类型 = 整数 @禁止流程检查 = 真>
{
// 1.对数字模板进行处理
// 读入数字模板图像
变量 局部_读入的数字模板图像 <类型 = CV矩阵类>
局部_读入的数字模板图像 = CV核心.读入图像 ("../images/reference.png", )
// 对数字模板图像转为灰度图
CV核心.颜色空间转换 (局部_读入的数字模板图像, 局部_读入的数字模板图像, , )
// 对数字模板图像进行二值化处理
CV核心.二值化 (局部_读入的数字模板图像, 局部_读入的数字模板图像, 127, 255, CV二值化阈值类型常量.反二进制阈值化)
// 进行轮廓检测
变量 局部_数字轮廓信息集合 <类型 = CV坐标容器数组>
CV核心.寻找轮廓 (局部_读入的数字模板图像, 局部_数字轮廓信息集合, , CV轮廓提取算法常量.只检测最外层轮廓, )
// 绘制出轮廓信息
变量 局部_寻找到轮廓信息图 <类型 = CV矩阵类>
局部_寻找到轮廓信息图 = 局部_读入的数字模板图像.复制 ()
CV核心.颜色空间转换 (局部_寻找到轮廓信息图, 局部_寻找到轮廓信息图, CV图像颜色空间转换常量.灰度转BGR, )
// CV核心.绘制轮廓 (局部_寻找到轮廓信息图, 局部_数字轮廓信息集合, -1, CV标量类.新建三通道 (0, 0, 255), 2, , , )
// 计算外接矩形
变量 局部_计算出的所有数字外接矩形集合 <类型 = CV矩形类容器>
计次循环 (局部_数字轮廓信息集合.取成员数 ())
{
变量 局部_坐标容器对象 <类型 = CV坐标容器>
局部_坐标容器对象 = 局部_数字轮廓信息集合.取成员 (取循环索引 ())
变量 局部_计算出的最小外接矩形 <类型 = CV矩形类>
局部_计算出的最小外接矩形 = CV核心.计算轮廓最小外接正交矩形 (局部_坐标容器对象)
局部_计算出的所有数字外接矩形集合.加入成员 (局部_计算出的最小外接矩形)
}
// 对获取到的信息进行排序
变量 局部_计数 <类型 = 整数>
变量 局部_计数2 <类型 = 整数>
循环 (0, 局部_计算出的所有数字外接矩形集合.取成员数 (), 局部_计数)
{
循环 (0, 局部_计算出的所有数字外接矩形集合.取成员数 () - 局部_计数 - 1, 局部_计数2)
{
如果 (局部_计算出的所有数字外接矩形集合.取成员 (局部_计数2).X > 局部_计算出的所有数字外接矩形集合.取成员 (局部_计数2 + 1).X)
{
局部_计算出的所有数字外接矩形集合.交换成员值 (局部_计数2, 局部_计数2 + 1)
}
}
}
变量 局部_数字图像集合 <类型 = CV矩阵类容器>
计次循环 (局部_计算出的所有数字外接矩形集合.取成员数 ())
{
变量 局部_输出图像 <类型 = CV矩阵类>
CV核心.提取ROI区域图像 (局部_读入的数字模板图像, 局部_计算出的所有数字外接矩形集合.取成员 (取循环索引 ()), 局部_输出图像)
局部_数字图像集合.加入成员 (局部_输出图像)
}
// 对之前使用过的变量进行清除
局部_计算出的所有数字外接矩形集合.清除成员 ()
// 2.开始对银行卡进行处理
// 读入银行卡图片
变量 局部_读入的银行卡图像 <类型 = CV矩阵类>
变量 局部_读入的银行卡图像2 <类型 = CV矩阵类>
变量 局部_读入的银行卡图像_原图像 <类型 = CV矩阵类>
局部_读入的银行卡图像 = CV核心.读入图像 ("../images/card1.png", )
局部_读入的银行卡图像_原图像 = 局部_读入的银行卡图像.复制 ()
// 转为灰度图
局部_读入的银行卡图像2 = 局部_读入的银行卡图像.复制 ()
CV核心.颜色空间转换 (局部_读入的银行卡图像, 局部_读入的银行卡图像2, , )
CV核心.形态学运算 (局部_读入的银行卡图像2, 局部_读入的银行卡图像2, CV形态学常量.顶帽, CV核心.获取结构元素 (, CV尺寸类.创建尺寸 (9, 3), ), , , , )
CV核心.边缘检测Canny (局部_读入的银行卡图像2, 局部_读入的银行卡图像2, 80, 200, 3, )
CV核心.形态学运算 (局部_读入的银行卡图像2, 局部_读入的银行卡图像2, CV形态学常量.闭运算, CV核心.获取结构元素 (, CV尺寸类.创建尺寸 (9, 3), ), , 3, , )
// 寻找轮廓
变量 局部_银行卡所有图形信息 <类型 = CV坐标容器数组>
CV核心.寻找轮廓 (局部_读入的银行卡图像2, 局部_银行卡所有图形信息, , CV轮廓提取算法常量.只检测最外层轮廓, )
// CV核心.绘制轮廓 (局部_读入的银行卡图像, 局部_银行卡所有图形信息, , CV标量类.新建三通道 (0, 0, 255), 3, , , )
// 根据长宽比来筛选
变量 局部_银行卡号码区域 <类型 = CV矩形类容器>
计次循环 (局部_银行卡所有图形信息.取成员数 ())
{
变量 局部_计算出来的轮廓矩形信息 <类型 = CV矩形类>
局部_计算出来的轮廓矩形信息 = CV核心.计算轮廓最小外接正交矩形 (局部_银行卡所有图形信息.取成员 (取循环索引 ()))
// CV核心.画矩形 (局部_读入的银行卡图像, 局部_计算出来的轮廓矩形信息, CV标量类.新建三通道 (0, 0, 255), , )
变量 局部_长宽比 <类型 = 小数>
局部_长宽比 = 局部_计算出来的轮廓矩形信息.宽度 / (小数)局部_计算出来的轮廓矩形信息.高度
如果 (局部_长宽比 > 2.5 && 局部_长宽比 < 4 && 局部_计算出来的轮廓矩形信息.宽度 > 90)
{
局部_计算出来的轮廓矩形信息.宽度 = 局部_计算出来的轮廓矩形信息.宽度 + 5
局部_计算出来的轮廓矩形信息.高度 = 局部_计算出来的轮廓矩形信息.高度 + 5
局部_银行卡号码区域.加入成员 (局部_计算出来的轮廓矩形信息)
}
}
// 对数字区域进行排序
循环 (0, 局部_银行卡号码区域.取成员数 (), 局部_计数)
{
循环 (0, 局部_银行卡号码区域.取成员数 () - 局部_计数 - 1, 局部_计数2)
{
如果 (局部_银行卡号码区域.取成员 (局部_计数2).X > 局部_银行卡号码区域.取成员 (局部_计数2 + 1).X)
{
局部_银行卡号码区域.交换成员值 (局部_计数2, 局部_计数2 + 1)
}
}
}
// 对每一块数字区域进行处理
变量 局部_计算出来的轮廓矩形信息 <类型 = CV矩形类>
变量 count <类型 = 整数>
循环 (0, 局部_银行卡号码区域.取成员数 (), count)
{
局部_计算出来的轮廓矩形信息 = 局部_银行卡号码区域.取成员 (count)
变量 局部_数字区域 <类型 = CV矩阵类>
变量 局部_数字区域2 <类型 = CV矩阵类>
CV核心.提取ROI区域图像 (局部_读入的银行卡图像, 局部_计算出来的轮廓矩形信息, 局部_数字区域)
局部_数字区域2 = 局部_数字区域.复制 ()
CV核心.颜色空间转换 (局部_数字区域2, 局部_数字区域2, , )
CV核心.二值化 (局部_数字区域2, 局部_数字区域2, 127, 255, CV二值化阈值类型常量.二进制阈值化)
变量 局部_数字信息 <类型 = CV坐标容器数组>
变量 局部_卡号信息 <类型 = CV矩形类容器>
CV核心.寻找轮廓 (局部_数字区域2, 局部_数字信息, , CV轮廓提取算法常量.只检测最外层轮廓, )
计次循环 (局部_数字信息.取成员数 ())
{
变量 局部_数字外形 <类型 = CV坐标容器>
局部_数字外形 = 局部_数字信息.取成员 (取循环索引 ())
变量 局部_计算出来的轮廓矩形 <类型 = CV矩形类>
局部_计算出来的轮廓矩形 = CV核心.计算轮廓最小外接正交矩形 (局部_数字外形)
// 局部_计算出来的轮廓矩形.X = 局部_计算出来的轮廓矩形.X - 2
// 局部_计算出来的轮廓矩形.Y = 局部_计算出来的轮廓矩形.Y - 2
// 局部_计算出来的轮廓矩形.宽度 = 局部_计算出来的轮廓矩形.宽度 + 4
// 局部_计算出来的轮廓矩形.高度 = 局部_计算出来的轮廓矩形.高度 + 4
局部_卡号信息.加入成员 (局部_计算出来的轮廓矩形)
}
循环 (0, 局部_卡号信息.取成员数 (), 局部_计数)
{
循环 (0, 局部_卡号信息.取成员数 () - 局部_计数 - 1, 局部_计数2)
{
如果 (局部_卡号信息.取成员 (局部_计数2).X > 局部_卡号信息.取成员 (局部_计数2 + 1).X)
{
局部_卡号信息.交换成员值 (局部_计数2, 局部_计数2 + 1)
}
}
}
// 对区域内的数字进行匹配
变量 局部_目标区域数字 <类型 = 文本型>
计次循环 (局部_卡号信息.取成员数 ())
{
变量 temp <类型 = CV矩阵类>
变量 计数 <类型 = 整数>
CV核心.提取ROI区域图像 (局部_数字区域2, 局部_卡号信息.取成员 (取循环索引 ()), temp)
变量 局部_各数字匹配概率集合 <类型 = 小数数组类>
局部_各数字匹配概率集合.清零 ()
循环 (0, 局部_数字图像集合.取成员数 (), 计数)
{
变量 局部_数字图像 <类型 = CV矩阵类>
局部_数字图像 = 局部_数字图像集合.取成员 (计数)
CV核心.置矩阵尺寸 (局部_数字图像, 局部_数字图像, CV尺寸类.创建尺寸 (temp.宽度, temp.高度), )
变量 局部_匹配结果 <类型 = CV矩阵类>
CV核心.模板匹配 (temp, 局部_数字图像, 局部_匹配结果, CV模板匹配方法常量类.标准归一化系数相关性, )
变量 min_val <类型 = 小数>
变量 max_val <类型 = 小数>
变量 min_loc <类型 = 小数>
变量 max_loc <类型 = 小数>
CV核心.求矩阵最值 (局部_匹配结果, 取变量地址 (min_val), 取变量地址 (max_val), 取变量地址 (min_loc), 取变量地址 (max_loc), )
局部_各数字匹配概率集合.加入成员 (max_val)
}
局部_目标区域数字 = 局部_目标区域数字 + 到文本 (计算小数数组最大值索引 (局部_各数字匹配概率集合))
}
CV核心.写图像文本 (局部_读入的银行卡图像, 局部_目标区域数字, 局部_计算出来的轮廓矩形信息.X + 10, 局部_计算出来的轮廓矩形信息.Y, CV字体常量.书写风格体, 1, CV标量类.新建三通道 (0, 255, 255), 3)
}
CV核心.显示图像 ("提取后的图像", 局部_读入的银行卡图像, , )
CV核心.显示图像 ("原图像", 局部_读入的银行卡图像_原图像, , )
CV核心.等待按键 (0)
CV核心.关闭窗口 ("images")
返回 (1)
}
方法 计算小数数组最大值索引 <公开 类型 = 整数 返回值注释 = "返回最大值所在的索引" 折叠>
参数 arg_数组对象 <类型 = 小数数组类>
{
变量 index <类型 = 整数>
变量 max_val <类型 = 小数>
如果 (arg_数组对象.是否为空 ())
{
返回 (-1)
}
index = 0
max_val = arg_数组对象.取成员 (0)
计次循环 (arg_数组对象.取成员数 ())
{
如果 (max_val < arg_数组对象.取成员 (取循环索引 ()))
{
index = 取循环索引 ()
max_val = arg_数组对象.取成员 (取循环索引 ())
}
}
返回 (index)
}
}
3.效果图
4.附带资源
images.zip
(530.64 KB, 下载次数: 32)
|
评分
-
查看全部评分
|