赞
踩
交互操作能够增加用户对程序流程的控制,使程序可以根据用户需求实现不同的处理结果。有时某一个参数需要反复尝试不同的数值,这时交互操作可以实现在程序运行过程中改变参数数值的作用,避免重复运行程序,节省时间,同时能够增强结果的对比效果。本文将介绍 OpenCV 4 中提供的图像窗口滑动条和鼠标响应两种窗口交互操作。
- int cv::createTrackbar(const String & trackbarname,
- const String & winname,
- int * value,
- int count,
- TrackbarCallback onChange = 0,
- void * userdata = 0
- )
• trackbarname:滑动条的名称。
• winname:创建滑动条窗口的名称。
• value:指向整数变量的指针,该指针指向的值反映滑块的位置,创建后,滑块位置由此变量定义。
• count:滑动条的最大取值。
• onChange:每次滑块更改位置时要调用的函数的指针,其中函数原型为 void Foo(int, void*);,其中第一个参数是轨迹栏位置,第二个参数是用户数据。如果回调是 NULL 指针,则不会调用任何回调,而只是更新数值。
• userdata:传递给回调函数的可选参数。
- #include <opencv2/opencv.hpp>
- #include <iostream>
-
- using namespace std;
- using namespace cv;
-
- //为了能在被调用函数中使用,设置成全局的
- int value;
- void callBack(int, void*); //滑动条回调函数
- Mat img1, img2;
-
- int main()
- {
- img1 = imread("../pic/gril.jpg");
- if (!img1.data)
- {
- cout << "请确认是否输入正确的图像文件" << endl;
- return -1;
- }
-
- Scalar scalar = mean(img1);
- float imgChannel1 = scalar.val[0];
- float imgChannel2 = scalar.val[1];
- float imgChannel3 = scalar.val[2];
- //float imgChannel4 = scalar.val[3];
- //qDebug() << "--4.method mean picture Light : " << QString::number(picMeanLight, 10, 4);
- float imgLight = (imgChannel1 + imgChannel2 + imgChannel3) / 3;
-
- cout << "111 imgLight == " << imgLight << endl;
-
- namedWindow("滑动条改变图像亮度");
- imshow("滑动条改变图像亮度", img1);
- value = 100; //滑动条创建时的初始值
- //创建滑动条
- createTrackbar("亮度值百分比", "滑动条改变图像亮度", &value, 600, callBack, 0);
- waitKey();
- }
-
- void callBack(int, void*)
- {
-
-
- float a = value / 100.0;
- img2 = img1 * a;
-
- Scalar scalar = mean(img2);
- float imgChannel1 = scalar.val[0];
- float imgChannel2 = scalar.val[1];
- float imgChannel3 = scalar.val[2];
- //float imgChannel4 = scalar.val[3];
- //qDebug() << "--4.method mean picture Light : " << QString::number(picMeanLight, 10, 4);
- float imgLight = (imgChannel1 + imgChannel2 + imgChannel3) / 3;
-
- cout << "222 imgLight == " << imgLight << endl;
- imshow("滑动条改变图像亮度", img2);
- }
打印图片亮度时,随着滑动条的值增大而增大
- void cv::setMouseCallback(const String & winname,
- MouseCallback onMouse,
- void * userdata = 0
- )
• winname :添加鼠标响应的窗口的名字。• onMouse :鼠标响应的回调函数。• userdata :传递给回调函数的可选参数。
- typedef void(* cv::MouseCallback)(int event,
- int x,
- int y,
- int flags,
- void *userdata
- )
• event :鼠标响应事件,参数为 EVENT_* 形式 。• x :鼠标指针在图像坐标系中的 x 坐标。• y :鼠标指针在图像坐标系中的 y 坐标。• flags :鼠标响应标志,参数为 EVENT_FLAG_* 形式。• userdata :传递给回调函数的可选参数。
- #include <opencv2/opencv.hpp>
- #include <iostream>
-
- using namespace std;
- using namespace cv;
-
- Mat img,imgPoint; //全局的图像
- Point prePoint; //前一时刻鼠标的坐标,用于绘制直线
- void mouse(int event, int x, int y, int flags, void*);
-
- int main()
- {
- img = imread("../pic/gril.jpg");
- if (!img.data)
- {
- cout << "请确认输入图像名称是否正确!" << endl;
- return -1;
- }
- img.copyTo(imgPoint);
- imshow("图像窗口 1", img);
- imshow("图像窗口 2", imgPoint);
- setMouseCallback("图像窗口 1", mouse,0 ); //鼠标响应
- waitKey(0);
- return 0;
- }
-
- void mouse(int event, int x, int y, int flags, void*)
- {
- if (event == EVENT_RBUTTONDOWN) //单击右键
- {
- cout << "点击鼠标左键才可以绘制轨迹" << endl;
- }
- if (event == EVENT_LBUTTONDOWN) //单击左键,输出坐标
- {
- prePoint = Point(x, y);
- cout << "轨迹起始坐标" << prePoint << endl;
- }
-
- if (event == EVENT_MOUSEMOVE && (flags & EVENT_FLAG_LBUTTON)) //按住鼠标左键移动
- {
- //通过改变图像像素显示鼠标移动轨迹
- imgPoint.at<Vec3b>(y, x) = Vec3b(0, 0, 255);
- imgPoint.at<Vec3b>(y, x-1) = Vec3b(0, 0, 255);
- imgPoint.at<Vec3b>(y, x+1) = Vec3b(0, 0, 255);
- imgPoint.at<Vec3b>(y+1, x) = Vec3b(0, 0, 255);
- imgPoint.at<Vec3b>(y+1, x) = Vec3b(0, 0, 255);
- imshow("图像窗口 2", imgPoint);
-
- //通过绘制直线显示鼠标移动轨迹
- Point pt(x, y);
- line(img, prePoint, pt, Scalar(0, 0, 255), 2, 5, 0);
- prePoint = pt;
- imshow("图像窗口 1", img);
- }
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。