机器视觉课程设计Word文档下载推荐.docx
《机器视觉课程设计Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《机器视觉课程设计Word文档下载推荐.docx(13页珍藏版)》请在冰豆网上搜索。
f_MakeCircle(doublee_dThreshold)
{
if(NULL==m_pIplImageSource)
{return0;
}
//定义变量存图像的宽,高,行像素
intq_iWidth=m_pIplImageSource->
width;
intq_iHeight=m_pIplImageSource->
height;
intq_iWidthStep=m_pIplImageSource->
widthStep;
uchar*q_pchDataImage=(uchar*)m_pIplImageSource->
imageData;
CvPointM_Point[4]={};
//存放检索出的四个点循环检索
//01纵扫
for(intCycle_Y=1;
Cycle_Y<
q_iHeight;
Cycle_Y++)
{
if(e_dThreshold>
q_pchDataImage[q_iWidth/2+q_iWidthStep*(Cycle_Y-1)])
{
M_Point[0].x=q_iWidth/2;
M_Point[0].y=Cycle_Y;
}
}
for(intCycle_Y=q_iHeight;
Cycle_Y>
1;
Cycle_Y--)
M_Point[1].x=q_iWidth/2;
M_Point[1].y=Cycle_Y;
for(intCycle_X=1;
Cycle_X<
q_iWidth;
Cycle_X++)
q_pchDataImage[Cycle_X+q_iWidthStep*(q_iHeight/2-1)])
M_Point[2].x=Cycle_X;
M_Point[2].y=q_iHeight/2;
for(intCycle_X=q_iWidth;
Cycle_X>
Cycle_X--)
M_Point[3].x=Cycle_X;
M_Point[3].y=q_iHeight/2;
for(inti=0;
i<
4;
i++)//画边界圆
{cvCircle(m_pIplImageSource,M_Point[i],8,cvScalarAll(127),2);
intRidius=0,clear=0;
intcircle_y=abs(M_Point[1].y+M_Point[0].y)/2;
intcircle_x=abs(M_Point[3].x+M_Point[2].x)/2;
floatc=0,j=0;
i++)
{
j=(M_Point[i].x-circle_x)*(M_Point[i].x-circle_x)+(M_Point[i].y-circle_y)*(M_Point[i].y-circle_y);
c=c+sqrt(j);
}
Ridius=c/4;
//在窗口中显示长和高
charch1[10],ch2[10];
itoa(Ridius,ch1,10);
itoa(clear,ch2,10);
SetDlgItemText(IDC_LONG,ch1);
SetDlgItemText(IDC_SHORT,ch2);
CWnd*e_pCWndPicture=this->
GetDlgItem(ID_PICTURE_DISPLAY);
f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);
cvSaveImage(_T("
.//Result_Image.jpg"
),m_pIplImageSource);
return0;
2.2检测与计算矩形长和宽的程序
思路:
这个程序主要包括:
打开摄像头---保存图片(拍照)---加载刚刚保存的图片---找出点并计算长和高四个按钮,每一个按钮包含下面的一段代码,拍摄的图片保存为CurrentImage.jpg,这里事先保存了一张同名的图片,所以可以直接点击LoadImage读取。
2.2.1打开摄像头程序
voidc_DialogTeclarn:
OnBnClickedButtonOpenCamera()
CvCapture*q_pCvCapture=cvCreateCameraCapture(0);
if(NULL==q_pCvCapture)
return;
IplImage*q_pIplImageCapture=cvQueryFrame(q_pCvCapture);
if(NULL==q_pIplImageCapture)
if(NULL!
=m_pIplImageSource)
cvReleaseImage(&
m_pIplImageSource);
m_pIplImageSource=NULL;
m_pIplImageSource=cvCloneImage(q_pIplImageCapture);
cvReleaseCapture(&
q_pCvCapture);
注:
绿色的为检测是否成功打开摄像头,蓝色的是读取摄像头拍摄的图片到内存,后面的语句是让图片在mfc窗口显示出来。
2.2.2保存拍摄的照片程序
OnBnClickedButtonSaveImage()
//TODO:
在此添加控件通知处理程序代码
.//CurrentImage.jpg"
2.2.3读取拍摄到的图片(读取文名字CurrentImage.jpg的图片)
OnBnClickedButtonLoadImage()
cvReleaseImage(&
m_pIplImageSource=NULL;
m_pIplImageSource=cvLoadImage(_T("
),0);
2.2.4检测边上的点和计算长和高的函数
思路是:
第一步找到边上的点,设定一个变量e_dThreshold值为127,通过循环让它与每一个像素的像素值进行比较。
如果检测到一个点的像素值比127小,则这个点可能就是需要的点(黑色=0,白色=255)如果每个像素都要比较运算太多,所以上边两个
点的检测是沿着图片长的的2/5分处和3/5分处向下检测,下边的点是沿着1/2处向上检测。
第二步是用找到6个点的坐标算出三角形的面积,然后除以底边边长得到高。
求三角形的面积用的是行列式的值等于三角形面积的2倍
f_MakeRectangleWidth(doublee_dThreshold)
//定义一些点和变量
intq_iXLeftTop=2*q_iWidth/5;
intq_iXRightTop=3*q_iWidth/5;
intq_iXBottom=q_iWidth/2;
intq_iYLeftTop=2*q_iHeight/5;
intq_iYLeftBottom=3*q_iHeight/5;
intq_iYRightMid=q_iHeight/2;
CvPointq_CvPointLeftTop,q_CvPointRightTop,q_CvPointBottom;
CvPointq_CvPointLeft_Top,q_CvPointRight_Mid,q_CvLeft_Bottom;
//求上下两边上的点,3个循环
for(intq_iCycleHeight=0;
q_iCycleHeight<
q_iCycleHeight++)
if(e_dThreshold>
q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXLeftTop])
q_CvPointLeftTop.x=q_iXLeftTop;
q_CvPointLeftTop.y=q_iCycleHeight;
break;
q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXRightTop])
q_CvPointRightTop.x=q_iXRightTop;
q_CvPointRightTop.y=q_iCycleHeight;
for(intq_iCycleHeight=q_iHeight-1;
q_iCycleHeight>
=0;
q_iCycleHeight--)
q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXBottom])
q_CvPointBottom.x=q_iXBottom;
q_CvPointBottom.y=q_iCycleHeight;
//求左右两边上的点,3个循环
for(intq_iCycleWidth=0;
q_iCycleWidth<
q_iCycleWidth++)
q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftTop-1)])
q_CvPointLeft_Top.x=q_iCycleWidth;
q_CvPointLeft_Top.y=q_iYLeftTop;
q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftBottom-1)])
q_CvLeft_Bottom.x=q_iCycleWidth;
q_CvLeft_Bottom.y=q_iYLeftBottom;
for(intq_iCycleWidth=q_iHeight-1;
q_iCycleWidth>
q_iCycleWidth--)
q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYRightMid-1)])
q_CvPointRight_Mid.x=q_iCycleWidth;
q_CvPointRight_Mid.y=q_iYRightMid;
//在检测到的点上画圆,只是为了更好看到找点的情况
cvCircle(m_pIplImageSource,q_CvPointLeftTop,5,cvScalarAll(127),2);
cvCircle(m_pIplImageSource,q_CvPointRightTop,5,cvScalarAll(127),2);
cvCircle(m_pIplImageSource,q_CvPointBottom,5,cvScalarAll(127),2);
cvCircle(m_pIplImageSource,q_CvPointLeft_Top,5,cvScalarAll(127),2);
cvCircle(m_pIplImageSource,q_CvLeft_Bottom,5,cvScalarAll(127),2);
cvCircle(m_pIplImageSource,q_CvPointRight_Mid,5,cvScalarAll(127),2);
//显示画圆后的图片
//计算长和高的像素值,三角形3点的坐标构成行列式,行列式的值=2*面积,行列式的值/底边=高
CvMatMa;
intHIGH,WIDE;
floatArea;
inta=q_CvPointLeftTop.x-q_CvPointRightTop.x;
intb=q_CvPointLeftTop.y-q_CvPointRightTop.y;
doublec=a*a+b*b;
//定义行列式
doublearr[9]={q_CvPointLeftTop.x,q_CvPointLeftTop.y,1,q_CvPointRightTop.x,q_CvPointRightTop.y,1,q_CvPointBottom.x,q_CvPointBottom.y,1};
cvInitMatHeader(&
Ma,3,3,CV_64FC1,arr);
Area=abs(cvDet(&
Ma));
HIGH=Area/sqrt(c);
intA=q_CvPointLeft_Top.x-q_CvLeft_Bottom.x;
intB=q_CvPointLeft_Top.y-q_CvLeft_Bottom.y;
doubleC=A*A+B*B;
DoubleARR[9]={q_CvPointLeft_Top.x,q_CvPointLeft_Top.y,1,q_CvLeft_Bottom.x,q_CvLeft_Bottom.y,1,q_CvPointRight_Mid.x,q_CvPointRight_Mid.y,1};
Ma,3,3,CV_64FC1,ARR);
WIDE=Area/sqrt(C);
//在窗口中显示长和高
itoa(HIGH,ch1,10);
itoa(WIDE,ch2,10);
//调用上面的函数进行检测点和计算长和高的值,点击第四个按钮会调用这段程序,当里面的函数调用时,它会调用上面那段函数
OnBnClickedButtonRectangle()
f_MakeRectangleWidth();
2.2.5老师写的显示图片的函数
f_ControlShowImage(IplImage*&
e_pIplImageShow,CWnd*e_pCWndControl,IplImage*e_pIplImageSource)
if((NULL==e_pCWndControl)||(NULL==e_pIplImageSource))
CRectq_CRectControl;
e_pCWndControl->
GetClientRect(&
q_CRectControl);
=e_pIplImageShow)
e_pIplImageShow);
e_pIplImageShow=NULL;
e_pIplImageShow=cvCreateImage(cvSize(q_CRectControl.Width(),q_CRectControl.Height()),
IPL_DEPTH_8U,
e_pIplImageSource->
nChannels);
cvResize(e_pIplImageSource,e_pIplImageShow);
HDCq_HDCControl=e_pCWndControl->
GetDC()->
GetSafeHdc();
unsignedintq_piBuffer[sizeof(BITMAPINFOHEADER)+sizeof(RGBQUAD)*256];
BITMAPINFO*e_pBITMAPINFODisplay=(BITMAPINFO*)q_piBuffer;
BITMAPINFOHEADER*e_pBITMAPINFOHEADERDisplay=&
(e_pBITMAPINFODisplay->
bmiHeader);
memset(e_pBITMAPINFOHEADERDisplay,0,sizeof(*e_pBITMAPINFOHEADERDisplay));
e_pBITMAPINFOHEADERDisplay->
biSize=sizeof(BITMAPINFOHEADER);
biWidth=e_pIplImageShow->
biHeight=-e_pIplImageShow->
biPlanes=1;
biBitCount=8*e_pIplImageShow->
nChannels;
biCompression=BI_RGB;
RGBQUAD*palette=e_pBITMAPINFODisplay->
bmiColors;
if(8==e_pBITMAPINFOHEADERDisplay->
biBitCount)
for(intq_iCycle=0;
q_iCycle<
256;
q_iCycle++)
palette[q_iCycle].rgbBlue=(BYTE)q_iCycle;
palette[q_iCycle].rgbGreen=(BYTE)q_iCycle;
palette[q_iCycle].rgbRed=(BYTE)q_iCycle;
palette[q_iCycle].rgbReserved=(BYTE)0;
StretchDIBits(q_HDCControl,
q_CRectControl.left,
q_CRectControl.top,
e_pIplImageShow->
width,
height,
imageData,
e_pBITMAPINFODisplay,
DIB_RGB_COLORS,
SRCCOPY);
3运行结果
运行结果图形如下:
4小结
通过本次设计,让我很好的锻炼了理论联系实际,与具体项目、课题相结合开发、