opencv(7)----实例应用2

本文介绍了一个鼠标截图程序,通过鼠标操作实现截图功能,并详细解释了鼠标事件处理的代码实现。此外,还介绍了一款视频播放程序,该程序能够通过滑动条实时显示视频帧位置和帧率,并允许用户通过拖动滑动条来调整播放进度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

鼠标截图程序

主要功能

鼠标左键按下拖动显示轨迹,鼠标左键弹起显示截图并保存截图到本地

代码实现

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(){

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值