opencv 手选roi区域_【OpenCV】选择ROI区域 (转)

该博客介绍了如何在OpenCV中通过鼠标交互选取感兴趣区域(ROI),包括点选择和矩形框选择两种模式。通过创建MouseSelect类并定义鼠标回调函数on_mouse,实现了在图像上实时显示和调整ROI的过程。
摘要由CSDN通过智能技术生成

问题描述:在测试目标跟踪算法时,需要选择不同区域作为目标,进行目标跟踪,测试目标跟踪的效果。

解决思路:

1.OpenCV中提供了鼠标交互控制,利用setMouseCallback()给固定的窗口设置鼠标回调函数。

2.在鼠标回调函数中,选择感兴趣区域。

代码实现如下,将感兴趣区域封装在MouseSelect类中,提供选择点和矩形框两种模式。

1 #pragma once

2 #ifndef __MOUSESELECT_H__

3 #define __MOUSESELECT_H__

4

5 #include

6 #include

7

8 #define MAX_OBJECTS 10

9 using namespace cv;

10 using namespace std;

11 typedef struct MouseSelectParams

12 {

13 vector pts; //Points of selected

14 char *win_name;

15 Mat *image;

16 unsigned int mode; //1 Point,2 Rect

17 int n; // selected object number

18 }MouseSelectParams;

19

20 void on_mouse(int event,int x,int y,int flags,void *param);

21 class MouseSelect

22 {

23 public:

24 MouseSelect();

25 ~MouseSelect();

26

27 void select_rect(Mat &frame);

28 void select_point(Mat &frame);

29

30 vector vPoints;

31 vector vRects;

32 unsigned int obj_selected;

33 private:

34 int get_rects(Mat &frame);

35 int get_points(Mat &frame);

36

37 };

38 #endif

1 #include "MouseSelect.h"

2

3 MouseSelectParams *g_mousep;

4 MouseSelect::MouseSelect() {}

5

6 MouseSelect::~MouseSelect() {}

7

8 void MouseSelect::select_rect(Mat &frame)

9 {

10 obj_selected = 0;

11 while(0 == obj_selected)

12 {

13 obj_selected = get_rects(frame);

14 if (obj_selected == 0)

15 {

16 cout<

17 }

18 }

19 }

20

21 void MouseSelect::select_point(Mat &frame)

22 {

23 obj_selected = 0;

24 while(0 == obj_selected)

25 {

26 obj_selected = get_points(frame);

27 if (obj_selected == 0)

28 {

29 cout<

30 }

31 }

32 }

33

34 int MouseSelect::get_rects(Mat &frame)

35 {

36 char *win_name = "Init Frame";

37 MouseSelectParams params;

38 params.win_name = win_name;

39 params.image = &frame;

40 params.n = 0;

41 params.mode = 2;

42 namedWindow(win_name,WINDOW_AUTOSIZE);

43 imshow(win_name,frame);

44

45 g_mousep = &params;

46 setMouseCallback(win_name,on_mouse,0);

47 waitKey(0);

48 destroyWindow(win_name);

49

50 int x1,x2,y1,y2,w,h;

51 Rect rt;

52 Point pt1,pt2;

53 cout<

54 for(int i = 0;i < params.pts.size();i += 2)

55 {

56 pt1 = params.pts[i];

57 pt2 = params.pts[i + 1];

58 x1 = min(pt1.x,pt2.x);

59 x2 = max(pt1.x,pt2.x);

60 y1 = min(pt1.y,pt2.y);

61 y2 = max(pt1.y,pt2.y);

62 w = x2 - x1;

63 h = y2 - y1;

64 w = (w % 2)? w:w+1;

65 h = (h % 2)? h:h+1;

66 rt.x = x1;

67 rt.y = y1;

68 rt.width = w;

69 rt.height = h;

70 vRects.push_back(rt);

71 }

72 return params.n;

73 }

74

75 int MouseSelect::get_points(Mat &frame)

76 {

77 char *win_name = "Init Frame";

78 MouseSelectParams params;

79 params.win_name = win_name;

80 params.image = &frame;

81 params.n = 0;

82 params.mode = 1;

83

84 namedWindow(win_name,1);

85 imshow(win_name,frame);

86

87 g_mousep = &params;

88 setMouseCallback(win_name,on_mouse,0);

89 waitKey(0);

90

91 destroyWindow(win_name);

92

93 cout<

94 for (int i = 0;i < params.n;i++)

95 {

96 vPoints.push_back(params.pts[i]);

97 }

98 return params.n;

99 }

100

101 void on_mouse(int event,int x,int y,int flags,void *param)

102 {

103 int n;

104 static bool pressed = false;

105 static Point cur_pt;

106 static Point prev_pt;

107 /* on left button press, remember first corner of rectangle around object */

108 if (event == CV_EVENT_LBUTTONDOWN)

109 {

110 n = g_mousep->n;

111 if (n == MAX_OBJECTS)

112 {

113 return;

114 }

115 prev_pt.x = x;

116 prev_pt.y = y;

117 //cout<

118 pressed = true;

119 }

120 /* on left button up, finalise the rectangle and draw it in black */

121 else if(event == CV_EVENT_LBUTTONUP && pressed)

122 {

123 /* 1 == mode for selecting points */

124 if (1 == g_mousep->mode)

125 {

126 n = g_mousep->n;

127 if (n == MAX_OBJECTS)

128 {

129 return;

130 }

131 cur_pt.x = x;

132 cur_pt.y = y;

133 g_mousep->pts.push_back(cur_pt);

134 int radius = 3;

135 circle(*g_mousep->image,cur_pt,radius,CV_RGB(255,0,0));

136 imshow(g_mousep->win_name,*g_mousep->image);

137 pressed = false;

138 g_mousep->n++;

139 }

140 /* 2 == mode for selecting rectangles */

141 else if (2 == g_mousep->mode)

142 {

143 n = g_mousep->n;

144 if (n == MAX_OBJECTS)

145 {

146 return;

147 }

148 cur_pt.x = x;

149 cur_pt.y = y;

150 g_mousep->pts.push_back(prev_pt);

151 g_mousep->pts.push_back(cur_pt);

152 // cout<

153 rectangle(*g_mousep->image,prev_pt,cur_pt,CV_RGB(0,0,255));

154 imshow(g_mousep->win_name,*g_mousep->image);

155 pressed = false;

156 g_mousep->n++;

157 }

158 else if (3 == g_mousep->mode)

159 {

160 n = g_mousep->n;

161

162 }

163 }

164 else if (event == CV_EVENT_MOUSEMOVE && pressed && CV_EVENT_FLAG_LBUTTON)

165 {

166 if (2 == g_mousep->mode)

167 {

168 n = g_mousep->n;

169 if (n == MAX_OBJECTS)

170 {

171 return;

172 }

173 cur_pt.x = x;

174 cur_pt.y = y;

175 Mat tmp = (*g_mousep->image).clone();

176 //cout<

177 rectangle(tmp,prev_pt,cur_pt,CV_RGB(0,255,0));

178 imshow(g_mousep->win_name,tmp);

179 }

180 }

181 }

代码分析:

on_mouse()回调函数,对应于一个显示窗口。

在回调函数处理鼠标事件,要理解一个鼠标点击过程,会产生多个事件。

例如:鼠标左击,对应着CV_EVENT_LBUTTONDOWN和CV_EVENT_LBUTTONUP。

在选择矩形框区域时,CV_EVENT_LBUTTONDOWN记录一个对角点;CV_EVENT_MOUSEMOVE记录选对矩形框的中间过程,并显示出来,便于用户调整选择的区域;CV_EVENT_LBUTTONUP记录另一个对角点,CV_EVENT_LBUTTONUP响应后,完成一个矩形框的选择。

在选择点时,只需记录CV_EVENT_LBUTTONUP事件响应的坐标。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值