机器视觉课程设计报告.docx
《机器视觉课程设计报告.docx》由会员分享,可在线阅读,更多相关《机器视觉课程设计报告.docx(17页珍藏版)》请在冰豆网上搜索。
机器视觉课程设计报告
机器视觉课程设计
对圆盘形零件圆心与直径和矩形
零件长与宽尺寸测量
学生学院机电学院
专业班级
学号
学生姓名
指导教师
2015年1月20日
1问题描述
1.1基本目标
显示一张图片(包含一个矩形或一个圆),测量矩形的长宽或圆的直径。
完成得及格分,扩展有加分!
要求图片
1.2基本要求
“机器视觉”考试结果要求独立在计算机上完成,建议使用VisualC++和OpenCV实现一个具有视觉捕捉、图像显示、尺寸测量等功能的对话框程序,其中必须完成对圆盘形零件圆心与直径和矩形零件长与宽尺寸测量内容。
在教师提供的基本框架程序基础上,修改、补充界面和功能。
2程序及其算法
2.1检测与计算圆半径的程序
思路:
从图片中间横扫取点得M_Point[0],M_Point[1](x坐标相加除2的圆心的x坐标)中间纵向取点得M_Point[2],M_Point[3](y坐标相加除2的圆心的y坐标)
圆上四个点到圆心的距离(半径)取平均值,输出为半径。
显示图片
程序如下:
doublec_DialogTeclarn:
:
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{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--){if(e_dThreshold>q_pchDataImage[q_iWidth/2+q_iWidthStep*(Cycle_Y-1)]){M_Point[1].x=q_iWidth/2;M_Point[1].y=Cycle_Y;}}for(intCycle_X=1;Cycle_X{if(e_dThreshold>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>1;Cycle_X--){if(e_dThreshold>q_pchDataImage[Cycle_X+q_iWidthStep*(q_iHeight/2-1)]){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;for(inti=0;i<4;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){return;}if(NULL!=m_pIplImageSource){cvReleaseImage(&m_pIplImageSource);m_pIplImageSource=NULL;}m_pIplImageSource=cvCloneImage(q_pIplImageCapture);cvReleaseCapture(&q_pCvCapture);CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);}注:绿色的为检测是否成功打开摄像头,蓝色的是读取摄像头拍摄的图片到内存,后面的语句是让图片在mfc窗口显示出来。2.2.2保存拍摄的照片程序voidc_DialogTeclarn::OnBnClickedButtonSaveImage(){//TODO:在此添加控件通知处理程序代码cvSaveImage(_T(".//CurrentImage.jpg"),m_pIplImageSource);}2.2.3读取拍摄到的图片(读取文名字CurrentImage.jpg的图片)voidc_DialogTeclarn::OnBnClickedButtonLoadImage(){//TODO:在此添加控件通知处理程序代码if(NULL!=m_pIplImageSource){cvReleaseImage(&m_pIplImageSource);m_pIplImageSource=NULL;}m_pIplImageSource=cvLoadImage(_T(".//CurrentImage.jpg"),0);CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);}2.2.4检测边上的点和计算长和高的函数思路是:第一步找到边上的点,设定一个变量e_dThreshold值为127,通过循环让它与每一个像素的像素值进行比较。如果检测到一个点的像素值比127小,则这个点可能就是需要的点(黑色=0,白色=255)如果每个像素都要比较运算太多,所以上边两个点的检测是沿着图片长的的2/5分处和3/5分处向下检测,下边的点是沿着1/2处向上检测。第二步是用找到6个点的坐标算出三角形的面积,然后除以底边边长得到高。求三角形的面积用的是行列式的值等于三角形面积的2倍 程序如下:doublec_DialogTeclarn::f_MakeRectangleWidth(doublee_dThreshold){//TODO:在此添加控件通知处理程序代码//定义一些点和变量intq_iWidth=m_pIplImageSource->width;intq_iHeight=m_pIplImageSource->height;intq_iWidthStep=m_pIplImageSource->widthStep;uchar*q_pchDataImage=(uchar*)m_pIplImageSource->imageData;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{if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXLeftTop]){q_CvPointLeftTop.x=q_iXLeftTop;q_CvPointLeftTop.y=q_iCycleHeight;break;}}for(intq_iCycleHeight=0;q_iCycleHeight{if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXRightTop]){q_CvPointRightTop.x=q_iXRightTop;q_CvPointRightTop.y=q_iCycleHeight;break;}}for(intq_iCycleHeight=q_iHeight-1;q_iCycleHeight>=0;q_iCycleHeight--){if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXBottom]){q_CvPointBottom.x=q_iXBottom;q_CvPointBottom.y=q_iCycleHeight;break;}}//求左右两边上的点,3个循环for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftTop-1)]){q_CvPointLeft_Top.x=q_iCycleWidth;q_CvPointLeft_Top.y=q_iYLeftTop;break;}}for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftBottom-1)]){q_CvLeft_Bottom.x=q_iCycleWidth;q_CvLeft_Bottom.y=q_iYLeftBottom;break;}}for(intq_iCycleWidth=q_iHeight-1;q_iCycleWidth>=0;q_iCycleWidth--){if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYRightMid-1)]){q_CvPointRight_Mid.x=q_iCycleWidth;q_CvPointRight_Mid.y=q_iYRightMid;break;}}//在检测到的点上画圆,只是为了更好看到找点的情况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);//显示画圆后的图片CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);//计算长和高的像素值,三角形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};cvInitMatHeader(&Ma,3,3,CV_64FC1,ARR);Area=abs(cvDet(&Ma));WIDE=Area/sqrt(C);//在窗口中显示长和高charch1[10],ch2[10];itoa(HIGH,ch1,10);itoa(WIDE,ch2,10);SetDlgItemText(IDC_LONG,ch1);SetDlgItemText(IDC_SHORT,ch2);cvSaveImage(_T(".//Result_Image.jpg"),m_pIplImageSource);return0;}//调用上面的函数进行检测点和计算长和高的值,点击第四个按钮会调用这段程序,当里面的函数调用时,它会调用上面那段函数voidc_DialogTeclarn::OnBnClickedButtonRectangle(){//TODO:在此添加控件通知处理程序代码f_MakeRectangleWidth();}2.2.5老师写的显示图片的函数voidc_DialogTeclarn::f_ControlShowImage(IplImage*&e_pIplImageShow,CWnd*e_pCWndControl,IplImage*e_pIplImageSource){if((NULL==e_pCWndControl)||(NULL==e_pIplImageSource)){return;}CRectq_CRectControl;e_pCWndControl->GetClientRect(&q_CRectControl);if(NULL!=e_pIplImageShow){cvReleaseImage(&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);e_pBITMAPINFOHEADERDisplay->biWidth=e_pIplImageShow->width;e_pBITMAPINFOHEADERDisplay->biHeight=-e_pIplImageShow->height;e_pBITMAPINFOHEADERDisplay->biPlanes=1;e_pBITMAPINFOHEADERDisplay->biBitCount=8*e_pIplImageShow->nChannels;e_pBITMAPINFOHEADERDisplay->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,e_pIplImageShow->height,q_CRectControl.left,q_CRectControl.top,e_pIplImageShow->width,e_pIplImageShow->height,e_pIplImageShow->imageData,e_pBITMAPINFODisplay,DIB_RGB_COLORS,SRCCOPY);}3运行结果运行结果图形如下: 4小结通过本次设计,让
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{if(e_dThreshold>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>1;Cycle_X--){if(e_dThreshold>q_pchDataImage[Cycle_X+q_iWidthStep*(q_iHeight/2-1)]){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;for(inti=0;i<4;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){return;}if(NULL!=m_pIplImageSource){cvReleaseImage(&m_pIplImageSource);m_pIplImageSource=NULL;}m_pIplImageSource=cvCloneImage(q_pIplImageCapture);cvReleaseCapture(&q_pCvCapture);CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);}注:绿色的为检测是否成功打开摄像头,蓝色的是读取摄像头拍摄的图片到内存,后面的语句是让图片在mfc窗口显示出来。2.2.2保存拍摄的照片程序voidc_DialogTeclarn::OnBnClickedButtonSaveImage(){//TODO:在此添加控件通知处理程序代码cvSaveImage(_T(".//CurrentImage.jpg"),m_pIplImageSource);}2.2.3读取拍摄到的图片(读取文名字CurrentImage.jpg的图片)voidc_DialogTeclarn::OnBnClickedButtonLoadImage(){//TODO:在此添加控件通知处理程序代码if(NULL!=m_pIplImageSource){cvReleaseImage(&m_pIplImageSource);m_pIplImageSource=NULL;}m_pIplImageSource=cvLoadImage(_T(".//CurrentImage.jpg"),0);CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);}2.2.4检测边上的点和计算长和高的函数思路是:第一步找到边上的点,设定一个变量e_dThreshold值为127,通过循环让它与每一个像素的像素值进行比较。如果检测到一个点的像素值比127小,则这个点可能就是需要的点(黑色=0,白色=255)如果每个像素都要比较运算太多,所以上边两个点的检测是沿着图片长的的2/5分处和3/5分处向下检测,下边的点是沿着1/2处向上检测。第二步是用找到6个点的坐标算出三角形的面积,然后除以底边边长得到高。求三角形的面积用的是行列式的值等于三角形面积的2倍 程序如下:doublec_DialogTeclarn::f_MakeRectangleWidth(doublee_dThreshold){//TODO:在此添加控件通知处理程序代码//定义一些点和变量intq_iWidth=m_pIplImageSource->width;intq_iHeight=m_pIplImageSource->height;intq_iWidthStep=m_pIplImageSource->widthStep;uchar*q_pchDataImage=(uchar*)m_pIplImageSource->imageData;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{if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXLeftTop]){q_CvPointLeftTop.x=q_iXLeftTop;q_CvPointLeftTop.y=q_iCycleHeight;break;}}for(intq_iCycleHeight=0;q_iCycleHeight{if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXRightTop]){q_CvPointRightTop.x=q_iXRightTop;q_CvPointRightTop.y=q_iCycleHeight;break;}}for(intq_iCycleHeight=q_iHeight-1;q_iCycleHeight>=0;q_iCycleHeight--){if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXBottom]){q_CvPointBottom.x=q_iXBottom;q_CvPointBottom.y=q_iCycleHeight;break;}}//求左右两边上的点,3个循环for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftTop-1)]){q_CvPointLeft_Top.x=q_iCycleWidth;q_CvPointLeft_Top.y=q_iYLeftTop;break;}}for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftBottom-1)]){q_CvLeft_Bottom.x=q_iCycleWidth;q_CvLeft_Bottom.y=q_iYLeftBottom;break;}}for(intq_iCycleWidth=q_iHeight-1;q_iCycleWidth>=0;q_iCycleWidth--){if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYRightMid-1)]){q_CvPointRight_Mid.x=q_iCycleWidth;q_CvPointRight_Mid.y=q_iYRightMid;break;}}//在检测到的点上画圆,只是为了更好看到找点的情况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);//显示画圆后的图片CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);//计算长和高的像素值,三角形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};cvInitMatHeader(&Ma,3,3,CV_64FC1,ARR);Area=abs(cvDet(&Ma));WIDE=Area/sqrt(C);//在窗口中显示长和高charch1[10],ch2[10];itoa(HIGH,ch1,10);itoa(WIDE,ch2,10);SetDlgItemText(IDC_LONG,ch1);SetDlgItemText(IDC_SHORT,ch2);cvSaveImage(_T(".//Result_Image.jpg"),m_pIplImageSource);return0;}//调用上面的函数进行检测点和计算长和高的值,点击第四个按钮会调用这段程序,当里面的函数调用时,它会调用上面那段函数voidc_DialogTeclarn::OnBnClickedButtonRectangle(){//TODO:在此添加控件通知处理程序代码f_MakeRectangleWidth();}2.2.5老师写的显示图片的函数voidc_DialogTeclarn::f_ControlShowImage(IplImage*&e_pIplImageShow,CWnd*e_pCWndControl,IplImage*e_pIplImageSource){if((NULL==e_pCWndControl)||(NULL==e_pIplImageSource)){return;}CRectq_CRectControl;e_pCWndControl->GetClientRect(&q_CRectControl);if(NULL!=e_pIplImageShow){cvReleaseImage(&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);e_pBITMAPINFOHEADERDisplay->biWidth=e_pIplImageShow->width;e_pBITMAPINFOHEADERDisplay->biHeight=-e_pIplImageShow->height;e_pBITMAPINFOHEADERDisplay->biPlanes=1;e_pBITMAPINFOHEADERDisplay->biBitCount=8*e_pIplImageShow->nChannels;e_pBITMAPINFOHEADERDisplay->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,e_pIplImageShow->height,q_CRectControl.left,q_CRectControl.top,e_pIplImageShow->width,e_pIplImageShow->height,e_pIplImageShow->imageData,e_pBITMAPINFODisplay,DIB_RGB_COLORS,SRCCOPY);}3运行结果运行结果图形如下: 4小结通过本次设计,让
if(e_dThreshold>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>1;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;
for(inti=0;i<4;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:
在此添加控件通知处理程序代码
cvSaveImage(_T(".//CurrentImage.jpg"),m_pIplImageSource);
2.2.3读取拍摄到的图片(读取文名字CurrentImage.jpg的图片)
OnBnClickedButtonLoadImage()
m_pIplImageSource=cvLoadImage(_T(".//CurrentImage.jpg"),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{if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXLeftTop]){q_CvPointLeftTop.x=q_iXLeftTop;q_CvPointLeftTop.y=q_iCycleHeight;break;}}for(intq_iCycleHeight=0;q_iCycleHeight{if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXRightTop]){q_CvPointRightTop.x=q_iXRightTop;q_CvPointRightTop.y=q_iCycleHeight;break;}}for(intq_iCycleHeight=q_iHeight-1;q_iCycleHeight>=0;q_iCycleHeight--){if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXBottom]){q_CvPointBottom.x=q_iXBottom;q_CvPointBottom.y=q_iCycleHeight;break;}}//求左右两边上的点,3个循环for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftTop-1)]){q_CvPointLeft_Top.x=q_iCycleWidth;q_CvPointLeft_Top.y=q_iYLeftTop;break;}}for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftBottom-1)]){q_CvLeft_Bottom.x=q_iCycleWidth;q_CvLeft_Bottom.y=q_iYLeftBottom;break;}}for(intq_iCycleWidth=q_iHeight-1;q_iCycleWidth>=0;q_iCycleWidth--){if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYRightMid-1)]){q_CvPointRight_Mid.x=q_iCycleWidth;q_CvPointRight_Mid.y=q_iYRightMid;break;}}//在检测到的点上画圆,只是为了更好看到找点的情况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);//显示画圆后的图片CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);//计算长和高的像素值,三角形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};cvInitMatHeader(&Ma,3,3,CV_64FC1,ARR);Area=abs(cvDet(&Ma));WIDE=Area/sqrt(C);//在窗口中显示长和高charch1[10],ch2[10];itoa(HIGH,ch1,10);itoa(WIDE,ch2,10);SetDlgItemText(IDC_LONG,ch1);SetDlgItemText(IDC_SHORT,ch2);cvSaveImage(_T(".//Result_Image.jpg"),m_pIplImageSource);return0;}//调用上面的函数进行检测点和计算长和高的值,点击第四个按钮会调用这段程序,当里面的函数调用时,它会调用上面那段函数voidc_DialogTeclarn::OnBnClickedButtonRectangle(){//TODO:在此添加控件通知处理程序代码f_MakeRectangleWidth();}2.2.5老师写的显示图片的函数voidc_DialogTeclarn::f_ControlShowImage(IplImage*&e_pIplImageShow,CWnd*e_pCWndControl,IplImage*e_pIplImageSource){if((NULL==e_pCWndControl)||(NULL==e_pIplImageSource)){return;}CRectq_CRectControl;e_pCWndControl->GetClientRect(&q_CRectControl);if(NULL!=e_pIplImageShow){cvReleaseImage(&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);e_pBITMAPINFOHEADERDisplay->biWidth=e_pIplImageShow->width;e_pBITMAPINFOHEADERDisplay->biHeight=-e_pIplImageShow->height;e_pBITMAPINFOHEADERDisplay->biPlanes=1;e_pBITMAPINFOHEADERDisplay->biBitCount=8*e_pIplImageShow->nChannels;e_pBITMAPINFOHEADERDisplay->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,e_pIplImageShow->height,q_CRectControl.left,q_CRectControl.top,e_pIplImageShow->width,e_pIplImageShow->height,e_pIplImageShow->imageData,e_pBITMAPINFODisplay,DIB_RGB_COLORS,SRCCOPY);}3运行结果运行结果图形如下: 4小结通过本次设计,让
if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXLeftTop])
q_CvPointLeftTop.x=q_iXLeftTop;
q_CvPointLeftTop.y=q_iCycleHeight;
break;
for(intq_iCycleHeight=0;q_iCycleHeight{if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXRightTop]){q_CvPointRightTop.x=q_iXRightTop;q_CvPointRightTop.y=q_iCycleHeight;break;}}for(intq_iCycleHeight=q_iHeight-1;q_iCycleHeight>=0;q_iCycleHeight--){if(e_dThreshold>q_pchDataImage[q_iCycleHeight*q_iWidthStep+q_iXBottom]){q_CvPointBottom.x=q_iXBottom;q_CvPointBottom.y=q_iCycleHeight;break;}}//求左右两边上的点,3个循环for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftTop-1)]){q_CvPointLeft_Top.x=q_iCycleWidth;q_CvPointLeft_Top.y=q_iYLeftTop;break;}}for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftBottom-1)]){q_CvLeft_Bottom.x=q_iCycleWidth;q_CvLeft_Bottom.y=q_iYLeftBottom;break;}}for(intq_iCycleWidth=q_iHeight-1;q_iCycleWidth>=0;q_iCycleWidth--){if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYRightMid-1)]){q_CvPointRight_Mid.x=q_iCycleWidth;q_CvPointRight_Mid.y=q_iYRightMid;break;}}//在检测到的点上画圆,只是为了更好看到找点的情况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);//显示画圆后的图片CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);//计算长和高的像素值,三角形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};cvInitMatHeader(&Ma,3,3,CV_64FC1,ARR);Area=abs(cvDet(&Ma));WIDE=Area/sqrt(C);//在窗口中显示长和高charch1[10],ch2[10];itoa(HIGH,ch1,10);itoa(WIDE,ch2,10);SetDlgItemText(IDC_LONG,ch1);SetDlgItemText(IDC_SHORT,ch2);cvSaveImage(_T(".//Result_Image.jpg"),m_pIplImageSource);return0;}//调用上面的函数进行检测点和计算长和高的值,点击第四个按钮会调用这段程序,当里面的函数调用时,它会调用上面那段函数voidc_DialogTeclarn::OnBnClickedButtonRectangle(){//TODO:在此添加控件通知处理程序代码f_MakeRectangleWidth();}2.2.5老师写的显示图片的函数voidc_DialogTeclarn::f_ControlShowImage(IplImage*&e_pIplImageShow,CWnd*e_pCWndControl,IplImage*e_pIplImageSource){if((NULL==e_pCWndControl)||(NULL==e_pIplImageSource)){return;}CRectq_CRectControl;e_pCWndControl->GetClientRect(&q_CRectControl);if(NULL!=e_pIplImageShow){cvReleaseImage(&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);e_pBITMAPINFOHEADERDisplay->biWidth=e_pIplImageShow->width;e_pBITMAPINFOHEADERDisplay->biHeight=-e_pIplImageShow->height;e_pBITMAPINFOHEADERDisplay->biPlanes=1;e_pBITMAPINFOHEADERDisplay->biBitCount=8*e_pIplImageShow->nChannels;e_pBITMAPINFOHEADERDisplay->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,e_pIplImageShow->height,q_CRectControl.left,q_CRectControl.top,e_pIplImageShow->width,e_pIplImageShow->height,e_pIplImageShow->imageData,e_pBITMAPINFODisplay,DIB_RGB_COLORS,SRCCOPY);}3运行结果运行结果图形如下: 4小结通过本次设计,让
if(e_dThreshold>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--)
if(e_dThreshold>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{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftTop-1)]){q_CvPointLeft_Top.x=q_iCycleWidth;q_CvPointLeft_Top.y=q_iYLeftTop;break;}}for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftBottom-1)]){q_CvLeft_Bottom.x=q_iCycleWidth;q_CvLeft_Bottom.y=q_iYLeftBottom;break;}}for(intq_iCycleWidth=q_iHeight-1;q_iCycleWidth>=0;q_iCycleWidth--){if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYRightMid-1)]){q_CvPointRight_Mid.x=q_iCycleWidth;q_CvPointRight_Mid.y=q_iYRightMid;break;}}//在检测到的点上画圆,只是为了更好看到找点的情况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);//显示画圆后的图片CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);//计算长和高的像素值,三角形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};cvInitMatHeader(&Ma,3,3,CV_64FC1,ARR);Area=abs(cvDet(&Ma));WIDE=Area/sqrt(C);//在窗口中显示长和高charch1[10],ch2[10];itoa(HIGH,ch1,10);itoa(WIDE,ch2,10);SetDlgItemText(IDC_LONG,ch1);SetDlgItemText(IDC_SHORT,ch2);cvSaveImage(_T(".//Result_Image.jpg"),m_pIplImageSource);return0;}//调用上面的函数进行检测点和计算长和高的值,点击第四个按钮会调用这段程序,当里面的函数调用时,它会调用上面那段函数voidc_DialogTeclarn::OnBnClickedButtonRectangle(){//TODO:在此添加控件通知处理程序代码f_MakeRectangleWidth();}2.2.5老师写的显示图片的函数voidc_DialogTeclarn::f_ControlShowImage(IplImage*&e_pIplImageShow,CWnd*e_pCWndControl,IplImage*e_pIplImageSource){if((NULL==e_pCWndControl)||(NULL==e_pIplImageSource)){return;}CRectq_CRectControl;e_pCWndControl->GetClientRect(&q_CRectControl);if(NULL!=e_pIplImageShow){cvReleaseImage(&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);e_pBITMAPINFOHEADERDisplay->biWidth=e_pIplImageShow->width;e_pBITMAPINFOHEADERDisplay->biHeight=-e_pIplImageShow->height;e_pBITMAPINFOHEADERDisplay->biPlanes=1;e_pBITMAPINFOHEADERDisplay->biBitCount=8*e_pIplImageShow->nChannels;e_pBITMAPINFOHEADERDisplay->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,e_pIplImageShow->height,q_CRectControl.left,q_CRectControl.top,e_pIplImageShow->width,e_pIplImageShow->height,e_pIplImageShow->imageData,e_pBITMAPINFODisplay,DIB_RGB_COLORS,SRCCOPY);}3运行结果运行结果图形如下: 4小结通过本次设计,让
if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftTop-1)])
q_CvPointLeft_Top.x=q_iCycleWidth;
q_CvPointLeft_Top.y=q_iYLeftTop;
for(intq_iCycleWidth=0;q_iCycleWidth{if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYLeftBottom-1)]){q_CvLeft_Bottom.x=q_iCycleWidth;q_CvLeft_Bottom.y=q_iYLeftBottom;break;}}for(intq_iCycleWidth=q_iHeight-1;q_iCycleWidth>=0;q_iCycleWidth--){if(e_dThreshold>q_pchDataImage[q_iCycleWidth+q_iWidthStep*(q_iYRightMid-1)]){q_CvPointRight_Mid.x=q_iCycleWidth;q_CvPointRight_Mid.y=q_iYRightMid;break;}}//在检测到的点上画圆,只是为了更好看到找点的情况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);//显示画圆后的图片CWnd*e_pCWndPicture=this->GetDlgItem(ID_PICTURE_DISPLAY);f_ControlShowImage(m_pIplImageDisplay,e_pCWndPicture,m_pIplImageSource);//计算长和高的像素值,三角形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};cvInitMatHeader(&Ma,3,3,CV_64FC1,ARR);Area=abs(cvDet(&Ma));WIDE=Area/sqrt(C);//在窗口中显示长和高charch1[10],ch2[10];itoa(HIGH,ch1,10);itoa(WIDE,ch2,10);SetDlgItemText(IDC_LONG,ch1);SetDlgItemText(IDC_SHORT,ch2);cvSaveImage(_T(".//Result_Image.jpg"),m_pIplImageSource);return0;}//调用上面的函数进行检测点和计算长和高的值,点击第四个按钮会调用这段程序,当里面的函数调用时,它会调用上面那段函数voidc_DialogTeclarn::OnBnClickedButtonRectangle(){//TODO:在此添加控件通知处理程序代码f_MakeRectangleWidth();}2.2.5老师写的显示图片的函数voidc_DialogTeclarn::f_ControlShowImage(IplImage*&e_pIplImageShow,CWnd*e_pCWndControl,IplImage*e_pIplImageSource){if((NULL==e_pCWndControl)||(NULL==e_pIplImageSource)){return;}CRectq_CRectControl;e_pCWndControl->GetClientRect(&q_CRectControl);if(NULL!=e_pIplImageShow){cvReleaseImage(&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);e_pBITMAPINFOHEADERDisplay->biWidth=e_pIplImageShow->width;e_pBITMAPINFOHEADERDisplay->biHeight=-e_pIplImageShow->height;e_pBITMAPINFOHEADERDisplay->biPlanes=1;e_pBITMAPINFOHEADERDisplay->biBitCount=8*e_pIplImageShow->nChannels;e_pBITMAPINFOHEADERDisplay->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,e_pIplImageShow->height,q_CRectControl.left,q_CRectControl.top,e_pIplImageShow->width,e_pIplImageShow->height,e_pIplImageShow->imageData,e_pBITMAPINFODisplay,DIB_RGB_COLORS,SRCCOPY);}3运行结果运行结果图形如下: 4小结通过本次设计,让
if(e_dThreshold>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>=0;q_iCycleWidth--)
if(e_dThreshold>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};
cvInitMatHeader(&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)
cvReleaseImage(&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);
e_pBITMAPINFOHEADERDisplay->biWidth=e_pIplImageShow->width;
e_pBITMAPINFOHEADERDisplay->biHeight=-e_pIplImageShow->height;
e_pBITMAPINFOHEADERDisplay->biPlanes=1;
e_pBITMAPINFOHEADERDisplay->biBitCount=8*e_pIplImageShow->nChannels;
e_pBITMAPINFOHEADERDisplay->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,
e_pIplImageShow->height,
e_pIplImageShow->imageData,
e_pBITMAPINFODisplay,
DIB_RGB_COLORS,
SRCCOPY);
3运行结果
运行结果图形如下:
4小结
通过本次设计,让
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1