模板匹配算法(手写数字识别)

研一的课程结束了,抓住暑假最后的尾巴,将模式识别与机器学习课程上的作业整理出来,当做是一次复习。

来自我b导的图

模板匹配

模板是已知的、带标签的,将未知的样本和所有模板进行匹配,计算相似度。相似度如何计算呢,我们的研究对象是图像,可以计算图像和模板特征向量之间的距离(欧式距离)。

作业要求为:使用模板匹配对手写数字,和车牌数字进行识别。数据集提供大家参考(提取码:roz1)

思路也挺简单的:

  1. 首先是做模板,将10个数字做成模板,定义一个函数将二维数组的图像展平为一纬数组,将十个模板存放在一个list中。需要对手写数字和车牌数字两种字体识别,所以需要做分别做模板
  2. 计算相似度用的是欧式距离,定义一个函数计算欧式距离
  3. 将待识别的图像分别和模型计算欧式距离,取最小距离的模型数字为识别结果 
import numpy as np
import cv2

#展平二维图像
def vector(data):
    h,w = data.shape[0:2]
    img_pixel = np.asarray(data).reshape(1,h*w)
    return img_pixel

#制作手写数字模板
def write_template():
    temple_list = []
    for i in range(0,10):
        path_tem = './课程数据集/手写数字/{}/'.format(i)
        img = cv2.imdecode(np.fromfile(path_tem+'2.bmp',np.uint8), cv2.IMREAD_GRAYSCALE)
        img_resize = cv2.resize(img, (250,250))
        tem_pixel = vector(img_resize)
        temple_list.append(tem_pixel)
    return temple_list

#制作车牌数字模板
def car_template():
    template_list2 = []
    for i in range(0,10):
        path_tem2 ='./课程数据集/车牌/{}.bmp'.format(i)
        img = cv2.imdecode(np.fromfile(path_tem2,np.uint8),cv2.IMREAD_GRAYSCALE)
        img_resize = cv2.resize(img,(250,250))
        tem_pixel = vector(img_resize)
        template_list2.append(tem_pixel)
    return template_list2

#计算欧式距离
def Euclidean_distance(x,y):
    tem = np.array(x).astype(np.float32)
    sam = np.array(y).astype((np.float32))
    num2 = np.square(tem-sam)
    return np.sqrt(np.sum(num2))

#template matching
if __name__ =="__main__":
    print('\n用手写体模板匹配\n')
    print('手写体数字匹配\n')
    template_list = write_template()
    number_list = []
    correct_num = 0
    for index in range(0,10):
        path_write = './课程数据集/手写数字/{}/'.format(index)
        sam_img = cv2.imdecode(np.fromfile(path_write + '5.bmp',np.uint8),cv2.IMREAD_GRAYSCALE)
        sam_resize = cv2.resize(sam_img,(250,250))
        sam_pixel = vector(sam_resize)
        ture_num = index
        number_list.append(index)

        #cal the Euclidean distance
        distance_list = []
        for tem in template_list:
            distance = Euclidean_distance(tem,sam_pixel)
            distance_list.append(distance)

        #cal the shortest distance
        short_dis = min(distance_list)
        short_index =distance_list.index(min(distance_list))
        if int(ture_num) == short_index:
            correct_num  += 1
        print('数字{}到模板的最短距离为:{},匹配到的类别为:{}\n'.format(ture_num,short_dis,short_index))
        distance_list.clear()
    n = len(number_list)
    print('共测试了{}个样本,正确匹配的个数为:{}'.format(n,correct_num))
    print('\n车牌数字匹配\n')
    car_num_list = []
    car_correct_num = 0
    for index in range(0,10):
        path_tem = './课程数据集/车牌/{}.1.bmp'.format(index)
        img_car_pic = cv2.imdecode(np.fromfile(path_tem,np.uint8),cv2.IMREAD_GRAYSCALE)
        img_car_pic_resize = cv2.resize(img_car_pic,(250,250))
        img_car_pixel = vector(img_car_pic_resize)
        car_ture_num = index
        car_num_list.append(index)

        #cal the Euclidean distance
        car_distance_list =[]
        for tem in template_list:
            car_distance = Euclidean_distance(tem,img_car_pixel)
            car_distance_list.append(car_distance)
        short_car_dis = min(car_distance_list)
        short_car_index = car_distance_list.index(min(car_distance_list))
        if int(car_ture_num) == int(short_car_index):
            car_correct_num +=1
        print('数字{}到模板的最短距离为:{},匹配到的类别为:{}\n'.format(car_ture_num,short_car_dis,short_car_index))
        car_distance_list.clear()
    m = len(car_num_list)
    print('共测试了{}个样本,正确匹配的个数为:{}'.format(m,car_correct_num))

    print('\n用车牌模板匹配\n')
    print('手写体数字匹配\n')
    template_list = car_template()
    number_list = []
    correct_num = 0
    for index in range(0,10):
        path_write = './课程数据集/手写数字/{}/'.format(index)
        sam_img = cv2.imdecode(np.fromfile(path_write + '5.bmp',np.uint8),cv2.IMREAD_GRAYSCALE)
        sam_resize = cv2.resize(sam_img,(250,250))
        sam_pixel = vector(sam_resize)
        ture_num = index
        number_list.append(index)

        #cal the Euclidean distance
        distance_list = []
        for tem in template_list:
            distance = Euclidean_distance(tem,sam_pixel)
            distance_list.append(distance)

        #cal the shortest distance
        short_dis = min(distance_list)
        short_index =distance_list.index(min(distance_list))
        if int(ture_num) == short_index:
            correct_num  += 1
        print('数字{}到模板的最短距离为:{},匹配到的类别为:{}\n'.format(ture_num,short_dis,short_index))
        distance_list.clear()
    n = len(number_list)
    print('共测试了{}个样本,正确匹配的个数为:{}'.format(n,correct_num))
    print('\n车牌数字匹配\n')
    car_num_list = []
    car_correct_num = 0
    for index in range(0,10):
        path_tem = './课程数据集/车牌/{}.1.bmp'.format(index)
        img_car_pic = cv2.imdecode(np.fromfile(path_tem,np.uint8),cv2.IMREAD_GRAYSCALE)
        img_car_pic_resize = cv2.resize(img_car_pic,(250,250))
        img_car_pixel = vector(img_car_pic_resize)
        car_ture_num = index
        car_num_list.append(index)

        #cal the Euclidean distance
        car_distance_list =[]
        for tem in template_list:
            car_distance = Euclidean_distance(tem,img_car_pixel)
            car_distance_list.append(car_distance)
        short_car_dis = min(car_distance_list)
        short_car_index = car_distance_list.index(min(car_distance_list))
        if int(car_ture_num) == int(short_car_index):
            car_correct_num +=1
        print('数字{}到模板的最短距离为:{},匹配到的类别为:{}\n'.format(car_ture_num,short_car_dis,short_car_index))
        car_distance_list.clear()
    m = len(car_num_list)
    print('共测试了{}个样本,正确匹配的个数为:{}'.format(m,car_correct_num))

以下内容为补充

模板匹配是图像处理的一个基础算法,在图像A中寻找到与图像B(模板)最相似的区域,opencv有相应的函数调用 cv.matchTemplate(img,template,参数)。函数不同参数的具体效果可以看看中文文档模板匹配 (apachecn.org),有趣的是cv.TM_CCOEFF_NORMED参数可以在一张图像上匹配多个对象。

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
手写数字识别系统是一种基于模板匹配的图像识别技术,可以用于识别手写数字。以下是一个基于MATLAB编程的手写数字识别系统的例子,其中使用了模板匹配算法: ```matlab % 读取数字模板 num1 = imread('num1.jpg'); num2 = imread('num2.jpg'); num3 = imread('num3.jpg'); num4 = imread('num4.jpg'); num5 = imread('num5.jpg'); num6 = imread('num6.jpg'); num7 = imread('num7.jpg'); num8 = imread('num8.jpg'); num9 = imread('num9.jpg'); num0 = imread('num0.jpg'); % 读取待识别的数字图像 testImg = imread('test.jpg'); % 对待识别的数字图像进行预处理 testImg = im2bw(testImg, graythresh(testImg)); testImg = imcomplement(testImg); testImg = bwareaopen(testImg, 30); % 对数字模板进行预处理 num1 = im2bw(num1, graythresh(num1)); num2 = im2bw(num2, graythresh(num2)); num3 = im2bw(num3, graythresh(num3)); num4 = im2bw(num4, graythresh(num4)); num5 = im2bw(num5, graythresh(num5)); num6 = im2bw(num6, graythresh(num6)); num7 = im2bw(num7, graythresh(num7)); num8 = im2bw(num8, graythresh(num8)); num9 = im2bw(num9, graythresh(num9)); num0 = im2bw(num0, graythresh(num0)); % 对待识别的数字图像进行模板匹配 corr1 = normxcorr2(num1, testImg); corr2 = normxcorr2(num2, testImg); corr3 = normxcorr2(num3, testImg); corr4 = normxcorr2(num4, testImg); corr5 = normxcorr2(num5, testImg); corr6 = normxcorr2(num6, testImg); corr7 = normxcorr2(num7, testImg); corr8 = normxcorr2(num8, testImg); corr9 = normxcorr2(num9, testImg); corr0 = normxcorr2(num0, testImg); % 找到最大相关系数 maxCorr = max([max(corr1(:)), max(corr2(:)), max(corr3(:)), max(corr4(:)), max(corr5(:)), max(corr6(:)), max(corr7(:)), max(corr8(:)), max(corr9(:)), max(corr0(:))]); % 根据最大相关系数确定识别结果 if maxCorr == max(corr1(:)) disp('识别结果为:1'); elseif maxCorr == max(corr2(:)) disp('识别结果为:2'); elseif maxCorr == max(corr3(:)) disp('识别结果为:3'); elseif maxCorr == max(corr4(:)) disp('识别结果为:4'); elseif maxCorr == max(corr5(:)) disp('识别结果为:5'); elseif maxCorr == max(corr6(:)) disp('识别结果为:6'); elseif maxCorr == max(corr7(:)) disp('识别结果为:7'); elseif maxCorr == max(corr8(:)) disp('识别结果为:8'); elseif maxCorr == max(corr9(:)) disp('识别结果为:9'); elseif maxCorr == max(corr0(:)) disp('识别结果为:0'); end ``` 该例子中,首先读取了数字模板和待识别的数字图像,然后对它们进行了预处理,包括二值化、反色、去除小面积噪声等。接着,使用`normxcorr2`函数进行模板匹配,找到最大相关系数,最后根据最大相关系数确定识别结果。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值