OpenCV来控制鼠标移动
来源:互联网 发布:2017淘宝生意好差 编辑:程序博客网 时间:2024/05/17 03:36
之前的日志“VS2005下配置OpenCV2.1”里介绍了如何在VS2005里安装OpenCV2.1,下面这篇日志里就介绍了下如何使用CV来控制鼠标移动。代码和AutoCamShift例子里的差不多,只是我进行了许多代码的删减以及我添加稍许注释,另外就是补充了::SetCursorPos(_x,_y)函数。
不太多说废话,C++代码如下:
001
#include "cv.h"
002
#include "highgui.h"
003
#include
004
#include
005
006
//基本的图像指针
007
IplImage *image = 0
008
, *hsv = 0
009
, *hue = 0
010
, *mask = 0
011
, *backproject = 0
012
, *histimg = 0;
013
014
//用于直方图
015
CvHistogram *hist = 0;
016
017
//用于判断
018
int
select_object = 0;
019
int
track_object = 0;
020
int
cursor_object=0;
021
022
//用于鼠标选择区域
023
CvPoint origin;
024
CvRect selection;
025
026
//CAMSHIFT算法用到
027
CvRect track_window;
028
CvBox2D track_box;
029
CvConnectedComp track_comp;
030
031
// 划分HIST的个数,越高越精确
032
int
hdims = 48;
033
034
//设置HSV的范围(0-180)
035
float
hranges_arr[] = {0,180};
036
float
* hranges = hranges_arr;
037
038
void
on_mouse(
int
event,
int
x,
int
y,
int
flags,
void
* param)
039
{
040
if
( !image )
041
return
;
042
043
if
( image->origin )
044
y = image->height - y;
045
046
//左键按下时 select_object=1
047
//右键按下时 select_object=0
048
if
( select_object )
049
{
050
selection.x = MIN(x,origin.x);
051
selection.y = MIN(y,origin.y);
052
selection.width = selection.x + CV_IABS(x - origin.x);
053
selection.height = selection.y + CV_IABS(y - origin.y);
054
055
selection.x = MAX( selection.x, 0 );
056
selection.y = MAX( selection.y, 0 );
057
selection.width = MIN( selection.width, image->width );
058
selection.height = MIN( selection.height, image->height );
059
selection.width -= selection.x;
060
selection.height -= selection.y;
061
062
}
063
064
switch
( event )
065
{
066
case
CV_EVENT_LBUTTONDOWN:
067
origin = cvPoint(x,y);
068
selection = cvRect(x,y,0,0);
069
select_object = 1;
070
break
;
071
case
CV_EVENT_LBUTTONUP:
072
select_object = 0;
073
if
( selection.width > 0 && selection.height > 0 )
074
track_object = -1;
075
#ifdef _DEBUG
076
printf
(
"/n # 鼠标的选择区域:"
);
077
printf
(
"/n X = %d, Y = %d, Width = %d, Height = %d"
,
078
selection.x, selection.y, selection.width, selection.height);
079
#endif
080
break
;
081
}
082
}
083
084
//画直方图里用到。HSV---->RGB,返回cvScalar。
085
CvScalar hsv2rgb(
float
hue )
086
{
087
int
rgb[3], p, sector;
088
static
const
int
sector_data[][3]=
089
{{0,2,1}, {1,2,0}, {1,0,2}, {2,0,1}, {2,1,0}, {0,1,2}};
090
hue *= 0.033333333333333333333333333333333f;
091
sector = cvFloor(hue);
092
p = cvRound(255*(hue - sector));
093
p ^= sector & 1 ? 255 : 0;
094
095
rgb[sector_data[sector][0]] = 255;
096
rgb[sector_data[sector][1]] = 0;
097
rgb[sector_data[sector][2]] = p;
098
099
#ifdef _DEBUG
100
printf
(
"/n # Convert HSV to RGB:"
);
101
printf
(
"/n HUE = %f"
, hue);
102
printf
(
"/n R = %d, G = %d, B = %d"
, rgb[0],rgb[1],rgb[2]);
103
#endif
104
105
return
cvScalar(rgb[2], rgb[1], rgb[0],0);
106
}
107
108
int
main(
int
argc,
char
** argv )
109
{
110
CvCapture* capture = 0;
111
IplImage* frame = 0;
112
113
capture = cvCaptureFromCAM(0);
114
115
int
frameH = (
int
) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
116
int
frameW = (
int
) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
117
118
if
( !capture )
119
{
120
fprintf
(stderr,
"Could not initialize capturing.../n"
);
121
return
-1;
122
}
123
124
cvNamedWindow(
"CamShiftDemo"
, 1 );
125
cvSetMouseCallback(
"CamShiftDemo"
, on_mouse, NULL );
126
127
for
(;;)
128
{
129
int
bin_w,ori_x,i,c;
130
131
ori_x=selection.x+(selection.width/2);
132
133
frame = cvQueryFrame( capture );
134
if
( !frame )
135
break
;
136
137
if
( !image )
138
{
139
image = cvCreateImage( cvGetSize(frame), 8, 3 );
140
image->origin = frame->origin;
141
142
hsv = cvCreateImage( cvGetSize(frame), 8, 3 );
143
hue = cvCreateImage( cvGetSize(frame), 8, 1 );
144
mask = cvCreateImage( cvGetSize(frame), 8, 1 );
145
backproject = cvCreateImage( cvGetSize(frame), 8, 1 );
146
histimg = cvCreateImage( cvSize(320,200), 8, 3 );
147
cvZero( histimg );
148
149
hist = cvCreateHist( 1, &hdims, CV_HIST_ARRAY, &hranges, 1 );
// 计算直方图
150
151
}
152
153
cvCopy(frame, image, 0 );
154
cvCvtColor( image, hsv, CV_BGR2HSV );
// 彩色空间转换 BGR to HSV
155
156
if
( track_object )
157
{
158
int
_vmin = 10;
159
int
_vmax = 256;
160
161
cvInRangeS( hsv,
162
cvScalar(0,30,MIN(_vmin,_vmax),0),
163
cvScalar(180,256,MAX(_vmin,_vmax),0),
164
mask );
// 得到二值的MASK
165
166
cvSplit( hsv, hue, 0, 0, 0 );
// 只提取 HUE 分量
167
168
if
( track_object < 0 )
169
{
170
float
max_val = 0.f;
171
cvSetImageROI( hue, selection );
// 得到选择区域 for ROI
172
cvSetImageROI( mask, selection );
// 得到选择区域 for mask
173
cvCalcHist( &hue, hist, 0, mask );
// 计算直方图
174
cvGetMinMaxHistValue( hist, 0, &max_val, 0, 0 );
// 只找最大值
175
cvConvertScale( hist->bins, hist->bins, max_val ? 255. / max_val : 0., 0 );
// 缩放 bin 到区间 [0,255]
176
cvResetImageROI( hue );
// remove ROI
177
cvResetImageROI( mask );
178
track_window = selection;
179
track_object = 1;
180
181
cvZero( histimg );
182
183
bin_w= histimg->width / hdims;
// hdims: 条的个数,则 bin_w 为条的宽度
184
185
// 画直方图
186
for
(i = 0; i < hdims; ++i)
187
{
188
int
val = cvRound( cvGetReal1D(hist->bins,i)*histimg->height/255 );
//cvRound一种舍入的方法把浮点数转为整形
189
190
CvScalar color = hsv2rgb(i*180.f/hdims);
191
cvRectangle(histimg,
192
cvPoint(i*bin_w,histimg->height),
//矩形左下角
193
cvPoint((i+1)*bin_w,histimg->height - val),
//矩形右上角
194
color,
195
-1,
196
8,
197
0 );
198
}
199
}
200
201
// 使用back project方法计算hue的反向投影
202
cvCalcBackProject( &hue, backproject, hist );
203
204
cvAnd( backproject, mask, backproject, 0 );
205
206
// CAMSHIFT算法
207
cvCamShift( backproject,
//目标直方图的反向投影
208
track_window,
//初始搜索窗口
209
cvTermCriteria( CV_TERMCRIT_EPS | CV_TERMCRIT_ITER, 10, 1 ),
//窗口搜索停止的准则
210
&track_comp,
//象素点的和
211
&track_box );
212
213
//改变光标
214
if
(cursor_object)
215
{
216
int
_x=track_box.center.x/frameW*1280;
217
int
_y=track_box.center.y/frameH*800;
218
::SetCursorPos(_x,_y);
219
}
220
221
//新旧交替
222
track_window = track_comp.rect;
223
224
if
( image->origin )
225
track_box.angle = -track_box.angle;
226
227
//绘制椭圆
228
cvEllipseBox(image, track_box, CV_RGB(255,0,0), 3, CV_AA, 0 );
229
230
}
231
232
if
( select_object && selection.width > 0 && selection.height > 0)
233
{
234
cvSetImageROI( image, selection );
//基于给定的值设置感兴趣通道
235
cvXorS( image, cvScalarAll(255), image, 0 );
//计算数组元素与数量之间的按位异或
236
cvResetImageROI( image );
//释放图像的ROI
237
}
238
239
cvShowImage(
"CamShiftDemo"
, image );
240
cvShowImage(
"Histogram"
, histimg );
241
242
c=cvWaitKey(10);
243
if
( (
char
) c == 27 )
244
break
;
245
switch
( (
char
) c )
246
{
247
case
'm'
:
248
if
(cursor_object)
249
cursor_object=0;
250
else
251
cursor_object=1;
252
break
;
253
default
:
254
;
255
}
256
257
}
258
259
cvReleaseCapture( &capture );
260
cvDestroyWindow(
"CamShiftDemo"
);
261
262
return
0;
263
}
整个代码里只控制了鼠标的移动,可是如何模仿鼠标的单击和双击以及右键呢?~如果你有思路希望你可以告诉我,共同探讨一下。
超越C++原创文章,转载请注明来源并保留原文链接
本文链接:http://www.beyondc.cn/opencv-to-control-the-mouse.html
- OpenCV来控制鼠标移动
- 怎么用鼠标滚动来控制DBGRID移动?
- 鼠标移动控制代码
- 鼠标控制小球移动
- 鼠标控制物体移动
- VS+opencv鼠标移动图片
- 鼠标移动控制对象滚动.
- 控制pb鼠标的移动
- 鼠标点击控制角色移动
- Unity 鼠标控制角色移动
- Unity3D鼠标控制角色移动
- 用鼠标控制角色移动
- selenium+python控制鼠标移动
- 用鼠标控制角色移动
- 用Kinect来控制鼠标的移动、单击、双击和右击 (Windows sdk)
- 用Kinect来控制鼠标的移动、单击、双击和右击 及PPT控制(Windows sdk)
- OpenCV图像处理->鼠标移动区域放大
- opencv 检测鼠标的点击和移动
- C++文件读写操作
- Java容器集合学习心得
- 做人必须保留的7张底牌
- C++ 内存池
- Java集合对象排序
- OpenCV来控制鼠标移动
- 课表
- Java Exception处理之最佳实践
- VS2005下配置OpenCV2.1
- C如何调用C++的库
- Win32下使用Socket:WinSock
- 如何在VS2008中调用DLL/如何在VS2008中生成DLL
- Linux下Socket编程之TCP应用
- jquery $.ajax 全局事件引用方式以及各个事件(全局/局部)执行顺序