多媒体制作技术大作业.docx

上传人:b****4 文档编号:3778039 上传时间:2022-11-25 格式:DOCX 页数:18 大小:803.85KB
下载 相关 举报
多媒体制作技术大作业.docx_第1页
第1页 / 共18页
多媒体制作技术大作业.docx_第2页
第2页 / 共18页
多媒体制作技术大作业.docx_第3页
第3页 / 共18页
多媒体制作技术大作业.docx_第4页
第4页 / 共18页
多媒体制作技术大作业.docx_第5页
第5页 / 共18页
点击查看更多>>
下载资源
资源描述

多媒体制作技术大作业.docx

《多媒体制作技术大作业.docx》由会员分享,可在线阅读,更多相关《多媒体制作技术大作业.docx(18页珍藏版)》请在冰豆网上搜索。

多媒体制作技术大作业.docx

多媒体制作技术大作业

 

 

姓名王涛涛学号0093997

专业09计算机班级

(1)班

实验项目名称车牌识别统设计

指导教师方志军

完成时间2011.12.23

 

一、实验目的及要求:

1)实验内容:

(1)通过在网上查阅资料,熟悉OpenCV的基本数据结构。

(2)利用OpenCV进行基本图像处理,实现图像预处理,包括对图像的平滑处理,边缘检测,二次线性插值等,最后实现对车牌识别。

2)实验要求:

利用OpenCV在VC6环境下开发。

写成命令行程序,无需设计图形用户界面。

保持良好的代码风格:

可读性、注释、变量命名、缩进等

二、实验方法与步骤

1、概要设计

(1)通过在网上查阅资料,熟悉OpenCV的基本数据结构。

(2)利用OpenCV进行基本图像处理,实现图像平滑处理、图像的分割,图像边缘提取算法,从而达到对车牌识别。

2、详细设计(文件组成、数据结构及函数设计、关键算法等)

2.1在图像预处理阶段

要实现的功能是提高得到图像的质量,首先是采用平滑滤波处理消除系统噪声,之后若要采用边缘提取,则在此步中要加强边缘。

现在已有的加强边缘的方法有:

(1)利用高通滤波器加强边缘后与原图像相加。

(2)利用低通滤波器取得背景后与原图像相减;对于已经进行过边缘加强的图像,再使用一定的方法进行阈算子等提取边缘。

(3)利用CANNY算子提取边缘。

2.2车牌识别系统流程图

输出结果

2.3图像数据结构

(i)灰度化函数cvCvtColor();

cvCvtColor()函数是将彩色图片转化成灰色进行处理,该灰度化函数为cvCvtColor(inputImg,grayImg,CV_BGR2GRAY);其中inputImg是输入的车牌号图片,要求是8-bit,16-bit或32-bit单倍精度浮点数影像;grayImg是处理后的灰度图片,输出的是8-bit,16-bit或32-bit单倍精度浮点数影像;CV_RGB2GRAY是色彩空间转换指标。

在OpenCV开发手册我们可以看到cvCvtColor(src,hsv,CV_BGR2HSV)基本用法如下所示。

#include"cv.h"

#include"highgui.h"

intmain(intargc,char**argv)

{

IplImage*src;

if(argc==2&&(src=cvLoadImage(argv[1],1))!

=0){

//计算HSV(hue色度saturation饱和度value亮度)并分解成为不同的平面

IplImage*hsv=cvCreateImage(cvGetSize(src),8,3);

cvCvtColor(src,hsv,CV_BGR2HSV);

//可以更改为CV_BGR2GRAY,可以自己尝试一下

cvNamedWindow("src",CV_WINDOW_AUTOSIZE);

cvShowImage("src",src);

cvNamedWindow("dst",CV_WINDOW_AUTOSIZE);

cvShowImage("dst",hsv);

cvWaitKey(0);

return0;

}

return0;

}

(ii)高斯滤波平滑处理函数CVSmooth()

在数字图像处理中,由于受到成像方法的限制,图像中的边缘、细节特征等重要信息常湮没于噪声信号中,给图像的后继处理带来很大的影响。

因此对含噪声图像进行适当的预处理是图像处理中的一个重要问题,对于改善图像质量具有重要的意义。

图像去噪是图像预处理中一项应用比较广泛的技术,其作用是为了提高图像的信噪比,突出图像的期望区域

各种方法的图像平滑

voidcvSmooth(constCvArr*src,CvArr*dst,intsmoothtype=CV_GAUS

SIAN,intparam1=3,intparam2=0,doubleparam3=0);

其中:

src输入图像.dst输出图像.smoothtype平滑方法:

.

(1)CV_BLUR_NO_SCALE(简单不带尺度变换的模糊)-对每个象素领域param1×param2求和。

如果邻域大小是变化的,可以事先利用函数cvIntegral计算积分图像。

(2)CV_BLUR(simpleblur)-对每个象素邻域param1×param2求和并做尺度变换1/(param1•param2).

(3)CV_GAUSSIAN(gaussianblur)-对图像进行核大小为param1×param2的高斯卷积

(4)CV_MEDIAN(medianblur)-发现邻域param1×param1的中值(i.e.邻域是方的).

(5)CV_BILATERAL(双滤波)-应用双向3x3滤波,彩色sigma=param1,空间sigma=param2.关于双向滤波,

param1:

平滑操作的第一个参数.

param2:

平滑操作的第二个参数param2为零对应简单的尺度变换和高斯模糊。

param3:

对应高斯参数的Gaussiansigma(标准差).如果为零,这由下面的核尺寸计算。

函数cvSmooth可使用上面任何一种方法平滑图像。

每一种方法都有自己的特点以及局限。

(iii)用于对图像的边缘检测(采用canny算法)。

1.Canny边缘检测基本原理

(1)图象边缘检测必须满足两个条件:

一能有效地抑制噪声;二必须尽量精确确定边缘的位置。

(2)根据对信噪比与定位乘积进行测度,得到最优化逼近算子。

这就是Canny边缘检测算子。

(3)类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法。

2.voidcvCanny(constCvArr*image,CvArr*edges,doublethreshold1,doublethreshold2,intaperture_size=3);

其中threshold1:

第一个阈,threshold2:

第二个阈值,aperture_sizeSobel:

算子内核大小.函数cvCanny采用Canny算法发现输入图像的边缘而且在输出图像中标识这些边缘。

threshold1和threshold2当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。

3.在opencv中文论坛上我们可以找到关于Canny算法的详细过程

#include"cv.h"

#include"cxcore.h"

#include"highgui.h"

intmain(intargc,char**argv)

{

IplImage*pImg=NULL;//声明IplImage指针

IplImage*pCannyImg=NULL;

char*filename;

filename="F:

\\练习\\VC6.0\\opencv\\1.jpg";

pImg=cvLoadImage(filename,1);//载入图像,强制转化为Gray

if((pImg=cvLoadImage(filename,0))!

=0){

pCannyImg=cvCreateImage(cvGetSize(pImg),IPL_DEPTH_8U,1);

cvCanny(pImg,pCannyImg,50,150,3);

cvNamedWindow("src",1);//创建窗口

cvNamedWindow("canny",1);

cvShowImage("src",pImg);//显示图像

cvShowImage("canny",pCannyImg);

cvWaitKey(0);//等待按键

cvDestroyWindow("src");//销毁窗口

cvDestroyWindow("canny");//释放图像

cvReleaseImage(&pImg);

cvReleaseImage(&pCannyImg);

return0;

}

return-1;

}

图1Canny算法处理后

(iv)cvSetImageROI()函数

cvSetImageROI()函数基于给定的矩形设置感兴趣区域,也就是从图片中找到我们需要的部分。

voidcvSetImageROI(IplImage*image,CvRectrect);函数cvSetImageROI基于给定的矩形设置图像的ROI(感兴趣区域).如果ROI是NULL并且参数RECT的值不等于整个图像,ROI被分配.不像COI,大多数的OpenCV函数支持ROI并且处理它就像它是一个分离的图像(例如,所有的像素坐标从ROI的左上角或左下角(基于图像的结构)计算。

下面用一段代码来说明cvSetImageROI函数:

#include"cv.h"

#include"highgui.h"

#include"stdio.h"

intmain()

{

IplImage*img=cvLoadImage("F:

\\练习\\VC6.0\\opencv\\1.jpg");

IplImage*img1=cvLoadImage("F:

\\练习\\VC6.0\\opencv\\2.jpg");

cvSetImageROI(img1,cvRect(0,0,256,256));//设置img1的ROI区域

cvResize(img,img1);//缩放img图像,并将数据拷贝到img1

cvResetImageROI(img1);//这句是必须的,在img1的ROI区域显示img

cvNamedWindow("img1",1);

cvShowImage("img1",img1);

cvWaitKey(0);

cvDestroyAllWindows();

return0;

}

图2处理前图3处理后

 

3、程序的运行与实现

本程序采用的是一种很简单的识别方法,即将分割出的字符与模板想比较,得到结果图像后检测图像中非零像素的个数,当个数最少时即判定为匹配图像。

因为模板的大小是22*14的,所以需要将所得分割字符统一大小,之后再相比较,检测最小值。

具体实现方面还是让我痛苦了一段时间,如何用循环实现字符自动匹配和字符的显示比较的困难。

后来我采用的方法是建立字符串数组存储模板图片的文件名,利用数组来自动匹配,显示方面我采用将汉字分成若干个SWITCH语句,利用数组中的数字表示汉字序数,不同的序数执行不同的分支程序。

图4原图像

图5分割结果

三、实验感想

我的这套车牌识别系统是基于opencv建立的,在网上虽然有很多matlab的识别程序,但真正用opencv而非直接使用VC识别的系统很少,所以我采用的方法是在借鉴matlab程序的思路的基础上,自己搭建一个VC平台,其中的模块很多是在网上找的,但他们之间的连接和搭配,以及一些方法的选择也加入了我自己的想法。

通过这次的大作业,我对于图像处理课上讲授的内容有了更深的理解,对一些算法的应用有了更深的感受,比如开闭操作、投影直方图和最佳全局阈值等,而且在这个过程中,也熟悉了opencv和VC的编程方法,真的是收益良多。

四、附录

源代码

#include

#include

#include

#include

usingnamespacestd;

#pragmacomment(lib,"cv.lib")

#pragmacomment(lib,"cxcore.lib")

#pragmacomment(lib,"highgui.lib")

#defineT27

#defineT12

#defineS(image,x,y)((uchar*)(image->imageData+image->widthStep*(y)))[(x)]//S

voidmain()

{

IplImage*src;

IplImage*pImg8u=NULL;//灰度图

IplImage*pImg8uSmooth=NULL;//高斯滤波后的图

IplImage*pImgCanny=NULL;//二值化的图

IplImage*pImgHist=NULL;//直方图

inthist_size=155;

floatrange_0[]={0,256};

float*ranges[]={range_0};

inti,j,bin_w;

floatmax_value,min_value;

intmin_dx,max_dx;

introw_start,row_end;//用来记录车牌开始,结束行

intcol_start,col_end;//用来记录车牌开始,结束列

intcount=0;//用来记录行或列的白点个数

src=cvLoadImage("8.jpg",-1);

pImg8uSmooth=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);

pImg8u=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);

pImgCanny=cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);

cvCvtColor(src,pImg8u,CV_RGB2GRAY);//灰度化

cvSmooth(pImg8u,pImg8uSmooth,CV_GAUSSIAN,3,0,0);//高斯滤波

cvCanny(pImg8uSmooth,pImgCanny,100,200,3);//二值化

row_start=0;

row_end=0;

col_start=0;

col_end=0;

introw[120];

intcol[340];

intk;

k=0;

boolflag=false;

for(j=0;jheight;j++)//找到上行开始

{

count=0;

for(i=0;iwidth-1;i++)

{

if(S(pImgCanny,i,j)!

=S(pImgCanny,i+1,j))//统计行跳数

count++;

if(count>T)

{

row[k]=j;

k++;

break;

}

}

}

for(i=0;i

{

if((row[i]==row[i+1]-1)&&(row[i+1]==row[i+2]-1)){

row_start=row[i];

break;

}

}

cout<<"thestartrow:

"<

cvLine(pImg8u,cvPoint(0,row_start),cvPoint(src->width,row_start),cvScalar(255,0,0),1,8,0);

for(i=k-1;i>row_start;i--)//从下边开始,3行连续时认为是起始行

{

if((row[i]==row[i-1]+1)&&(row[i-1]==row[i-2]+1)){

row_end=row[i];

break;

}

}

cout<<"theendrow:

"<

cvLine(pImg8u,cvPoint(0,row_end),cvPoint(src->width,row_end),cvScalar(255,0,0),1,8,0);

flag=false;

for(i=10;iwidth;i++)//找到左列开始

{

count=0;

for(j=row_start;j

{

if(S(pImgCanny,i,j)==255)

count++;

if(count>T1)

{

col_start=i;

flag=true;

break;

}

}

if(flag)break;

}

cout<<"thestartcol:

"<

cvLine(pImg8u,cvPoint(col_start,row_start),cvPoint(col_start,row_end),cvScalar(255,0,0),1,8,0);

flag=false;

for(i=pImgCanny->width-10;i>col_start;i--)//找到右列开始

{

count=0;

for(j=row_start;j

{

if(S(pImgCanny,i,j)==255)

count++;

if(count>T1)

{

col_end=i;

flag=true;

break;

}

}

if(flag)break;

}

cout<<"theendcol:

"<

cvLine(pImg8u,cvPoint(col_end,row_start),cvPoint(col_end,row_end),cvScalar(255,0,0),1,8,0);

CvRectROI_rect;//获得图片感兴趣区域

ROI_rect.x=col_start;

ROI_rect.y=row_start;

ROI_rect.width=col_end-col_start;

ROI_rect.height=row_end-row_start;

IplImage*pImg8uROI=NULL;//感兴趣的图片

cvSetImageROI(pImg8u,ROI_rect);

pImg8uROI=cvCreateImage(cvSize(ROI_rect.width,ROI_rect.height),IPL_DEPTH_8U,1);

cvCopy(pImg8u,pImg8uROI);

cvResetImageROI(pImg8u);

intnWidth=409;//(409,90)分别为感兴趣图像的宽度与高度

intnHeight=90;

IplImage*pImgResize=NULL;//归一化的灰度图

pImgResize=cvCreateImage(cvSize(nWidth,nHeight),IPL_DEPTH_8U,1);

cvResize(pImg8uROI,pImgResize,CV_INTER_LINEAR);//线性插值

intnCharWidth=45;

intnSpace=12;

for(i=0;i<7;i++)//得到每个字符的双边界

{

switch(i){

case0:

case1:

col[i*2]=i*nCharWidth+i*nSpace;

col[i*2+1]=(i+1)*nCharWidth+i*nSpace;

break;

case2:

case3:

case4:

case5:

case6:

col[i*2]=i*nCharWidth+i*nSpace+22;

col[i*2+1]=(i+1)*nCharWidth+i*nSpace+22;

break;

}

}

for(i=0;i<14;i++)//画出每个字符的区域

{

cvLine(pImgResize,cvPoint(col[i],0),cvPoint(col[i],nHeight),cvScalar(255,0,0),1,8,0);

}

IplImage*pImgCharOne=NULL;

IplImage*pImgCharTwo=NULL;

IplImage*pImgCharThree=NULL;

IplImage*pImgCharFour=NULL;

IplImage*pImgCharFive=NULL;

IplImage*pImgCharSix=NULL;

IplImage*pImgCharSeven=NULL;

pImgCharOne=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1);

pImgCharTwo=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1);

pImgCharThree=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1);

pImgCharFour=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1);

pImgCharFive=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1);

pImgCharSix=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1);

pImgCharSeven=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1);

CvRectROI_rect1;

ROI_rect1.x=col[0];

ROI_rect1.y=0;

ROI_rect1.width=nCharWidth;

ROI_rect1.height=nHeight;

cvSetImageROI(pImgResize,ROI_rect1);

cvCopy(pImgResize,pImgCharOne,NULL);//获取第1个字符

cvResetImageROI(pImgResize);

ROI_rect1.x=col[2];

ROI_rect1.y=0;

ROI_rect1.width=nCharWidth;

ROI_r

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生 > 中医中药

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1