基于MFC和OpenCV实现角点检测

时间:2022-03-25 20:18:24

本文实例为大家分享了MFC和OpenCV实现角点检测的具体代码,供大家参考,具体内容如下

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
// 角点检测
// 根据《基于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();
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/abcjennifer/article/details/7315220