提交 aca97817 编写于 作者: G gineshidalgo99

Video can be recorded from images

上级 a35999f5
......@@ -289,7 +289,8 @@ OpenPose Library - Release Notes
19. All bash scripts incorporate `#!/bin/bash` to tell the terminal that they are bash scripts.
20. Added flag `--verbose` to plot the progress.
21. Added find_package(Protobuf) to allow specific versions of Protobuf.
22. Examples do not end in core dumped if an OpenPose exception occurred, but it is rather closed returning -1.
22. Examples do not end in core dumped if an OpenPose exception occurred during initialization, but it is rather closed returning -1. However, it will still results in core dumped if the exception occurs during multi-threading execution.
23. Video (`--write_video`) can be generated from images (`--image_dir`), as long as they maintain the same resolution.
2. Functions or parameters renamed:
1. By default, python example `tutorial_developer/python_2_pose_from_heatmaps.py` was using 2 scales starting at -1x736, changed to 1 scale at -1x368.
2. WrapperStructPose default parameters changed to match those of the OpenPose demo binary.
......
......@@ -10,7 +10,7 @@ namespace op
class OP_API VideoSaver
{
public:
VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps, const Point<int>& cvSize);
VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps);
virtual ~VideoSaver();
......@@ -24,7 +24,8 @@ namespace op
const std::string mVideoSaverPath;
const int mCvFourcc;
const double mFps;
const Point<int> mCvSize;
Point<int> mCvSize;
bool mVideoStarted;
cv::VideoWriter mVideoWriter;
unsigned int mNumberImages;
......
......@@ -651,7 +651,7 @@ namespace op
if (!wrapperStructOutput.writeVideo.empty() || !wrapperStructOutput.writeBvh.empty())
{
if (wrapperStructOutput.writeVideoFps <= 0
&& (producerSharedPtr == nullptr || producerSharedPtr->get(CV_CAP_PROP_FPS) <= 0))
&& (!oPProducer || producerSharedPtr->get(CV_CAP_PROP_FPS) <= 0))
error("The frame rate of the frames producer is unknown. Set `--write_video_fps` to your desired"
" FPS if you wanna record video (`--write_video`). E.g., if it is a folder of images, you"
" will have to know or guess the frame rate; if it is a webcam, you should use the OpenPose"
......@@ -666,12 +666,8 @@ namespace op
error("Video file can only be recorded inside `wrapper/wrapper.hpp` if the producer"
" is one of the default ones (e.g., video, webcam, ...).",
__LINE__, __FUNCTION__, __FILE__);
if (finalOutputSize.x <= 0 || finalOutputSize.y <= 0)
error("Video can only be recorded if outputSize is fixed (e.g., video, webcam, IP camera),"
" but not for a image directory.", __LINE__, __FUNCTION__, __FILE__);
const auto videoSaver = std::make_shared<VideoSaver>(
wrapperStructOutput.writeVideo, CV_FOURCC('M','J','P','G'), originalVideoFps, finalOutputSize
);
wrapperStructOutput.writeVideo, CV_FOURCC('M','J','P','G'), originalVideoFps);
outputWs.emplace_back(std::make_shared<WVideoSaver<TDatumsSP>>(videoSaver));
}
// Write joint angles as *.bvh file on hard disk
......
......@@ -3,11 +3,26 @@
namespace op
{
cv::VideoWriter openVideo(const std::string& videoSaverPath, const int cvFourcc, const double fps,
const Point<int>& cvSize, const int numberImages)
const Point<int>& cvSize)
{
try
{
return cv::VideoWriter{videoSaverPath, cvFourcc, fps, cv::Size{numberImages*cvSize.x, cvSize.y}};
// Open video
const cv::VideoWriter videoWriter{
videoSaverPath, cvFourcc, fps, cv::Size{cvSize.x, cvSize.y}};
// Check it was successfully opened
if (!videoWriter.isOpened())
{
const std::string errorMessage{
"Video to write frames could not be opened as `" + videoSaverPath + "`. Please, check that:"
"\n\t1. The path ends in `.avi`.\n\t2. The parent folder exists.\n\t3. OpenCV is properly"
" compiled with the FFmpeg codecs in order to save video."
"\n\t4. You are not saving in a protected folder. If you desire to save a video in a"
" protected folder, use sudo (Ubuntu) or execute the binary file as administrator (Windows)."};
error(errorMessage, __LINE__, __FUNCTION__, __FILE__);
}
// Return video
return videoWriter;
}
catch (const std::exception& e)
{
......@@ -16,32 +31,17 @@ namespace op
}
}
VideoSaver::VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps,
const Point<int>& cvSize) :
VideoSaver::VideoSaver(const std::string& videoSaverPath, const int cvFourcc, const double fps) :
mVideoSaverPath{videoSaverPath},
mCvFourcc{cvFourcc},
mFps{fps},
mCvSize{cvSize},
mNumberImages{1}
mVideoStarted{false}
{
try
{
// Sanity checks
if (cvSize.x <= 0 || cvSize.y <= 0)
error("Desired frame size to save the video is <= 0.", __LINE__, __FUNCTION__, __FILE__);
// Sanity check
if (fps <= 0.)
error("Desired fps (frame rate) to save the video is <= 0.", __LINE__, __FUNCTION__, __FILE__);
// Open video-writter
mVideoWriter = openVideo(mVideoSaverPath, mCvFourcc, mFps, mCvSize, mNumberImages);
// Check it was successfully opened
if (!mVideoWriter.isOpened())
{
const std::string errorMessage{"Video to write frames could not be opened as `" + videoSaverPath
+ "`. Please, check that:\n\t1. The path ends in `.avi`."
"\n\t2. The parent folder exists.\n\t3. OpenCV is properly"
" compiled with the FFmpeg codecs in order to save video."};
error(errorMessage, __LINE__, __FUNCTION__, __FILE__);
}
}
catch (const std::exception& e)
{
......@@ -82,23 +82,33 @@ namespace op
{
try
{
// Sanity checks
if (!isOpened())
error("Video to write frames is not opened.", __LINE__, __FUNCTION__, __FILE__);
// Sanity check
if (cvMats.empty())
error("The image(s) to be saved cannot be empty.", __LINE__, __FUNCTION__, __FILE__);
// Re-shape video writer if required
if (mNumberImages != cvMats.size())
// Open video (1st frame)
// Done here and not in the constructor to handle cases where the resolution is not known (e.g.,
// reading images or multiple cameras)
if (!mVideoStarted)
{
mNumberImages = (unsigned int)cvMats.size();
mVideoWriter = openVideo(mVideoSaverPath, mCvFourcc, mFps, mCvSize, mNumberImages);
mVideoStarted = true;
const auto cvSize = cvMats.at(0).size();
mCvSize = Point<int>{(int)cvMats.size()*cvSize.width, cvSize.height};
mVideoWriter = openVideo(mVideoSaverPath, mCvFourcc, mFps, mCvSize);
}
// Sanity check
if (!isOpened())
error("Video to write frames is not opened.", __LINE__, __FUNCTION__, __FILE__);
// Concat images
cv::Mat cvOutputData;
if (cvMats.size() > 1)
cv::hconcat(cvMats.data(), cvMats.size(), cvOutputData);
else
cvOutputData = cvMats.at(0);
// Sanity check
if (mCvSize.x != cvOutputData.cols || mCvSize.y != cvOutputData.rows)
error("You selected to write video (`--write_video`), but the frames to be saved have different"
" resolution. You can only save frames with the same resolution.",
__LINE__, __FUNCTION__, __FILE__);
// Save concatenated image
mVideoWriter.write(cvOutputData);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册