读取视频
VideoCapture cap;
//视频路径
cap.open("test.mp4");
//如果视频不能正常打开则返回
if (!cap.isOpened())
{
cout << "cannot open video!" << endl;
return 0;
}
Mat frame_key;
cap >> frame_key;
//定义当前帧 frame_key=currentFrame
long currentFrame = 1;
if (frame_key.empty())
cout << "frame_key is empty!" << endl;
//显示视频
imshow("fram_1", frame_key);
waitKey(20);
//把第一帧写入关键帧
stringstream str;
str << "./keyframe/" << currentFrame << ".jpg";
imwrite(str.str(), frame_key);
定义一个循环,使得前一帧和当前帧进行对比
while (1)
{
//定义后一帧 frame=currentFrame+1
currentFrame++;
Mat frame;
cap >> frame;
if (frame.empty())
{
//cout << "frame is empty!" << endl;
break;
}
waitKey(20);
Mat srcImage_base;
Mat srcImage_test1;
srcImage_base = frame_key;
srcImage_test1 = frame;
Mat previousImage, currentImage, resultImage;
//将图像从BGR色彩空间转换到 HSV色彩空间
cvtColor(srcImage_base, previousImage, COLOR_BGR2GRAY);
cvtColor(srcImage_test1, currentImage, COLOR_BGR2GRAY);
//帧差法,相减
absdiff(currentImage, previousImage, resultImage);
//二值化,像素值相差大于20则置为255,其余为0。可以通过改变像素差值来调整视频关键帧
threshold(resultImage, resultImage, 10, 255.0, THRESH_BINARY);
float counter = 0, num = 0;
// 统计两帧相减后图像素
for (int i = 0; i < resultImage.rows; i++)
{
//获取每一行的指针
uchar *data = resultImage.ptr<uchar>(i);
for (int j = 0; j < resultImage.cols; j++)
{
//计算总像素个数
num = num + 1;
//访问到像素值
if (data[j] == 255)
{
//计算像素值变化的像素个数
counter = counter + 1;
}
}
}
//p设置的阈值
float p;
p = counter / num;
//阈值大于0.55是关键帧
if (p > 0.55)
{
frame_key = frame;
cout << "正在写第" << currentFrame << "帧" << endl;
//写入关键帧
stringstream str;
str << "./keyframe/" << currentFrame << ".jpg";
imwrite(str.str(), frame_key);
}
}