鼠标截图程序
主要功能
鼠标左键按下拖动显示轨迹,鼠标左键弹起显示截图并保存截图到本地
代码实现
mainwindow.cpp
Mat img=imread("D:\\1\\1.png");
Mat temp;
temp=img.clone();
bool flag=false;
//鼠标消息回调函数
void OnMouse(int event, int x, int y, int flag, void* param)
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN: //鼠标左键按下
//cout<<"left button down"<<endl;
flag = true;
pt.x = x;
pt.y = y;
break;
case CV_EVENT_MOUSEMOVE: //鼠标移动
//cout<<"mouse move"<<endl;
if(flag)
{
temp.copyTo(img);
rectangle(img, pt, Point(x, y), Scalar(0, 255, 0), 2, 8);
}
break;
case CV_EVENT_LBUTTONUP: //鼠标左键弹起
//cout<<"left button up"<<endl;
flag = false;
ROI = temp(Rect(pt.x, pt.y, x-pt.x, y-pt.y)); //确定ROI区域
imshow("ROI", ROI);
imwrite("ROI.bmp", ROI);
break;
default:
break;
}
}
void main(){
//鼠标截图功能
namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
setMouseCallback("Mouse", OnMouse, 0); //设置鼠标回调函数
while(1)
{
imshow("Mouse", img);
if(27 == waitKey(10)) //Esc跳出循环
break;
}
}
知识点详解
1.处理鼠标事件的通用代码
//鼠标消息回调函数
void OnMouse(int event, int x, int y, int flag, void* param)
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN: //鼠标左键按下
cout<<"left button down"<<endl;
pt.x = x;
pt.y = y;
.....................
break;
case CV_EVENT_MOUSEMOVE: //鼠标移动
cout<<"mouse move"<<endl;
.....................
break;
case CV_EVENT_LBUTTONUP: //鼠标左键弹起
cout<<"left button up"<<endl;
....................
break;
default:
break;
}
}
void main(){
//鼠标截图功能
namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
setMouseCallback("Mouse", OnMouse, 0); //设置鼠标回调函数
while(1)
{
imshow("Mouse", img);
if(27 == waitKey(10)) //Esc跳出循环
break;
}
}
2. 使用按键事件时,必须将显示窗口放在while循环中
while(1)
{
imshow("Mouse", img);
if(27 == waitKey(10)) //Esc跳出循环
break;
}
但是,在滑动条事件中,无须使用while循环
3. 设置满足要求函数
Mat img=imread("D:\\1\\1.png");
Mat temp;
temp=img.clone();
bool flag=false;
//鼠标消息回调函数
void OnMouse(int event, int x, int y, int flag, void* param)
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN: //鼠标左键按下
//cout<<"left button down"<<endl;
flag = true;
pt.x = x;
pt.y = y;
break;
case CV_EVENT_MOUSEMOVE: //鼠标移动
//cout<<"mouse move"<<endl;
if(flag)
{
temp.copyTo(img);
rectangle(img, pt, Point(x, y), Scalar(0, 255, 0), 2, 8);
}
break;
case CV_EVENT_LBUTTONUP: //鼠标左键弹起
//cout<<"left button up"<<endl;
flag = false;
ROI = temp(Rect(pt.x, pt.y, x-pt.x, y-pt.y)); //确定ROI区域
imshow("ROI", ROI);
imwrite("ROI.bmp", ROI);
break;
default:
break;
}
}
4.
ROI = temp(Rect(pt.x, pt.y, x-pt.x, y-pt.y)); //确定ROI区域
之所以使用temp而不使用img
img是已经被绘制过矩形框的图像,temp是原图
temp(Rect(..,..))
可以用于获取一幅图像中的一部分
滑动条视频播放程序
主要功能
视频播放时,滑动条同时显示播放帧的位置和视频帧率,滑动条拖动时可以实现同步指定帧播放
代码实现
#include "mainwindow.h"
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int value;
int framePos;
/*将帧的位置设置为滑动条拖动的位置*/
void onChange(int ,void *param){
VideoCapture cap=*(VideoCapture*)param;
cap.set(CV_CAP_PROP_POS_FRAMES,value);//设置视频帧位置
}
MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
VideoCapture cap;
Mat frame;
char strFPS[20];
cap.open("D:\\1.avi");
if(!cap.isOpened()){
cout<<"open false"<<endl;
return;
}
int totalFrame=cap.get(CAP_PROP_FRAME_COUNT);//获取总帧数
int FPS=cap.get(CAP_PROP_FPS);//获取速率
sprintf(strFPS,"Fps:%d",FPS);//格式化字符串
namedWindow("Video",CV_WINDOW_AUTOSIZE);
createTrackbar("FRAME","Video",&value,totalFrame,onChange,&cap);
cout<<FPS<<endl;
while(1){
//控制视频播放时trackbar的位置
framePos=cap.get(CV_CAP_PROP_POS_FRAMES);//获取当前视频帧位置
setTrackbarPos("FRAME","Video",framePos);//设置滑动条位置
getTrackbarPos()
cap.read(frame);
if(frame.empty()){
break;
}
putText(frame,strFPS,Point(5,30),CV_FONT_HERSHEY_COMPLEX_SMALL,1,Scalar(255,255,255),2,8);
imshow("Video",frame);
if(waitKey(1000/FPS)==27){
break;
}
}
cap.release();
destroyAllWindows();
}
MainWindow::~MainWindow(){
}