Linux教程網
- // 角點檢測
- // 根據《基於OpenCV的計算機視覺技術實現》
-
- #define max_corners 200; // 限定的最大角點數
-
- IplImage* srcImage = 0; // 待處理的源圖像
- IplImage* ImageShow = 0; // 存儲顯示帶角點的圖像
- IplImage* grayImage = 0; // 原始圖像轉換成的灰階圖像
- IplImage* corners1 = 0; // 臨時圖像
- IplImage* corners2 = 0; // 臨時圖像
-
- int cornerCount0 = max_corners;
- int cornerCount; // 實際測得角點數
- int qualityLevel = 0; // 最小質量因子
- int minDistance = 15; // 角點最小距離
- CvScalar color = CV_RGB(255,0,0); // 繪圖顏色
- CvPoint2D32f corners[200]; // 角點坐標
- CvRect ROI_rect; // 測試范圍
- char chek_area_state = 0; // 鼠標狀態
-
- void re_find_corners(int) // 滑動條響應函數
- {
- int i,x,y,xl,yu,xr,yd,k;
- int radius = 5;
- int thickness = 1;
- double quality_level = (double) qualityLevel / 100 + 0.02;
- double min_distance = (double) minDistance;
-
- cornerCount=cornerCount0; // 設置最大角點數
- cvGoodFeaturesToTrack(grayImage, // 角點檢測
- corners1,corners2,corners,&cornerCount,
- quality_level,min_distance,NULL);
-
- if (cornerCount>0) { // 測到角點
- xl=ROI_rect.x; yu=ROI_rect.y; // 設置初始測試范圍
- xr=ROI_rect.x+ROI_rect.width;
- yd=ROI_rect.y+ROI_rect.height;
- cvCopy(srcImage,ImageShow); // 恢復源圖像
- for (i=0,k=0;i<cornerCount;i++) {
- x=(int)corners[i].x;
- y=(int)corners[i].y;
- if ((xl<x)&&(x<xr)&&(yu<y)&&(y<yd)) { // 范圍檢查
- corners[k].x=corners[i].x; // 保存范圍內角點
- corners[k].y=corners[i].y;
- k++;
- }
- }
- cornerCount=k; // 范圍內角點數
- cvCopy(srcImage,ImageShow);
- for (i=0;i<cornerCount;i++) {
- x=(int)corners[i].x;
- y=(int)corners[i].y;
- cvCircle(ImageShow,cvPoint(x,y), // 角點處畫圈
- radius,color,thickness,CV_AA,0);
- }
- cvRectangle(ImageShow,cvPoint(xl,yu),cvPoint(xr,yd),
- CV_RGB(0,255,0),thickness,CV_AA,0); // 畫矩形
- cvShowImage("image", ImageShow); // 顯示畫圈圖像
- }
- }
-
- void on_mouse2(int event,int x,int y,int flags,void* param)
- { // 鼠標響應函數
- int thickness = 1;
- CvPoint point1,point2;
-
- if (event == CV_EVENT_LBUTTONDOWN) { // 鼠標左鍵按下
- ROI_rect.x = x; // 記錄檢測窗口一角坐標
- ROI_rect.y = y;
- chek_area_state = 1; // 設置狀態標志
- }
- else if (chek_area_state && event == CV_EVENT_MOUSEMOVE) { // 鼠標移動
- cvCopy(srcImage,ImageShow); // 恢復原始圖像
- point1 = cvPoint(ROI_rect.x, ROI_rect.y);
- point2 = cvPoint(x,y); // 當前坐標
- cvRectangle(ImageShow,point1,point2,CV_RGB(0,255,0),
- thickness,CV_AA,0); // 畫矩形
- cvShowImage("image", ImageShow); // 顯示檢測結果
- cvWaitKey(20); // 延時
- }
- else if (chek_area_state && event == CV_EVENT_LBUTTONUP) { // 鼠標左鍵抬起
- ROI_rect.width = abs(x - ROI_rect.x); // 記錄檢測窗口對角坐標
- ROI_rect.height = abs(y - ROI_rect.y);
-
- re_find_corners(0); // 角點檢測
- chek_area_state = 0; // 恢復狀態標志
- cvWaitKey(20);
- }
- }
-
- void CCVMFCView::OnCornersTest() // 角點檢測
- {
- if (workImg->nChannels>1) { // 原圖為真彩色圖像==3
- srcImage = cvCloneImage(workImg);
- }
- else { // 原圖為灰階圖像
- srcImage = cvCreateImage(cvGetSize(workImg),IPL_DEPTH_8U,3);
- cvCvtColor(workImg,srcImage,CV_GRAY2BGR);
- }
- cvFlip(srcImage);
-
- grayImage = cvCreateImage(cvGetSize(srcImage),IPL_DEPTH_8U,1);
- cvCvtColor(srcImage,grayImage,CV_BGR2GRAY); // 轉換為灰階圖像
- ImageShow = cvCloneImage(srcImage);
-
- ROI_rect.x =0;
- ROI_rect.y =0;
- ROI_rect.width = grayImage->width;
- ROI_rect.height = grayImage->height;
-
- corners1 = cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_32F,1);
- corners2 = cvCreateImage(cvGetSize(grayImage),IPL_DEPTH_32F,1);
-
- cvNamedWindow("image",0); // 設置顯示窗口
- cvResizeWindow("image",325,350); // 改變窗口尺寸
-
- cvCreateTrackbar("角點最小距離", "image", // 設置距離滑動條
- &minDistance, 200,re_find_corners);
- cvCreateTrackbar("最小質量因子","image", // 設置質量滑動條
- &qualityLevel,100,re_find_corners);
-
- re_find_corners(0); // 角點檢測
-
- cvSetMouseCallback("image",on_mouse2,0); // 設置鼠標響應函數
-
- cvWaitKey(0); // 等待鍵輸入
-
- cvDestroyWindow( "image" ); // 關閉窗口
-
- cvReleaseImage(&srcImage); // 釋放圖像存儲單元
- cvReleaseImage(&grayImage);
- cvReleaseImage(&corners1);
- cvReleaseImage(&corners2);
-
- cvFlip(ImageShow);
- m_dibFlag=imageReplace(ImageShow,&workImg); // 輸出檢測結果
-
- m_ImageType=-2;
- Invalidate();
- }
Copyright ©
Linux教程網 All Rights Reserved