• 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 }
    View Code
  • 相关阅读:
    LG4377 「USACO2018OPEN」Talent Show 分数规划+背包
    LG4111/LOJ2122 「HEOI2015」小Z的房间 矩阵树定理
    LG5104 红包发红包 概率与期望
    LG2375/LOJ2246 「NOI2014」动物园 KMP改造
    LG4824 「USACO2015FEB」(Silver)Censoring KMP+栈
    20191004 「HZOJ NOIP2019 Round #9」20191004模拟
    LG5357 「模板」AC自动机(二次加强版) AC自动机+fail树
    LG3812 「模板」线性基 线性基
    数据结构
    git
  • 原文地址:https://www.cnblogs.com/riddick/p/7696019.html
Copyright © 2020-2023  润新知