openCv中的鼠标回调函数是为了处理鼠标操作消息的响应事件,函数原型为:
C++: void SetMouseCallback(const string & winname,MouseCallback onMouse,void* userdata=0)
第一个参数:const string & 类型的winname ,窗口的名字;
第二个参数: MouseCallback 类型的onMouse,指定窗口里每次鼠标事件发生时的时候被调用的函数指针。
这个函数的原型的大概形势为:void Foo(int event ,int x ,int y ,int flags ,void * param)。event 是鼠标响应类型,CV_EVENT_*变量之一:
EVENT_MOUSEMOVE 滑动 EVENT_LBUTTONDOWN 左击 EVENT_RBUTTONDOWN 右击
EVENT_MBUTTONDOWN 中键点击 EVENT_LBUTTONUP 左键放开 EVENT_RBUTTONUP 右键放开
EVENT_LBUTTONDBLCLK 左键双击 EVENT_RBUTTONDBLCLK 右键双击 EVENT_MBUTTONDBLCLK 中键双击
x和y是鼠标指针在图像坐标系的坐标(不是窗口坐标系)。
flags是CV_EVENT_FLAG的组合,flag的状态有:
EVENT_FLAG_LBUTTON 左键拖拽 EVENT_FLAG_RBUTTON 右键拖拽 EVENT_FLAG_MBUTTON 中键拖拽 EVENT_FLAG_CTRLKEY 按住Ctrl不放 EVENT_FLAG_SHIFTKEY 按住Shift不放 EVENT_FLAG_ALTKEY 按住Alt不放 param是用户定义的传递到setMouseCallback函数调用的参数。
第三个参数:void *userdata 传给回调函数的参数(onMouse)。
示例代码如下:
//--------------------------------【鼠标响应函数声明部分】----------------
// 描述:
//------------------------------------------------------------------------
void onMouseHandle(int event,int x,int y,int flags,void *param);
void onMouseHandle1(int event,int x,int y);
void DrawRectangle(Mat &img,Rect box);
Rect g_rectangle;
bool g_bDrawingBox=false; //是否进行绘制
RNG g_rng(12345);
void Main2()
{
g_rectangle=Rect(-1,-1,0,0);
Mat srcImage(600,800,CV_8UC3),tempImage;
srcImage.copyTo(tempImage);
srcImage=Scalar::all(0);
//设置鼠标操作回调函数
namedWindow(windowName);
setMouseCallback(windowName,onMouseHandle,(void*)&srcImage);
//程序主循环
while (1)
{
srcImage.copyTo(tempImage);
if(g_bDrawingBox)
DrawRectangle(tempImage,g_rectangle);
imshow(windowName,tempImage);
if(waitKey(10)==27)
break;
}
}
//鼠标回调函数
void onMouseHandle(int event,int x,int y,int flags,void *param)
{
Mat &image=*(Mat *) param;
switch(event)
{
//鼠标移动消息
case EVENT_MOUSEMOVE:
{
if(g_bDrawingBox) //是否进行绘制
{
g_rectangle.width=x-g_rectangle.x;
g_rectangle.height=x-g_rectangle.y;
}
}
break;
case EVENT_LBUTTONDOWN:
g_bDrawingBox=true;
g_rectangle=Rect(x,y,0,0); //记录起始点
break;
//左键抬起消息
case EVENT_LBUTTONUP:
g_bDrawingBox=false;
if(g_rectangle.width<0)
{
g_rectangle.x+=g_rectangle.width;
g_rectangle.width*=-1;
}
if(g_rectangle.height<0)
{
g_rectangle.y+=g_rectangle.height;
g_rectangle.height*=-1;
}
//调用函数进行绘制
DrawRectangle(image,g_rectangle);
break;
}
}
//矩形绘制函数
void DrawRectangle(Mat &img,Rect box)
{
rectangle(img,box.tl(),box.br(),Scalar(g_rng.uniform(0,255),g_rng.uniform(0,255),g_rng.uniform(0,255)));//随机颜色
}
效果图:
二、滑动条的创建
创建滑动条的函数是createTrackbar,函数原型如下:
C++ :int createTrackbar(const string & trackbarname, const string & winname ,int * value ,int count ,TrackbarCallback onChange=0 , void * userdata =0 );
第一个参数:const string & 类型的trackbarname 。滑动条名称。
第二个参数:const string & 类型的 winname ,窗口的名称。
第三个参数:int * 类型的value 。整型的指针,表示滑块创建时初始位置。
第四个参数:int 类型的count ,表示滑块可达到的最大位置。
第五个参数:TrackbarCallback 类型的onChange。回调函数,滑块移动时会调用onChange函数。
第六个参数:void *类型的userdata参数。这个参数是用户用来传递给回调函数的参数。
利用滑块调整图像透明度的函数代码:
//创建滑动条
const char windowName[]="【线性混合示例】";
//---------------------【全局变量】-----------------------
const int g_nMAxAlphaValue=100;
int g_nAlphaValueSlider; //滑动条对应的变量
double g_dAlphaValue;
double g_dBetaValue;
//声明存储图像的变量
cv::Mat g_srcImage1;
cv::Mat g_srcImage2;
cv::Mat g_srcImage;
//--------------------------【onTrackBar()函数】----------------------
// 描述:响应滑动条的回调函数
//
//--------------------------------------------------------------------
void onTrackBar(int ,void *)
{
//求当前alpha值相对于最大值得比例
g_dAlphaValue=(double)g_nAlphaValueSlider/(double)g_nMAxAlphaValue;
//则beta值为1减去alpha值
g_dBetaValue=1-g_dAlphaValue;
//根据alpha和beta值进行线性混合
addWeighted(g_srcImage1,g_dAlphaValue,g_srcImage2,g_dBetaValue,0.0,g_srcImage);
//显示效果图
imshow(windowName,g_srcImage);
}
void Main1()
{
//加载图像(两图像尺寸需相同)
g_srcImage1=imread("1-s.jpg");
g_srcImage2=imread("1-s.jpg");
if(!g_srcImage1.data)
{
printf("读取第一幅图片错误!!!");
return ;
}
if(!g_srcImage2.data)
{
printf("读取第二幅图片错误!!!");
return ;
}
//设置滑动条初始位置为70
g_nAlphaValueSlider=70;
//创建窗体
namedWindow(windowName,1);
//在创建的窗体中创建一个滑动条控件
char TrackbarName[50];
sprintf(TrackbarName,"透明值 %d",g_nMAxAlphaValue);
createTrackbar(TrackbarName,windowName,&g_nAlphaValueSlider,g_nMAxAlphaValue,onTrackBar);
//结果在回调函数中显示
onTrackBar(g_nAlphaValueSlider,0);
waitKey(0);
}