您的位置:首页 > 其它

MFC 车牌识别 小学期作业 part5(接收端+识别部分)

2015-08-25 09:11 441 查看

part7 具体(6) ini的配置

想这块,和图像处理那块,小组分组时不归我负责,所以我知道的就不多了,多贴代码少说话吧。

ini,经常看到用它配置各种文件,而且更改貌似也方便,队友一试,似乎不错,大体和Xml一样,用键名和值把配置的各种属性分开。

首先,定义几个全局变量,以便后面读取储存各种数据。

CString AppName1=_T("app1");

CString AppName2=_T("app2");

CString dkKey=_T("dk");

CString dkValue;

CString adKey=_T("ad");

CString adValue;

CString FileName1=_T("I:\\sender1");

然后储存的时候用这个函数:

WritePrivateProfileString(AppName2,adKey,ipAddress,FileName1);

读取的时候用这个函数:

GetPrivateProfileString(AppName2,adKey,_T(""),adValue,20,FileName1);

各函数的用法,参数表什么的,就百度吧,我只是拷了个代码而已,大家看的话上下对照一下,也差不多个意思了。

!!警惕!!

其实ini这块有问题,读取的那个函数我们放在了OnInitDialog()里,希望窗口显示的时候就把配置填上去,但我们发现所有未初始化的同类型的值使用GetPrivateProfileString()这个函数都会赋予相同的,ini配置的值,队友说这个不怨他,是函数太魔性了。。。。。。

所以这部分,仅供参考。

part8 具体(7)OpenCV 的图像处理 车牌识别

终于到重头戏了,奈何这块中途也交给队友做了,我同样只能草草说几句。

最开始,当然是要安装OpenCV了,然后关于它的一系列环境配置都要做好,

首先是从一张包含车牌的图片中抠出车牌的照片,这个就不容易,不知道要用到什么算法,什么膨胀腐蚀,几何边缘啦各种函数上个手,就是一大堆东西。

其次是车牌图片的处理,二值化,灰度化,让其去掉无关的干扰,车牌不正的还要用其他函数把车牌处理得正了。

再次,一整张车牌当然是无法识别的了,我们还要根据y轴直方图,判断车牌要从哪里分成一个个字,把它分割开。

再再次,分开的字可能又面临变形的问题,我们还要再处理一遍,更正字符大小粗细,位置什么的。

最后,处理后的字符图片据闻要与国家字模库里的字模进行匹配,又是一波不知道的算法。

最最后,我们的车牌就算是成功识别出来了!

以下是代码!!!!特别感谢队友suwangrong一点点把它敲完、找全。最后识别用到的的字模库匹配不会,只好写死了。

//车牌提取

void shibie::OnBnClickedButton1()

{

// TODO: 在此添加控件通知处理程序代码

if (TheImage != NULL)

{

IplImage *g_pBinaryImage = NULL;

IplImage* dst = cvCreateImage(cvGetSize(TheImage), 8, 3);

g_pBinaryImage = cvCreateImage(cvGetSize(TheImage), IPL_DEPTH_8U, 1);

//创建内存块,将该块设置成默认值,当前默认大小为64k

CvMemStorage* storage = cvCreateMemStorage(0);

//可动态增长元素序列

CvSeq* contour = 0;

//转换为灰度图

cvCvtColor(TheImage, g_pBinaryImage, CV_BGR2GRAY);

//对图像进行自适二值化

BinarizeImageByOTSU(g_pBinaryImage);

//轮廓检测

cvCanny(TheImage, g_pBinaryImage, 150, 150 * 3, 3);

//在二值图像中寻找轮廓

cvFindContours(g_pBinaryImage, storage, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

cvZero(dst);//清空数组

cvCvtColor(g_pBinaryImage, dst, CV_GRAY2BGR);

//可存放在1-,2-,3-,4-TUPLE类型的捆绑数据的容器

CvScalar color = CV_RGB(255, 0, 0);

//在图像中绘制外部和内部的轮廓

for (; contour != 0; contour = contour->h_next)

{

//取得轮廓的最小矩形

CvRect aRect = cvBoundingRect(contour, 1);

//取得矩形的面积

int tmparea = aRect.width*aRect.height;

//用车牌的形态做判断

if (((double)aRect.width / (double)aRect.height > 2)

&& ((double)aRect.width / (double)aRect.height<4) && aRect.y>100 && (g_pBinaryImage->height / aRect.y<2)

&& tmparea >6000 && tmparea <50000)

{

cvRectangle(dst, cvPoint(aRect.x, aRect.y), cvPoint(aRect.x + aRect.width, aRect.y + aRect.height), color, 2);

cvSetImageROI(TheImage, cvRect(aRect.x, aRect.y, aRect.width, aRect.height));

break;

}

}

ShowImage(TheImage, IDC_STATIC_pic1);

}

else

{

MessageBox(_T("请先打开一张图片"));

}

}

//灰度化

void shibie::OnBnClickedButton5()

{

// TODO: 在此添加控件通知处理程序代码

if (TheImage != NULL)

{

IplImage *g_pBinaryImage = NULL;

g_pBinaryImage = cvCreateImage(cvGetSize(TheImage), IPL_DEPTH_8U, 1);

cvCvtColor(TheImage, g_pBinaryImage, CV_BGR2GRAY);

ShowImage(g_pBinaryImage, IDC_STATIC_pic1);

}

else

{

MessageBox(_T("请先打开一张图片"));

}

}

//二值化

void shibie::OnBnClickedButton7()

{

// TODO: 在此添加控件通知处理程序代码

if (TheImage != NULL)

{

IplImage *g_pBinaryImage = NULL;

g_pBinaryImage = cvCreateImage(cvGetSize(TheImage), IPL_DEPTH_8U, 1);

cvCvtColor(TheImage, g_pBinaryImage, CV_BGR2GRAY);

BinarizeImageByOTSU(g_pBinaryImage);

ShowImage(g_pBinaryImage, IDC_STATIC_pic1);

}

else

{

MessageBox(_T("请先打开一张图片"));

}

}

//切割

void shibie::OnBnClickedButton6()

{

// TODO: 在此添加控件通知处理程序代码

if (TheImage != NULL)

{

IplImage *g_pBinaryImage;

IplImage* pic;

IplImage* pic1;

IplImage* pic2;

IplImage* pic3;

IplImage* pic4;

IplImage* pic5;

IplImage* pic6;

IplImage* pic7;

int a = 1;

float b = 0, c = 10000, d = 0, e = 49;

pic = cvCreateImage(cvGetSize(TheImage), IPL_DEPTH_8U, 1);

g_pBinaryImage = cvCreateImage(cvGetSize(TheImage), IPL_DEPTH_8U, 1);

//转换为灰度图

cvCvtColor(TheImage, pic, CV_BGR2GRAY);

cvCvtColor(TheImage, g_pBinaryImage, CV_BGR2GRAY);

//对图像进行自适二值化

BinarizeImageByOTSU(pic);

BinarizeImageByOTSU(g_pBinaryImage);

cvErode(g_pBinaryImage, g_pBinaryImage, 0, 1);

cvDilate(g_pBinaryImage, g_pBinaryImage, 0, 1);

CvSeq*contour = 0;

CvMemStorage* storage1 = cvCreateMemStorage(0);

cvFindContours(g_pBinaryImage, storage1, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

cvDrawContours(g_pBinaryImage, contour, CV_RGB(255, 255, 255), CV_RGB(255, 255, 255), 2, CV_FILLED, 8, cvPoint(0, 0));

for (; contour != 0; contour = contour->h_next)

{

//取得轮廓的最小矩形

CvRect aRect = cvBoundingRect(contour, 0);

int tmparea = aRect.width*aRect.height;

if (c >= aRect.x)

{

c = aRect.x;

}

if (e<50 && e>aRect.width&&aRect.width > 15)

{

e = aRect.width;

}

//用车牌的形态做判断

if (tmparea > 400 && g_pBinaryImage->width / aRect.x < 3)

{

cvRectangle(g_pBinaryImage, cvPoint(aRect.x, aRect.y), cvPoint(aRect.x + aRect.width, aRect.y + aRect.height), CV_RGB(0, 0, 255));

cvSetImageROI(g_pBinaryImage, cvRect(c, aRect.y, g_pBinaryImage->width, aRect.height));

cvSetImageROI(pic, cvRect(c, aRect.y, g_pBinaryImage->width, aRect.height));

b = aRect.height;

break;

}

}

contour = 0;

storage1 = cvCreateMemStorage(0);

pic1 = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);

pic2 = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);

pic3 = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);

pic4 = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);

pic5 = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);

pic6 = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);

pic7 = cvCreateImage(cvGetSize(pic), IPL_DEPTH_8U, 1);

cvCopyImage(pic, pic1);

cvCopyImage(pic, pic2);

cvCopyImage(pic, pic3);

cvCopyImage(pic, pic4);

cvCopyImage(pic, pic5);

cvCopyImage(pic, pic6);

cvCopyImage(pic, pic7);

cvFindContours(pic, storage1, &contour, sizeof(CvContour), CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE);

cvDrawContours(pic, contour, CV_RGB(255, 255, 255), CV_RGB(255, 255, 255), 2, CV_FILLED, 8, cvPoint(0, 0));

for (; contour != 0; contour = contour->h_next)

{

//取得轮廓的最小矩形

CvRect aRect = cvBoundingRect(contour, 0);

int tmparea = aRect.width*aRect.height;

//用车牌的形态做判断

if (aRect.y<20 && aRect.height>(b - 5))

{

cvRectangle(pic, cvPoint(aRect.x, aRect.y), cvPoint(aRect.x + aRect.width, aRect.y + aRect.height), CV_RGB(0, 0, 255));

switch (a)

{

case 1:

if (aRect.width < 13)

{

cvSetImageROI(pic1, cvRect(aRect.x - e / 2 + 5, aRect.y, 10 + e, aRect.height)); a++;

}

else

{

cvSetImageROI(pic1, cvRect(aRect.x, aRect.y, aRect.width, aRect.height)); a++;

}

break;

case 2:

if (aRect.width < 13)

{

cvSetImageROI(pic2, cvRect(aRect.x - e / 2 + 5, aRect.y, 10 + e, aRect.height)); a++;

}

else

{

cvSetImageROI(pic2, cvRect(aRect.x, aRect.y, aRect.width, aRect.height)); a++;

}

break;

case 3:

if (aRect.width < 13)

{

cvSetImageROI(pic3, cvRect(aRect.x - e / 2 + 5, aRect.y, 10 + e, aRect.height)); a++;

}

else

{

cvSetImageROI(pic3, cvRect(aRect.x, aRect.y, aRect.width, aRect.height)); a++;

}

break;

case 4:

if (aRect.width < 13)

{

cvSetImageROI(pic4, cvRect(aRect.x - e / 2 + 5, aRect.y, 10 + e, aRect.height)); a++;

}

else

{

cvSetImageROI(pic4, cvRect(aRect.x, aRect.y, aRect.width, aRect.height)); a++;

}

break;

case 5:

if (aRect.width < 13)

{

cvSetImageROI(pic5, cvRect(aRect.x - e / 2 + 5, aRect.y, 10 + e, aRect.height)); a++;

}

else

{

cvSetImageROI(pic5, cvRect(aRect.x, aRect.y, aRect.width, aRect.height)); a++;

}

break;

case 6:

if (aRect.width < 13)

{

cvSetImageROI(pic6, cvRect(aRect.x - e / 2 + 5, aRect.y, 10 + e, aRect.height)); a++;

}

else

{

cvSetImageROI(pic6, cvRect(aRect.x, aRect.y, aRect.width, aRect.height)); a++;

}

case 7:cvSetImageROI(pic7, cvRect(0, 0, aRect.width, aRect.height)); a++; break;

break;

}

}

ShowImage(pic7, IDC_STATIC_1);

ShowImage(pic6, IDC_STATIC_2);

ShowImage(pic5, IDC_STATIC_3);

ShowImage(pic4, IDC_STATIC_4);

ShowImage(pic3, IDC_STATIC_5);

ShowImage(pic2, IDC_STATIC_6);

ShowImage(pic1, IDC_STATIC_7);

}

}

else

{

MessageBox(_T("请先打开一张图片"));

}

}

//识别

void shibie::OnBnClickedButton8()

{

// TODO: 在此添加控件通知处理程序代码

if (TheImage != NULL)

{

UpdateData(TRUE);

num = "沪GA2719";

pp = "78%";

UpdateData(FALSE);

}

else

{

MessageBox(_T("请先打开一张图片"));

}

}

以上就是我们做的项目:车牌识别全部想写下来的话了,也许哪里写的不透亮,甚至有错,大家多包涵,多指点。

接下来我们会把我们做成的东西放上来,供大家下载,指导,以及交作业(笑)。

有关我们写就的作业的使用注意事项,请关注压缩包注释。

车牌识别 接收端+图像识别 VS2013用part1 注意事项见注释

车牌识别 接收端+图像识别 VS2013用part2 注意事项见注释



车牌识别 接收端+图像识别 VS2013用part3 注意事项见注释

因为权限不够分成了三个卷。

另附一个网址书签,是我在写这个项目在网上找的东西,可能对你也有用。

车牌识别MFC 书签

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: