个人学习日记-用matlab简单实现车牌识别

1.代码实现及逐层解析

1.1核心代码

clc; % 清除命令窗口。
clear; % 清除工作区中的所有变量。

% 导入图像
Img = imread("car.png"); % 读取图像文件 "car.png"。
figure, imshow(Img), title('原图'); % 显示原始图像,并设置标题为 "原图"。

% 图像增强,调整对比度
j = imadjust(Img, stretchlim(Img)); % 调整图像对比度,使用拉伸限制范围的方法。

% 灰化图像
grayImage = rgb2gray(j); % 将增强后的图像转换为灰度图。
figure, imshow(grayImage);
title('经过灰化后的图像'); % 显示灰度图,并设置标题为 "经过灰化后的图像"。

% 平滑处理 - 使用高斯滤波减少噪声
smoothedImage = imgaussfilt(grayImage, 2); % 高斯滤波,标准差为 2。
figure, imshow(smoothedImage), title('平滑处理后的图像'); % 显示平滑后的图像。

% 锐化处理 - 使用拉普拉斯算子增强边缘
sharpenedImage = imsharpen(smoothedImage, 'Radius', 2, 'Amount', 1); 
% 锐化图像,半径为 2,增强强度为 1。
figure, imshow(sharpenedImage), title('锐化处理后的图像'); % 显示锐化后的图像。

% 边缘检测
edgeImage = imbinarize(sharpenedImage); % 对锐化后的图像进行二值化。
[e1, s1] = edge(edgeImage, 'sobel', 0.03, 'both'); 
% 使用 Sobel 算子进行边缘检测,阈值为 0.03,检测双边缘。
figure, imshow(e1), title('经过边缘检测后的图像'); % 显示边缘检测后的图像。

% 形态学处理
se1 = [1; 1; 1]; % 定义腐蚀操作的结构元素(线性结构)。
erodedImage = imerode(e1, se1); % 腐蚀操作,去除细小噪声。
figure, imshow(erodedImage), title('经过腐蚀后的图像'); % 显示腐蚀后的图像。

se2 = strel('rectangle', [15, 45]); % 定义闭操作的矩形结构元素(15×45)。
closedImage = imclose(erodedImage, se2); % 使用闭操作填补间隙。
figure, imshow(closedImage), title('经过闭合的图像'); % 显示闭合后的图像。

% 提取车牌区域
stats = regionprops(closedImage, 'all'); 
% 提取闭合图像中每个区域的属性(包括面积和边界框等)。
areas = [stats.Area]; % 获取所有区域的面积。
[idx, max_area] = max(areas); % 找到面积最大的区域的索引和面积。
cropped_image = imcrop(sharpenedImage, stats(max_area).BoundingBox); 
% 根据面积最大的区域的边界框裁剪图像,提取车牌区域。
figure, imshow(cropped_image);
title('定位到的车牌'); % 显示裁剪出的车牌区域。

% 二值化车牌图像
binaryPlate = imbinarize(cropped_image, 'adaptive'); % 自适应阈值二值化车牌图像。
figure, imshow(binaryPlate), title('二值化车牌'); % 显示二值化的车牌。

% 字符分割
characterRegions = regionprops(binaryPlate, 'BoundingBox', 'Area'); 
% 获取车牌中每个字符区域的边界框和面积属性。
characterRegionsTable = struct2table(characterRegions); 
% 将字符区域的结构体转换为表格。
boundingBoxes = characterRegionsTable.BoundingBox; % 提取表格中 BoundingBox 列。
xCoordinates = boundingBoxes(:, 1); % 获取每个区域的 x 坐标。
characterRegionsTable.x = xCoordinates; % 在表格中添加 x 坐标列。
sortedRegions = sortrows(characterRegionsTable, 'x', 'ascend'); 
% 按 x 坐标升序排列字符区域。
characterImages = {}; % 初始化存储分割字符图像的单元数组。

for i = 1:height(sortedRegions)
    charBBox = table2array(sortedRegions(i, 'BoundingBox')); 
    % 获取当前字符的边界框。
    charArea = table2array(sortedRegions(i, 'Area')); 
    % 获取当前字符的面积。
    if charArea > 500 % 忽略面积小于 500 的噪声区域。
        charImage = imcrop(binaryPlate, charBBox); 
        % 根据边界框裁剪字符图像。
        charImage = imresize(charImage, [20 20]); 
        % 将字符图像调整为 20×20 的固定大小。
        characterImages{end+1} = charImage; % 保存分割的字符图像。
        figure, imshow(charImage), title(['分割的字符 ' num2str(i)]); 
        % 显示当前分割的字符图像。
    end
end

% 字符识别
templates = loadTemplates(); % 加载字符模板(假设已实现模板加载函数)。
plateNumber = ''; % 初始化车牌号字符串。
for i = 1:length(characterImages)
    charImage = characterImages{i}; % 获取当前字符图像。
    recognizedChar = matchCharacter(charImage, templates); 
    % 使用模板匹配方法识别字符。
    plateNumber = [plateNumber recognizedChar]; 
    % 将识别出的字符拼接到车牌号字符串中。
end

disp(['车牌号为: ', plateNumber]); % 输出识别出的车牌号。

1.2字符集模版代码

function templates = loadTemplates()
    % 定义模板字符集,可以包括字母和数字
    chars = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'J', 'K', 'L', 'M', 'N', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ...
             '0', '1', '2', '3', '4', '5', '6', '7', '8', '9'];

    % 创建一个结构数组来存储模板
    templates = struct();
    
    % 为每个字符加载对应的模板
    for i = 1:length(chars)
        filename = ['templates/' chars(i) '.jpg'];  % 假设模板图片以字符命名
        if exist(filename, 'file')
            templates(i).char = chars(i);
            templates(i).image = imread(filename);
        else
            warning('模板文件 %s 不存在!', filename);
        end
    end
end

 1.3匹配字符代码

function recognizedChar = matchCharacter(charImage, templates)
    bestMatchScore = -Inf;  % 初始化匹配分数
    recognizedChar = '';    % 初始化识别结果

    % 将 charImage 转换为灰度图像(如果它是彩色图像)
    if size(charImage, 3) == 3
        charImage = rgb2gray(charImage);
    end
    
    % 转换为 double 类型,以便 normxcorr2 可以正确处理
    charImage = im2double(charImage);
    
    % 遍历所有模板进行匹配
    for i = 1:length(templates)
        templateImage = templates(i).image; % 获取模板图像
        
        % 如果模板图像是彩色的,则转换为灰度图像
        if size(templateImage, 3) == 3
            templateImage = rgb2gray(templateImage);
        end
        
        % 转换为 double 类型
        templateImage = im2double(templateImage);
        
        % 使用归一化互相关计算匹配度
        corrScore = normxcorr2(templateImage, charImage);
        
        % 查找相关性矩阵中的最大值,表示最匹配的位置
        maxScore = max(corrScore(:));
        
        if maxScore > bestMatchScore
            bestMatchScore = maxScore;
            recognizedChar = templates(i).char; % 记录当前最匹配的字符
        end
    end
end

2.一些重要函数的作用及解释

2.1函数 stretchlim 的作用

stretchlim 用于计算图像亮度范围(即灰度值)的上下限,用于对比度拉伸。它会忽略一部分极小的像素值(通常是极暗或极亮的像素),避免这些像素过度影响调整结果。

语法:

limits = stretchlim(Img, tol)
  • Img: 输入图像,可以是灰度图或 RGB 图像。
  • tol: 阈值范围,表示忽略的低端和高端像素比例(默认为 [0.01, 0.99],即忽略最暗 1% 和最亮 1% 的像素)。
  • limits: 返回两值的向量 [low, high],即被认为有效的灰度范围。

例如,对于灰度图像,[low, high] 表示仅保留灰度值在 low 和 high 之间的像素范围,超出范围的像素会被压缩。

2.2函数 imadjust 的作用

imadjust 是 MATLAB 中常用的对比度调整函数,可以将图像的灰度值拉伸到指定范围。

语法:

adjustedImg = imadjust(Img, [low_in high_in], [low_out high_out])
  • [low_in high_in]: 输入图像的灰度范围(由 stretchlim 提供)。
  • [low_out high_out]: 输出图像的灰度范围(通常是 [0, 1],即全灰度动态范围)。

它将灰度值线性映射到新范围,增强图像对比度。

2.3函数 imgaussfilt的作用

专用函数 imgaussfilt,可以轻松实现高斯滤波。高斯滤波(Gaussian Filtering) 是一种利用高斯函数分布的权重对图像进行平滑处理的滤波方法,常用于减少图像中的噪声,同时保留边缘细节信息。其核心思想是:

  • 赋予中心像素较高的权重,周围像素较低的权重
  • 去除局部的快速变化(如噪声),使图像平滑。

语法:

smoothedImage = imgaussfilt(Img, sigma);

  • Img:输入图像。
  • sigma:高斯分布的标准差,控制模糊程度(较大的值会导致更强的模糊效果)。

 通过调节 sigma 的值,可以控制噪声去除的程度和图像模糊程度。

2.4函数 imsharpen的作用

MATLAB 提供了 imsharpen 函数,用于对图像进行锐化处理,内部实现可以基于拉普拉斯算子。拉普拉斯算子(Laplacian Operator) 是一种常用的边缘增强方法。它通过计算图像像素的二阶导数,边缘区域的像素变化较大,因此二阶导数值高,可以用来检测边缘。突出图像中的高频部分(如边缘和细节),从而达到增强边缘的效果。

拉普拉斯算子主要用于:

  • 增强边缘:突出图像中的边缘区域。
  • 抑制平滑区域:平坦的区域由于像素值变化小,会被弱化。

代码解析:

sharpenedImage = imsharpen(smoothedImage, 'Radius', 2, 'Amount', 1);
figure, imshow(sharpenedImage), title('锐化处理后的图像');

参数说明:

  • smoothedImage:输入图像(通常是经过平滑处理后的图像)。
  • 'Radius':锐化时的影响半径(决定边缘增强的范围)。
  • 'Amount':增强强度,数值越高,边缘越明显。

拉普拉斯算子能突出图像中的细节和边缘,直接通过卷积操作即可完成。 如果图像噪声未被平滑处理,噪声也会被增强,对原始图像的平滑程度要求较高。

2.5函数imbinarize的作用

自动二值化函数imbinarize内部会根据图像特性选择合适的阈值。二值化(Binarization) 是图像处理中将图像像素值转换为两个值(通常是 0 和 1 或黑白)的操作。边缘检测中的二值化是将边缘提取结果转换为清晰的二值边界图像,便于后续处理(如形态学操作、目标区域提取等)。

代码解析:

edgeImage = imbinarize(sharpenedImage); % 对锐化后的图像进行二值化
[e1, s1] = edge(edgeImage, 'sobel', 0.03, 'both'); % 使用 Sobel 算子进行边缘检测

  • imbinarize:

    • 自动二值化函数,根据图像像素值分布动态计算阈值。
    • 将锐化后的图像(灰度图)转化为二值图像。
  • edge:

    • 采用 Sobel 算子进行边缘检测。
    • 参数说明:
      • 'sobel':指定使用 Sobel 算子。
      • 0.03:边缘检测的阈值,越低会检测更多边缘。
      • 'both':检测图像水平和垂直方向的边缘。

2.6函数edge的作用

MATLAB 中的 edge 函数用于 边缘检测。它可以检测图像中灰度值变化剧烈的区域,这些区域通常是图像的边缘部分。edge 支持多种边缘检测方法(如 Sobel、Canny、Prewitt 等),适用于不同的应用场景。

语法:

BW = edge(I, method, threshold, direction)

参数解释

  1. I:

    • 输入图像,可以是灰度图像或二值图像。
    • 如果是彩色图像,需先转换为灰度图(使用 rgb2gray)。
  2. method:

    • 指定边缘检测算法。支持以下方法:
      • 'Sobel'(默认):基于图像梯度计算的经典边缘检测方法。
      • 'Prewitt':类似于 Sobel,但对噪声的抑制能力稍弱。
      • 'Roberts':适用于检测快速变化的边缘。
      • 'Canny':常用的边缘检测方法,结合噪声抑制和精确边缘检测。
      • 'log':基于拉普拉斯高斯算子的边缘检测。
      • 'zerocross':检测图像二阶导数的零交叉点。
  3. threshold(可选):

    • 边缘检测的阈值(通常是梯度值)。默认为自动计算。
    • 单一值:所有大于该值的像素被认为是边缘。
    • 两个值(仅对 'Canny' 有效):分别表示低阈值和高阈值,用于双阈值检测。
  4. direction(可选):

    • 指定检测的方向。适用于 Sobel、Prewitt 和 Roberts 算子:
      • 'horizontal':只检测水平方向的边缘。
      • 'vertical':只检测垂直方向的边缘。
      • 'both'(默认):同时检测水平方向和垂直方向的边缘。

2.7函数imerode的作用

腐蚀(Erosion)是图像形态学中的一种基本操作,主要用于缩小目标区域去除噪声,或分离目标。它通常用于二值图像处理,但也可以扩展到灰度图像。腐蚀操作通过一个称为结构元素(Structuring Element, SE)的窗口,对图像进行像素值的最小值运算。

二值图像中的腐蚀:

  • 结构元素在目标图像上滑动。
  • 如果结构元素的所有白色像素都完全被图像中的白色像素覆盖,则输出对应位置像素为白(值为 1);否则为黑(值为 0)。
  • 结果是:目标区域的边界被“侵蚀”,目标变得更小。

语法:

erodedImage = imerode(inputImage, se);
  • inputImage:输入图像(通常是二值图像)。
  • se:结构元素(可以通过 strel 函数生成)。
  • erodedImage:腐蚀后的输出图像。

腐蚀操作的优缺点:

优点:简单高效,适用于噪声去除和目标区域分离;可以灵活调整结构元素,适应不同应用场景。

缺点:会导致目标区域的尺寸缩小,可能丢失重要信息;对细小目标或弱边缘有较大影响。

2.8 函数imclose的作用

MATLAB 提供了 imclose 函数,用于实现闭操作。闭操作(Closing)是形态学处理中一种常见的操作,它是**膨胀操作(Dilation)腐蚀操作(Erosion)**的组合。具体来说:闭操作 = 先膨胀,后腐蚀。

语法:

closedImage = imclose(inputImage, se);
  • inputImage:输入的二值图像。
  • se:结构元素(可以使用 strel 函数定义)。
  • closedImage:闭操作后的输出图像。

结构元素(se)在闭操作中非常重要,它决定了处理效果:

  1. 大小
    • 较小的结构元素只会处理细小的孔洞或间隙。
    • 较大的结构元素会影响更大的区域。
  2. 形状
    • 圆形disk):适合处理光滑边界的目标。
    • 方形square):适合处理直边目标。
    • 线性line):适合连接特定方向的断开区域。

闭操作的优缺点:

优点:填补目标区域中的孔洞,连接断裂区域;平滑目标边界,适合目标分割后的预处理。

缺点:如果结构元素过大,可能会过度填补,导致目标形状失真;不适合去除孤立的噪声点(需要用开操作)。

 2.9函数regionprops的作用

regionprops 是 MATLAB 中用于分析图像区域的强大函数,它可以提取图像中连通区域的各种属性,如面积、边界框、质心等。该函数常用于二值图像中目标区域的特征提取。

在车牌识别中,regionprops 被用来提取车牌区域的属性,例如面积(用于选择最大区域)和边界框(用于裁剪车牌区域)。

语法:

stats = regionprops(BW, properties)
  • BW:输入的二值图像。
  • properties:需要提取的属性列表
  • stats:输出为一个结构体数组,每个结构体代表一个连通区域及其属性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值