1.滑动条的创建和使用
滑动条(Trackbar)是opencv在它调节动态参数的时候的一种工具,它依附于窗口存在。
由于opencv没有实现按钮的功能,所以我们可以用仅含有0-1的滑动条来实现按钮的功能。
1.1创建滑动条:createTrackbar()函数 createTrackbar用于创建一个依附于指定窗口上的可以调节数值的滑动条(轨迹条)。 回调函数原型: int createTrackbar(const string& trackbarname, const string& winname, int* value, int count , TrackbarCallback onChange=0, void* userdata=1)
- 参数一:轨迹条的名称;
- 参数二:轨迹条依附的窗口名称,对应namedWindow()创建时填写的窗口名。
- 参数三:int* 一个指向整数型的指针,滑动块的位置。滑动块创建时的起始值。
- 参数四:滑块可以达到的最大值,最小为0.
- 参数五:TrackbarCallbar类型的onChagne,默认为0,这是一个指向回调函数的指针,每次滑块的值改变,都会进行回调。并且这个函数的原型为
void XXX(int , void*) ,其中第一个参数时轨迹位置,第二个是用户数据(第六个参数)。如果回调为NULL,则只有滑动条的值有变化,无回调。 - 参数六:默认为0,这个参数是用户传递给回调函数的,用来处理轨迹事件。如果使用的第三个参数value是全局变量地 话,可以不用管这个参数。
createTrackbar函数创建了一个具有特定名称和范围的轨迹条。 回调函数就是一个通过指针调用的函数。如果我们把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其他所指向的函数时,就称为回调函数。回调函数,不由该函数的实现直接调用,而是在特定的事件或条件发生时由另外的一方调用,用于对该事件或条件进行响应。
createTrackbar("对比度:", "[窗口效果]", &g_nContrastValue, 300, on_Change);
1.2 实例 如何用轨迹条来控制两幅图像的Alpha的混合。 实现代码:
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace std;
using namespace cv;
#define WINDOW_NAME "[线性混合实例]"
const int g_nMaxAlphaValue = 100;
int g_nAlphaValueSlider;
double g_dAlphaValue;
double g_dBetaValue;
Mat g_srcImage1;
Mat g_srcImage2;
Mat g_dstImage;
void on_Trackbar(int , void *)
{
g_dAlphaValue = (double) g_nAlphaValueSlider / g_nMaxAlphaValue;
g_dBetaValue = ( 1.0 - g_dAlphaValue);
addWeighted(g_srcImage1, g_dAlphaValue, g_srcImage2, g_dBetaValue, 0.0, g_dstImage);
imshow(WINDOW_NAME, g_dstImage);
}
int main(int argc, char ** argv)
{
g_srcImage1 = imread("../1.png");
g_srcImage2 = imread("../2.png");
cout << g_srcImage1.rows << g_srcImage1.cols << endl;
cout << g_srcImage2.rows << g_srcImage2.cols << endl;
if( !g_srcImage1.data) {
cerr << "第一副图所在路径错误!" << endl;
}
if( !g_srcImage2.data) {
cerr << "第二副图所在路径错误!" << endl;
}
g_nAlphaValueSlider = 70;
namedWindow(WINDOW_NAME, 1);
char TrackbarName[50];
sprintf(TrackbarName, "透明值 %d", g_nMaxAlphaValue);
createTrackbar(TrackbarName, WINDOW_NAME, &g_nAlphaValueSlider, g_nMaxAlphaValue, on_Trackbar);
on_Trackbar(g_nAlphaValueSlider, 0);
int value = getTrackbarPos(TrackbarName, WINDOW_NAME);
cout << value << endl;
waitKey(0);
return 0;
}
CMakeLists.txt:
cmake_minimum_required(VERSION 3.6)
find_package(OpenCV REQUIRED)
include_directories(${OpenCV_INCLUDE_DIRS})
add_executable(open 2.cpp)
target_link_libraries(open ${OpenCV_LIBS})
混合后的效果,通过改变滑动条,可以该变他们的混合程度。 1.3 获取当前轨迹条的位置:getTrackbarPos()函数 getTrackPos()是配合createTrackbar()使用的函数,用于获取当前轨迹条的位置。 函数原型: int getTrackbarPos(const string& trackbarname , const string& winname) ;
2.1 setMouseCallback()函数的作用是为指定的窗口设置鼠标回调函数 函数原型: void setMouseCallback(const string& winname, MOuseCallback onMouse, void * userdata=0) ;
- 参数一:窗口名称;
- 参数二:MouseCallback类型的onMouse,指定窗口里每次鼠标时间发生的时候,被调用的函数指针。这个函数的原型
void Foo(int event, int x, int y, int flags, void* param) 。其中event是EVENT_+变量之一, x, y 是鼠标指针在图像坐标系中的 坐标值,flags是EVENT_FLAG的组合,param是用户定义的传递到SetMouseCallback函数调用的参数。如EVENT_MOUSEMOVE为鼠标移动消息,EVENT_LBUTTONDOWN为鼠标左键按下消息等。 - 参数三:用户定义的传递到回调函数的参数,默认为0;
2.2实例 如何在OpenCV中使用鼠标进行交互 实现代码:
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;
#define WINDOW_NAME "[程序窗口]"
void on_MouseHandle(int event, int x, int y, int flags, void* param);
void DrawRectangle(cv::Mat& image, cv::Rect box);
void ShowHelpText();
Rect g_rectangle;
bool g_bDrawingBox = false;
RNG g_rng(1234);
int main(int argc, char ** argv)
{
ShowHelpText();
g_rectangle = Rect(-1, -1, 0, 0);
Mat srcImage(600, 800, CV_8UC3), tempImage;
srcImage.copyTo(tempImage);
srcImage = Scalar::all(0);
namedWindow(WINDOW_NAME);
setMouseCallback(WINDOW_NAME, on_MouseHandle, (void*)&srcImage);
while(1) {
srcImage.copyTo(tempImage);
if(g_bDrawingBox)
DrawRectangle(tempImage, g_rectangle);
imshow(WINDOW_NAME, tempImage);
if(waitKey(10) == 27)
break;
}
return 0;
}
void on_MouseHandle(int event, int x, int y, int flags, void* param)
{
Mat& image = *(cv::Mat*) param;
switch(event)
{
case EVENT_MOUSEMOVE:
{
if(g_bDrawingBox)
{
g_rectangle.width = x - g_rectangle.x;
g_rectangle.height = y - g_rectangle.y;
}
}
break;
case EVENT_LBUTTONDOWN:
{
g_bDrawingBox = true;
g_rectangle = Rect(x, y, 0, 0);
}
break;
case EVENT_LBUTTONUP:
{
g_bDrawingBox = false;
if(g_rectangle.width < 0)
{
g_rectangle.x += g_rectangle.width;
g_rectangle.width *= -1;
}
if(g_rectangle.height < 0)
{
g_rectangle.y += g_rectangle.height;
g_rectangle.height *= -1;
}
DrawRectangle( image, g_rectangle);
}
break;
}
}
void DrawRectangle(cv::Mat& img, cv::Rect box)
{
rectangle(img, box.tl(), box.br(), Scalar(g_rng.uniform(0, 255), g_rng.uniform(0,255), g_rng.uniform(0,255)));
}
void ShowHelpText()
{
printf("\n\n\n\t*************\n");
printf("\n\n\t鼠标事件\n");
}
CMakeLists.txt:同上 实现效果:
|