OpenCV鼠标滑轮事件
鼠标的滑轮事件实现图像的缩放很方便,具体在回调函数中如下写:
其中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>0) scale +=step; else if(value<0) scale -=step; break; default: break; } }
下面是简单编写的滑动滑轮实现图像的缩放操作代码:
1 #include <iostream> 2 #include <string> 3 #include <opencv2/opencv.hpp> 4 5 using namespace std; 6 using namespace cv; 7 8 float scale=1.0; 9 10 void zoomInAndOut(const float scale, const Mat srcImg, Mat &dstImg) 11 { 12 Mat M=Mat::eye(3,3,CV_32FC1); 13 int imgHeight=srcImg.rows; 14 int imgWidth=srcImg.cols; 15 16 uchar* pSrcData = (uchar*)srcImg.data; 17 uchar* pDstData = (uchar*)dstImg.data; 18 19 Point2f center(imgWidth / 2.0, imgHeight / 2.0); 20 //计算仿射矩阵 21 M.at<float>(0, 0) = scale; 22 M.at<float>(0, 2) = (1 - scale)*center.x; 23 M.at<float>(1, 1) = scale; 24 M.at<float>(1, 2) = (1 - scale)*center.y; 25 26 float a11 = M.at<float>(0, 0); 27 float a12 = M.at<float>(0, 1); 28 float a13 = M.at<float>(0, 2); 29 float a21 = M.at<float>(1, 0); 30 float a22 = M.at<float>(1, 1); 31 float a23 = M.at<float>(1, 2); 32 float a31 = M.at<float>(2, 0); 33 float a32 = M.at<float>(2, 1); 34 float a33 = M.at<float>(2, 2); 35 36 float bx = a11*a22 - a21*a12; 37 float by = a12*a21 - a11*a22; 38 if ( abs(bx) > 1e-3 && abs(by) > 1e-3) 39 { 40 bx = 1.0 / bx; 41 by = 1.0 / by; 42 float cx = a13*a22 - a23*a12; 43 float cy = a13*a21 - a23*a11; 44 45 for (int j =0; j < imgHeight; j++) 46 { 47 for (int i = 0; i < imgWidth; i++) 48 { 49 float u = (a22*i - a12*j - cx) *bx; 50 float v = (a21*i - a11*j - cy) *by; 51 52 int u0 = floor(u); 53 int v0 = floor(v); 54 int u1 = floor(u0 + 1); 55 int v1 = floor(v0 + 1); 56 if (u0 >= 0 && v0 >= 0 && u1 < imgWidth && v1 < imgHeight) 57 { 58 float dx = u - u0; 59 float dy = v - v0; 60 float weight1 = (1 - dx)*(1 - dy); 61 float weight2 = dx*(1 - dy); 62 float weight3 = (1 - dx)*dy; 63 float weight4 = dx*dy; 64 65 for (int k=0; k<srcImg.channels(); k++) 66 { 67 pDstData[j*imgWidth * 3 + i * 3 + k] = weight1*pSrcData[v0*imgWidth * 3 + u0 * 3 + k] + 68 weight2*pSrcData[v0*imgWidth * 3 + u1 * 3 + k] + 69 weight3*pSrcData[v1*imgWidth * 3 + u0 * 3 + k] + 70 weight4*pSrcData[v1*imgWidth * 3 + u1 * 3 + k]; 71 } 72 } 73 else 74 { 75 for (int k=0; k<srcImg.channels(); k++) 76 { 77 pDstData[j*imgWidth * 3 + i * 3 + k] = 0; 78 } 79 } 80 } 81 } 82 } 83 } 84 85 void onMouse(int event, int x, int y, int flags, void* ) 86 { 87 double value; 88 float step=0.02; 89 switch (event) 90 { 91 case CV_EVENT_MOUSEWHEEL: 92 value = getMouseWheelDelta(flags); 93 if (value>0) 94 scale +=step; 95 else if(value<0) 96 scale -=step; 97 break; 98 default: 99 break; 100 } 101 } 102 103 void main() 104 { 105 string imgPath="data/source_images/"; 106 Mat srcImg = imread(imgPath+"moon.jpg"); 107 pyrDown(srcImg, srcImg); 108 pyrDown(srcImg, srcImg); 109 110 Mat dstImg = srcImg.clone(); 111 dstImg.setTo(0); 112 113 string windowName="showImg"; 114 namedWindow(windowName); 115 imshow(windowName, srcImg); 116 waitKey(10); 117 118 setMouseCallback(windowName, onMouse, NULL); 119 float scaleMin=0.5; 120 float scaleMax=2; 121 while (true) 122 { 123 scale = (scale<scaleMin)? (scaleMin): scale; 124 scale = (scale>scaleMax)? (scaleMax): scale; 125 zoomInAndOut(scale, srcImg, dstImg); 126 imshow(windowName, dstImg); 127 waitKey(10); 128 } 129 }
---------------------------------
业精于勤而荒于嬉 行成于思而毁于随
---------------------------------