鼠标的滑轮事件实现图像的缩放很方便,具体在回调函数中如下写:

其中scale可以在外部定义为全局变量,通过响应CV_EVENT_MOUSEWHEEL滑轮事件获取Scale的具体值。

获取Scale值需要关注两个问题,滑轮滑动的方向和滑动量的大小。滑动方向通过getMouseWheelDelta(flags)获取,当返回值>0时,表示向前滑动;当返回值<0时,表示向后滑动。滑动量根据滑动方向自行设置相应的滑动步长即可。

void onMouse(int event, int x, int y, int flags,  void* )
{
double value;
float step=0.02;
switch (event)
{
case CV_EVENT_MOUSEWHEEL:
value = getMouseWheelDelta(flags);
if (value>)
scale +=step;
else if(value<)
scale -=step;
break;
default:
break;
}
}

下面是简单编写的滑动滑轮实现图像的缩放操作代码:

 #include <iostream>
#include <string>
#include <opencv2/opencv.hpp> using namespace std;
using namespace cv; float scale=1.0; void zoomInAndOut(const float scale, const Mat srcImg, Mat &dstImg)
{
Mat M=Mat::eye(,,CV_32FC1);
int imgHeight=srcImg.rows;
int imgWidth=srcImg.cols; uchar* pSrcData = (uchar*)srcImg.data;
uchar* pDstData = (uchar*)dstImg.data; Point2f center(imgWidth / 2.0, imgHeight / 2.0);
//计算仿射矩阵
M.at<float>(, ) = scale;
M.at<float>(, ) = ( - scale)*center.x;
M.at<float>(, ) = scale;
M.at<float>(, ) = ( - scale)*center.y; float a11 = M.at<float>(, );
float a12 = M.at<float>(, );
float a13 = M.at<float>(, );
float a21 = M.at<float>(, );
float a22 = M.at<float>(, );
float a23 = M.at<float>(, );
float a31 = M.at<float>(, );
float a32 = M.at<float>(, );
float a33 = M.at<float>(, ); float bx = a11*a22 - a21*a12;
float by = a12*a21 - a11*a22;
if ( abs(bx) > 1e- && abs(by) > 1e-)
{
bx = 1.0 / bx;
by = 1.0 / by;
float cx = a13*a22 - a23*a12;
float cy = a13*a21 - a23*a11; for (int j =; j < imgHeight; j++)
{
for (int i = ; i < imgWidth; i++)
{
float u = (a22*i - a12*j - cx) *bx;
float v = (a21*i - a11*j - cy) *by; int u0 = floor(u);
int v0 = floor(v);
int u1 = floor(u0 + );
int v1 = floor(v0 + );
if (u0 >= && v0 >= && u1 < imgWidth && v1 < imgHeight)
{
float dx = u - u0;
float dy = v - v0;
float weight1 = ( - dx)*( - dy);
float weight2 = dx*( - dy);
float weight3 = ( - dx)*dy;
float weight4 = dx*dy; for (int k=; k<srcImg.channels(); k++)
{
pDstData[j*imgWidth * + i * + k] = weight1*pSrcData[v0*imgWidth * + u0 * + k] +
weight2*pSrcData[v0*imgWidth * + u1 * + k] +
weight3*pSrcData[v1*imgWidth * + u0 * + k] +
weight4*pSrcData[v1*imgWidth * + u1 * + k];
}
}
else
{
for (int k=; k<srcImg.channels(); k++)
{
pDstData[j*imgWidth * + i * + k] = ;
}
}
}
}
}
} void onMouse(int event, int x, int y, int flags, void* )
{
double value;
float step=0.02;
switch (event)
{
case CV_EVENT_MOUSEWHEEL:
value = getMouseWheelDelta(flags);
if (value>)
scale +=step;
else if(value<)
scale -=step;
break;
default:
break;
}
} void main()
{
string imgPath="data/source_images/";
Mat srcImg = imread(imgPath+"moon.jpg");
pyrDown(srcImg, srcImg);
pyrDown(srcImg, srcImg); Mat dstImg = srcImg.clone();
dstImg.setTo(); string windowName="showImg";
namedWindow(windowName);
imshow(windowName, srcImg);
waitKey(); setMouseCallback(windowName, onMouse, NULL);
float scaleMin=0.5;
float scaleMax=;
while (true)
{
scale = (scale<scaleMin)? (scaleMin): scale;
scale = (scale>scaleMax)? (scaleMax): scale;
zoomInAndOut(scale, srcImg, dstImg);
imshow(windowName, dstImg);
waitKey();
}
}
04-25 05:36