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

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 书签


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值