这一章主要完成了两个实例应用:
1.鼠标截图程序
2.滑动条视频播放程序
代码1:鼠标截图程序
///鼠标截图功能
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
Mat img = imread("1.jpg",CV_LOAD_IMAGE_COLOR);
Mat temp = img.clone(); //Mat类型变量temp深拷贝原图
Mat ROI;//设置感兴趣区域ROI
Point pt;//记录鼠标左键按下时的坐标
bool flag = false;flag用来标记鼠标移动是否画矩形
///鼠标消息回调函数
//逻辑:逻辑:左键按下,记录位置;鼠标移动,画矩形;左键抬起,鼠标移动不再画矩形,显示ROI,保存ROI。
void OnMouse(int event, int x, int y, int flags, void* param)
{
switch(event)
{
case CV_EVENT_LBUTTONDOWN: //鼠标左键按下
//cout<<"left button down"<<endl;
flag = true;//flag标记置为真,触发鼠标移动画矩形
pt.x = x; //记录当前点坐标
pt.y = y;
break;
case CV_EVENT_MOUSEMOVE: //鼠标移动
//cout<<"mouse move"<<endl;
if(flag)
{
temp.copyTo(img);//通过temp将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;//flag标记置为假,关闭鼠标移动画矩形
ROI = temp(Rect(pt.x, pt.y, x-pt.x, y-pt.y)); //确定ROI区域
imshow("ROI", ROI); //显示ROI
imwrite("ROI.bmp", ROI);//保存ROI
break;
default:
break;
}
}
void main()
{
namedWindow("Mouse", CV_WINDOW_AUTOSIZE);
setMouseCallback("Mouse", OnMouse, 0); //设置鼠标回调函数
while(1)
{
imshow("Mouse", img); //每10ms刷新一次图像,不在onMouse()里显示图像,因为太快会有拖动重影
if(27 == waitKey(10)) //Esc跳出循环
break;
}
}
运行结果:
代码2:滑动条视频播放程序
///滑动条视频播放程序
//逻辑:VideoCapture类播放每一帧图像(同原本FPS一样),通过视频帧位置,来设置滑动条位置(setTrackbarPos()),
//通过滑动块位置,来设置视频帧位置(cap.set())
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
double Fps; //double类型变量保存帧率
int value;//记录滑动块位置
int framePos; //记录视频帧位置
void OnChange(int , void* param)
{
VideoCapture cap = *(VideoCapture*)param;
cap.set(CV_CAP_PROP_POS_FRAMES, value); //通过滑动块位置,来设置视频帧位置
}
void main()
{
char strFps[20]; //存储帧率字符串
Mat frame;
VideoCapture cap("1.avi");
if(!cap.isOpened()) //打开视频失败
return;
int FrameCount = cap.get(CV_CAP_PROP_FRAME_COUNT); //获取视频总帧数
namedWindow("Video", CV_WINDOW_AUTOSIZE);
createTrackbar("Frame", "Video", &value, FrameCount, OnChange, &cap);//创建滑动条
Fps = cap.get(CV_CAP_PROP_FPS); //获取视频帧率
sprintf(strFps, "Fps:%0.1f/s", Fps); //格式化字符串
while(1)
{
framePos = cap.get(CV_CAP_PROP_POS_FRAMES); //获取视频帧位置
setTrackbarPos("Frame", "Video", framePos); //通过视频帧位置,来设置滑动条位置
cap>>frame;//取帧给frame
if(frame.empty()) //取帧失败
break;
putText(frame, strFps, Point(5, 30), CV_FONT_HERSHEY_COMPLEX_SMALL, 1, Scalar(0, 255, 0), 1, 8);
imshow("Video", frame);
//waitKey(10);//10毫秒显示一帧
if(27 == waitKey(1000/Fps) ) //经过换算,每(1000/Fps)显示一帧,与原视频FPS一样。且Esc控制跳出循环退出
break;
}
cap.release(); //资源释放
destroyAllWindows();//销毁窗口
}
运行结果: