1、#include cv.hhighgui.hint main(int argc, char* argv) IplImage *src; if (argc = 2 &(src = cvLoadImage(argv1,1) != 0) /计算HSV(hue色度saturation饱和度value亮度)并分解成为不同的平面 IplImage *hsv = cvCreateImage(cvGetSize(src),8,3);cvCvtColor(src,hsv,CV_BGR2HSV);/可以更改为CV_BGR2GRAY,可以自己尝试一下 cvNamedWindow(src,CV_WINDOW_AUTO
2、SIZE); cvShowImage(,src);dst,hsv); cvWaitKey(0); return 0; (ii) 高斯滤波平滑处理函数CVSmooth()在数字图像处理中,由于受到成像方法的限制,图像中的边缘、细节特征等重要信息常湮没于噪声信号中,给图像的后继处理带来很大的影响。因此对含噪声图像进行适当的预处理是图像处理中的一个重要问题,对于改善图像质量具有重要的意义。图像去噪是图像预处理中一项应用比较广泛的技术,其作用是为了提高图像的信噪比,突出图像的期望区域各种方法的图像平滑void cvSmooth( const CvArr* src, CvArr* dst, int sm
3、oothtype=CV_GAUSSIAN,int param1=3, int param2=0, double param3=0 );其中:src输入图像. dst输出图像. smoothtype平滑方法:.(1)CV_BLUR_NO_SCALE (简单不带尺度变换的模糊) - 对每个象素领域 param1param2 求和。如果邻域大小是变化的,可以事先利用函数 cvIntegral 计算积分图像。(2)CV_BLUR (simple blur) - 对每个象素邻域 param1param2 求和并做尺度变换 1/(param1param2).(3)CV_GAUSSIAN (gaussian
4、 blur) - 对图像进行核大小为 param1param2 的高斯卷积(4)CV_MEDIAN (median blur) - 发现邻域 param1param1 的中值 (i.e. 邻域是方的).(5)CV_BILATERAL (双滤波) - 应用双向 3x3 滤波,彩色 sigma=param1,空间 sigma=param2. 关于双向滤波, param1:平滑操作的第一个参数.param2:平滑操作的第二个参数param2为零对应简单的尺度变换和高斯模糊。param3:对应高斯参数的 Gaussian sigma (标准差). 如果为零,这由下面的核尺寸计算。函数 cvSmooth
5、 可使用上面任何一种方法平滑图像。每一种方法都有自己的特点以及局限。(iii)用于对图像的边缘检测(采用canny算法)。1.Canny边缘检测基本原理 (1)图象边缘检测必须满足两个条件:一能有效地抑制噪声;二必须尽量精确确定边缘的位置。 (2)根据对信噪比与定位乘积进行测度,得到最优化逼近算子。这就是Canny边缘检测算子。 (3)类似与Marr(LoG)边缘检测方法,也属于先平滑后求导数的方法。2.void cvCanny( const CvArr* image,CvArr* edges,double threshold1,double threshold2, int aperture_
6、size=3 );其中threshold1:第一个阈,threshold2:第二个阈值,aperture_size Sobel:算子内核大小.函数 cvCanny 采用 Canny 算法发现输入图像的边缘而且在输出图像中标识这些边缘。threshold1和threshold2 当中的小阈值用来控制边缘连接,大的阈值用来控制强边缘的初始分割。3.在opencv中文论坛上我们可以找到关于Canny 算法的详细过程 #include cxcore.h int main( int argc, char* argv ) IplImage* pImg = NULL; /声明IplImage指针 IplIm
7、age* pCannyImg = NULL; char *filename; filename= F:练习VC6.0opencv1.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);, 1); /创建窗口 cvNamedWindow(canny,1); cvShowIm
8、age( , pImg ); /显示图像 cvShowImage( , pCannyImg ); /等待按键 cvDestroyWindow( ); /销毁窗口 /释放图像cvReleaseImage( &pImg ); cvReleaseImage( &pCannyImg ); return -1;图1 Canny 算法处理后(iv) cvSetImageROI()函数cvSetImageROI()函数基于给定的矩形设置感兴趣区域 ,也就是从图片中找到我们需要的部分。void cvSetImageROI( IplImage* image, CvRect rect );函数 cvSetImag
9、eROI 基于给定的矩形设置图像的 ROI(感兴趣区域) . 如果ROI是NULL 并且参数RECT的值不等于整个图像, ROI被分配. 不像 COI, 大多数的 OpenCV 函数支持 ROI并且处理它就像它是一个分离的图像 (例如, 所有的像素坐标从ROI的左上角或左下角(基于图像的结构)计算。下面用一段代码来说明cvSetImageROI函数:stdio.hint main() IplImage *img=cvLoadImage(F:练习VC6.0opencv1.jpg); IplImage *img1=cvLoadImage(练习VC6.0opencv2.jpg cvSetImageR
10、OI(img1,cvRect(0,0,256,256);/设置img1的ROI区域 cvResize(img, img1);/缩放img图像,并将数据拷贝到img1 cvResetImageROI(img1);/这句是必须的,在img1的ROI区域显示imgimg1,img1); cvDestroyAllWindows();图2 处理前 图3 处理后3、程序的运行与实现 本程序采用的是一种很简单的识别方法,即将分割出的字符与模板想比较,得到结果图像后检测图像中非零像素的个数,当个数最少时即判定为匹配图像。因为模板的大小是 22*14 的,所以需要将所得分割字符统一大小,之后再相比较,检测最小值
11、。具体实现方面还是让我痛苦了一段时间,如何用循环实现字符自动匹配和字符的显示比较的困难。后来我采用的方法是建立字符串数组存储模板图片的文件名,利用数组来自动匹配,显示方面我采用将汉字分成若干个 SWITCH 语句,利用数组中的数字表示汉字序数,不同的序数执行不同的分支程序。 图4 原图像 图5 分割结果三、实验感想 我的这套车牌识别系统是基于 opencv 建立的,在网上虽然有很多 matlab 的识别程序,但真正用 opencv 而非直接使用 VC 识别的系统很少,所以我采用的方法是在借鉴 matlab 程序的思路的基础上,自己搭建一个 VC 平台,其中的模块很多是在网上找的,但他们之间的连
12、接和搭配,以及一些方法的选择也加入了我自己的想法。通过这次的大作业,我对于图像处理课上讲授的内容有了更深的理解,对一些算法的应用有了更深的感受,比如开闭操作、投影直方图和最佳全局阈值等,而且在这个过程中,也熟悉了 opencv 和 VC 的编程方法,真的是收益良多。四、附录源代码#include cxcore.hhighgui.hiostreamusing namespace std;#pragma comment(lib,cv.lib)cxcore.libhighgui.lib#define T 27#define T1 2#define S(image,x,y) (uchar*)(imag
13、e-imageData + image-widthStep*(y)(x) /Svoid main() IplImage *pImg8u=NULL; /灰度图 IplImage *pImg8uSmooth=NULL; /高斯滤波后的图 IplImage *pImgCanny=NULL; /二值化的图 IplImage *pImgHist=NULL; /直方图 int hist_size=155; float range_0=0,256; float *ranges=range_0; int i,j,bin_w; float max_value,min_value; int min_dx,max_
14、dx; int row_start,row_end;/用来记录车牌开始,结束行 int col_start,col_end;/用来记录车牌开始,结束列 int count=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); cvC
15、vtColor(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; int row120; int col340; int k; k=0; bool flag=false; for(j=0;jheight;j+) /找到上行开始 count=0; for(i=0;iT) rowk=j; k+
16、; break; for(i=0;k;i+) /从上边开始,3行连续时认为是起始行 if(rowi=rowi+1-1)&(rowi+1=rowi+2-1) row_start=rowi; break; coutthe start row:row_startwidth,row_start),cvScalar(255,0,0),1,8,0); for(i=k-1;irow_start;i-) /从下边开始,3行连续时认为是起始行 if(rowi=rowi-1+1)&(rowi-1=rowi-2+1) row_end=rowi;the end row:row_endwidth,row_end),cv
17、Scalar(255,0,0),1,8,0); flag=false; for(i=10;width;i+) /找到左列开始 for(j=row_start;row_end;j+) if(S(pImgCanny,i,j)=255)T1) col_start=i; flag=true; if(flag) break;the start col:col_startwidth-10;col_start;i-) /找到右列开始 col_end=i;the end col:col_end cvLine(pImg8u,cvPoint(col_end,row_start),cvPoint(col_end,r
18、ow_end),cvScalar(255,0,0),1,8,0); CvRect ROI_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.heig
19、ht),IPL_DEPTH_8U,1); cvCopy(pImg8u,pImg8uROI); cvResetImageROI(pImg8u); int nWidth=409;/(409,90)分别为感兴趣图像的宽度与高度 int nHeight=90; IplImage *pImgResize=NULL; /归一化的灰度图 pImgResize=cvCreateImage(cvSize(nWidth,nHeight),IPL_DEPTH_8U,1); cvResize(pImg8uROI,pImgResize,CV_INTER_LINEAR); /线性插值 int nCharWidth=45;
20、 int nSpace=12;7;i+) /得到每个字符的双边界 switch(i) case 0: case 1: coli*2=i*nCharWidth+i*nSpace; coli*2+1=(i+1)*nCharWidth+i*nSpace; case 2: case 3: case 4: case 5: case 6: coli*2=i*nCharWidth+i*nSpace+22; coli*2+1=(i+1)*nCharWidth+i*nSpace+22;14;i+) /画出每个字符的区域 cvLine(pImgResize,cvPoint(coli,0),cvPoint(coli
21、,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
22、_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); pImgChar
23、Six=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1); pImgCharSeven=cvCreateImage(cvSize(nCharWidth,nHeight),IPL_DEPTH_8U,1); CvRect ROI_rect1; ROI_rect1.x=col0; 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=col2; ROI_r
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1