数字图像处理纸牌识别课程设计.docx
- 文档编号:3357515
- 上传时间:2022-11-22
- 格式:DOCX
- 页数:23
- 大小:402.02KB
数字图像处理纸牌识别课程设计.docx
《数字图像处理纸牌识别课程设计.docx》由会员分享,可在线阅读,更多相关《数字图像处理纸牌识别课程设计.docx(23页珍藏版)》请在冰豆网上搜索。
数字图像处理纸牌识别课程设计
课程设计
课程名称___数字图像处理______
题目名称______纸牌识别________
学生学院______________
专业班级_____
学号__________
学生____________
指导教师______江中_______
一、设计题目
(1)、在VC++环境下实现打开、显示一幅纸牌图(设计资料中有纸牌图)。
(2)、将提供的几幅图片中的纸牌进行分类和识别,要求:
a、判断出是那种类型(共四类:
红桃,梅花、黑桃、方片);b、检测出点数(1、2…10);
c:
将上述检测的结果输出。
二、设计目的
通过设计,以C++为工具,实现数字图像处理。
会用数字图像处理知识对图像进行增强,如全局阈值,对图像进行旋转,边缘检测,对图像进行平移,截取图像特征并会用简单的模板匹配方法匹配判断图片容。
学会使用FMC。
三设计容。
(1)基本思想为:
对图片进行中值滤波去除噪声,对图像进行全局阈值处理,用锐化模板检测,纸牌边缘,左方开始测量每个点当碰到纸牌边缘时灰度为255,此时记下像素距离,从而对得到纸牌水平位置,同理得图片竖直距离,对图片进行平移,并截取左上角的特征,对特征进行基本处理,如二值化。
逐一加载模板,进行匹配,匹配原理为特征于模板相同像素的个数,如个数很高则匹配成功,从而识别纸牌。
(2)在VC下建立FMC平台。
使用DIB类处理bmp格式文件。
工程名为pokeridentyfy。
CPokeridentyfyview.中包的DIB类有
CDIBm_dib;
CDIBmid_boader;
CDIBboaer_crect
CDIBcutmask;
CDIBforcut;
CDIBmasknumber;
CDIBmasktype;
用于存放,处理和显示图片。
制作菜单每个对于图像处理功能,一个按键调用一个处理函数,也可一个按键调用多个处理函数。
菜单及其功能如下图
打开图像的代码为功能为大开所处理图像:
voidCPokeridentifyView:
:
OnOpenimage()
{
//TODO:
Addyourcommandhandlercodehere
staticcharszFilter[]="BMP文件(*.bmp)|*.bmp||";//定义过滤文件的类型
CFileDialogdlg(TRUE,"bmp",NULL,
OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT,szFilter);//定义文件对话框对象
CStringfilename;
intret=dlg.DoModal();//运行打开文件对方框
if(ret==IDOK)
{
filename=dlg.GetFileName();//获取所选择图像的路径
m_dib.LoadFromFile(filename);//加载图像
if(!
m_dib.m_bLoaded)//判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}
mid_boader.LoadFromFile(filename);//加载图像
if(!
mid_boader.m_bLoaded)//判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}
boaer_crect.LoadFromFile(filename);//加载图像
if(!
boaer_crect.m_bLoaded)//判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}
cutmask.LoadFromFile("TTcut.bmp");//加载图像
if(!
cutmask.m_bLoaded)//判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}
forcut.LoadFromFile(filename);//加载图像
if(!
forcut.m_bLoaded)//判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}
masknumber.LoadFromFile("1.bmp");//加载图像
if(!
masknumber.m_bLoaded)//判断是否加载图像成功masktype
{
AfxMessageBox("图像打不开");
return;
}
masktype.LoadFromFile("111.bmp");//加载图像
if(!
masktype.m_bLoaded)//判断是否加载图像成功
{
AfxMessageBox("图像打不开");
return;
}}
打开一图片后为:
中值滤波的代码为:
voidCPokeridentifyView:
:
OnMidiamaskImage()
{
//TODO:
Addyourcommandhandlercodehere
if(!
m_dib.m_bLoaded)
{
AfxMessageBox("图像还打开,请先打开图像!
");
return;
}
//获取图像宽和高
intnw=m_dib.GetDIBWidth();
intnh=m_dib.GetDIBHeight();
inti,j;
BYTE*ptemp=(BYTE*)newBYTE[nw*nh];
memset(ptemp,0,nw*nh);
doublemid[9];
for(j=3/2;j for(i=3/2;i {doubleresult=0; intk,h; for(k=0;k<3;k++)//k行h列 for(h=0;h<3;h++) { mid[k*3+h]=m_dib.m_pdata[(j-k)*nw+i-h]; intii,jj,tempmid; doublesweep; for(ii=0;ii<8;ii++) { tempmid=ii; for(jj=ii;jj<=8;jj++) { if(mid[jj] } sweep=mid[ii]; mid[ii]=mid[tempmid]; mid[tempmid]=sweep; } result=mid[4]; if(result>255)result=255; if(result<0)result=0; } ptemp[j*nw+i]=result; } memcpy(m_dib.m_pdata,ptemp,nw*nh); m_dib.UpdateData(); memcpy(mid_boader.m_pdata,ptemp,nw*nh); mid_boader.UpdateDatadup(); delete[]ptemp; //刷新屏幕 Invalidate();} 调用后结果为: 全局门限的代码中先计算图像的直方图,以一个点(一般去中间值)把直方图分成两份,分别计算两部分的灰度均值,m1与m2,由(m1+m2)/2得到新的阈值与灰度分割点,知道新阈值与旧的阈值相差不到。 用新的阈值进行二值化。 代码为: voidCPokeridentifyView: : OnAllthrImage() { //TODO: Addyourcommandhandlercodehere if(! m_dib.m_bLoaded) { AfxMessageBox("图像还打开,请先打开图像! "); return; }//获取图像宽和高 intnw=m_dib.GetDIBWidth(); intnh=m_dib.GetDIBHeight(); inti,j; doublep[256];//存放直方图 intthrold=200,thrnew=210,m1=0,m2=0;//匹配时用180 for(i=0;i<256;i++) p[i]=0; for(j=0;j for(i=0;i { p[m_dib.m_pdata[j*nw+i]]++;//统计各像素总数 } for(i=0;i<256;i++) { p[i]=p[i]*1.0/(nw*nh);//直方图归一化 } do { throld=thrnew; for(i=0;i<=throld;i++) { m1=m1+p[i]*i; } for(i=throld+1;i<256;i++) { m2=m2+p[i]*i; } thrnew=(m1+m2)/2; } while(abs(thrnew=throld)<5); for(j=0;j for(i=0;i { //对图像的第j行、第i列的象素的灰度信息进行判断,修改 if(m_dib.m_pdata[j*nw+i]>thrnew) m_dib.m_pdata[j*nw+i]=255; else m_dib.m_pdata[j*nw+i]=0; } //将修改的m_pdata的数据赋值给m_pDIBData,以显示修改的结果 m_dib.UpdateData(); memcpy(mid_boader.m_pdata,m_dib.m_pdata,nw*nh); mid_boader.UpdateData();//刷新屏幕 Invalidate(); }结果为: 对图像进行边缘检测的代码为: voidCPokeridentifyView: : OnFindborderImage() { //TODO: Addyourcommandhandlercodehere if(! m_dib.m_bLoaded) { AfxMessageBox("图像还打开,请先打开图像! "); return; } //获取图像宽和高 intnw=m_dib.GetDIBWidth(); intnh=m_dib.GetDIBHeight(); inti,j; BYTE*ptemp=(BYTE*)newBYTE[nw*nh]; memset(ptemp,0,nw*nh); doublemask[3][3]={-1,-1,-1,-1,8,-1,-1,-1,-1}; for(j=3/2;j for(i=3/2;i { doubleresult=0; intk,h; for(k=0;k<3;k++) for(h=0;h<3;h++) result+=mask[k][h]*m_dib.m_pdata[(j-k)*nw+i-h]; if(result>255)result=255; if(result<0)result=0; ptemp[j*nw+i]=result; } memcpy(m_dib.m_pdata,ptemp,nw*nh); m_dib.UpdateData(); memcpy(boaer_crect.m_pdata,ptemp,nw*nh); boaer_crect.UpdateData(); delete[]ptemp;//刷新屏幕 Invalidate(); } 结果为: 对图片进行测量并平移校正的代码为: voidCPokeridentifyView: : OnAutomoveImage() { //TODO: Addyourcommandhandlercodehere if(! m_dib.m_bLoaded) { AfxMessageBox("图像还打开,请先打开图像! "); return; }//获取图像宽和高 intnw=m_dib.GetDIBWidth(); intnh=m_dib.GetDIBHeight(); inti,j; BYTE*ptemp=(BYTE*)newBYTE[nw*nh]; memset(ptemp,0,nw*nh); intmovedownj,moverighti;//移动像素距离 inth,k; inttemp; intnwmove[7],nhmove[7]; intnwmlength[7]={600,600,600,600,600,600,600},nhmlength[7]={600,600,600,600,600,600,600}; intbnw,bnh; for(i=0;i<7;i++) {nhmove[i]=nh*(i+1)/8; nwmove[i]=nw*(i+1)/8; } for(k=0;k<7;k++)//寻找水平距离 {for(i=0;i {if(m_dib.m_pdata[nhmove[k]*nw+i]! =0) {nhmlength[k]=i; break; } } for(k=0;k<7;k++)//寻找竖直距离 {for(j=nh;j>0;j--) {if(m_dib.m_pdata[j*nw+nwmove[k]]! =0) {nwmlength[k]=nh-j; break; } } } for(i=0;i<6;i++)//水平测量量nhmlegnth的排列 {k=i; for(j=i;j<7;j++) {if(nhmlength[j] } temp=nhmlength[k]; nhmlength[k]=nhmlength[i]; nhmlength[i]=temp; } bnw=nhmlength[0]; for(i=0;i<6;i++)//竖直测量量nwmlength的排列 {k=i; for(j=i;j<7;j++) {if(nwmlength[j] } temp=nwmlength[k]; nwmlength[k]=nwmlength[i]; nwmlength[i]=temp; } bnh=nwmlength[0]; movedownj=-bnh; moverighti=-bnw; for(j=0;j for(i=0;i {h=j-movedownj; k=i+moverighti; if(h>0&&h ptemp[h*nw+k]=m_dib.m_pdata[j*nw+i]; } memcpy(m_dib.m_pdata,ptemp,nw*nh); m_dib.UpdateData(); memcpy(boaer_crect.m_pdata,ptemp,nw*nh); boaer_crect.UpdateDatadup();//刷新屏幕 Invalidate(); /***********************************/ for(j=0;j for(i=0;i {h=j-movedownj; k=i+moverighti; if(h>0&&h ptemp[h*nw+k]=forcut.m_pdata[j*nw+i]; } memcpy(forcut.m_pdata,ptemp,nw*nh); forcut.UpdateData(); delete[]ptemp; } voidCPokeridentifyView: : OnRecreactImage() {//TODO: Addyourcommandhandlercodehere if(! m_dib.m_bLoaded) {AfxMessageBox("图像还打开,请先打开图像! "); return; }//获取图像宽和高 intnw=m_dib.GetDIBWidth(); intnh=m_dib.GetDIBHeight(); inti,j; inth,k; BYTE*ptemp=(BYTE*)newBYTE[nw*nh]; memset(ptemp,0,nw*nh); intmovedownj,moverighti;//移动像素距离 intbnh; intmoveup=500; for(j=0;j { if(m_dib.m_pdata[j*nw+50]==255) {moveup=j; break; } } bnh=moveup; movedownj=bnh; moverighti=0; for(j=0;j for(i=0;i { h=j+movedownj; k=i-moverighti; if(h>0&&h ptemp[h*nw+k]=m_dib.m_pdata[j*nw+i]; } memcpy(m_dib.m_pdata,ptemp,nw*nh); m_dib.UpdateData(); //刷新屏幕 delete[]ptemp; Invalidate(); } 平移结果为: 截取特权的代码为: voidCPokeridentifyView: : OnCrectGetfeature() { //TODO: Addyourcommandhandlercodehere if(! cutmask.m_bLoaded) {AfxMessageBox("图像还打开,请先打开图像! "); return; }//获取图像宽和高 intnw=m_dib.GetDIBWidth(); intnh=m_dib.GetDIBHeight(); inti,j; BYTE*ptemp=(BYTE*)newBYTE[nw*nh]; memset(ptemp,0,nw*nh); intnw1=cutmask.GetDIBWidth(); intnh1=cutmask.GetDIBHeight(); for(j=nh-nh1;j {for(i=0;i {cutmask.m_pdata[(j-(nh-nh1))*nw1+i]=forcut.m_pdata[j*nw+i]; } } cutmask.UpdateDatadup(); Invalidate(); } 结果为: 对特征进行处理并加载模板,进行匹配,并显示匹配结果的代码为: voidCPokeridentifyView: : OnFeatureRecognize() { //TODO: Addyourcommandhandlercodehere if(! cutmask.m_bLoaded) {AfxMessageBox("图像还打开,请先打开图像! "); return; }//获取图像宽和高 intnw=cutmask.GetDIBWidth(); intnh=cutmask.GetDIBHeight(); inti,j; intk,h,t; BYTE*ptemp=(BYTE*)newBYTE[nw*nh]; /**************************************************************************************/ //特征增强 doublep[256]; intthrold=200,thrnew=180,m1=0,m2=0;//匹配时用180 for(i=0;i<256;i++) p[i]=0; for(j=0;j for(i=0;i {p[cutmask.m_pdata[j*nw+i]]++;//统计各像素总数 } for(i=0;i<256;i++) {p[i]=p[i]*1.0/(nw*nh);//直方图归一化 } do {throld=thrnew; for(i=0;i<=throld;i++) {m1=m1+p[i]*i; } for(i=throld+1;i<256;i++) {m2=m2+p[i]*i; } thrnew=(m1+m2)/2; } while(abs(thrnew=throld)<5); for(j=0;j for(i=0;i {//对图像的第j行、第i列的象素的灰度信息进行判断,修改 if(cutmask.m_pdata[j*nw+i]>thrnew) ptemp[j*nw+i]=255; else ptemp[j*nw+i]=0; } memcpy(cutmask.m_pdata,ptemp,nw*nh); cutmask.UpdateData(); Invalidate(); //识别 intcardnumber; floatnuberthr=0.9; floattypethr=0.92; CStringfilename; /*****************************************************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 数字图像 处理 纸牌 识别 课程设计