#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define WINNAME "画板"
struct MouseParam
{
Mat img; //用于画好一个后显示
Mat imgZoomBackup; //用于zoom的还原备份
Mat imgTmp; //用于实时显示
Mat imgBackup; //清空,显示最初的图
Point pt1;
Point pt2;
bool mouseLflag;
float scale;
};
void draw_rectangle(Mat &img, const Point &pt1, const Point &pt2)
{
//rectangle函数参数: 图片, 左上角, 右下角, 颜色, 线条粗细, 线条类型,点类型
rectangle(img, pt1, pt2, Scalar(0, 255, 0), 1, 0, 0);
}
void draw_crossline(Mat &img, const Point &pt)
{
int width = img.cols;
int height = img.rows;
cv::Point ptv1;
cv::Point ptv2;
cv::Point pth1;
cv::Point pth2;
ptv1 = cv::Point(pt.x, 0);
ptv2 = cv::Point(pt.x, height);
pth1 = cv::Point(0, pt.y);
pth2 = cv::Point(width, pt.y);
cv::line(img, ptv1, ptv2, Scalar(255, 255, 0), 1);
cv::line(img, pth1, pth2, Scalar(255, 255, 0), 1);
}
void zoom(Mat &img, const Mat &srcimg, const Point &pt, const float scale)
{
int x1, y1, x2, y2;
int width, height;
width = (int)(srcimg.cols*scale / 2.0);
height = (int)(srcimg.rows*scale / 2.0);
x1 = max(pt.x - width, 0);
y1 = max(pt.y - height, 0);
x2 = min(pt.x + width, srcimg.cols);
y2 = min(pt.y + height, srcimg.rows);
Rect zoomRect(Point(x1, y1), Point(x2, y2));
img = srcimg(zoomRect).clone();
}
void on_mouse(int event, int x, int y, int flags, void* param)
{
MouseParam *par = (MouseParam*)param;
Point pt(x, y);
double value;
float step = 0.05;
if (event == EVENT_RBUTTONDOWN) //按下右键,重画
{
par->img = par->imgBackup.clone();
}
else if (event == EVENT_LBUTTONDOWN)
{
par->pt1 = pt;
par->pt2 = pt;
par->mouseLflag = true;
}
else if (event == CV_EVENT_MOUSEMOVE && flags == CV_EVENT_FLAG_LBUTTON)
{
par->pt2 = pt;
}
else if (event == CV_EVENT_LBUTTONUP)
{
par->pt2 = pt;
draw_rectangle(par->img, par->pt1, par->pt2);
//par->imgZoomBackup = par->img.clone();
par->mouseLflag = false;
}
else if (event == CV_EVENT_MOUSEMOVE)
{
par->pt1 = pt;
}
else if (event == CV_EVENT_MOUSEWHEEL)
{
value = getMouseWheelDelta(flags);
if (value>0)
par->scale += step;
else if (value<0)
par->scale -= step;
par->scale = max((float)0.3, par->scale);
par->scale = min((float)1.0, par->scale);
zoom(par->img, par->imgZoomBackup, par->pt1, par->scale);
}
}
int main()
{
//Mat img(512, 512, CV_8UC3, Scalar::all(255));
Mat img = imread("E:\\bg.jpg");
MouseParam mouseParam;
mouseParam.img = img.clone();
mouseParam.imgBackup = img.clone();
mouseParam.imgZoomBackup = img.clone();
mouseParam.mouseLflag = false;
float step = 0.05;
mouseParam.scale = 1.0;
namedWindow(WINNAME, 0);
setMouseCallback(WINNAME, on_mouse, &mouseParam);
int key;
while (1)
{
mouseParam.imgTmp = mouseParam.img.clone();
draw_crossline(mouseParam.imgTmp, mouseParam.pt1);
if (mouseParam.mouseLflag == true)
draw_rectangle(mouseParam.imgTmp, mouseParam.pt1, mouseParam.pt2);
imshow(WINNAME, mouseParam.imgTmp);
key = waitKey(40);
if (key == 27)
{
break;
}
else if (key == toascii('q'))
{
mouseParam.scale -= step;
zoom(mouseParam.img, mouseParam.imgZoomBackup, mouseParam.pt1, mouseParam.scale);
}
else if (key == toascii('e'))
{
mouseParam.scale += step;
zoom(mouseParam.img, mouseParam.imgZoomBackup, mouseParam.pt1, mouseParam.scale);
}
}
return 0;
}
效果如下: