mirror of
https://github.com/gosticks/openpose.git
synced 2026-08-16 06:10:25 +00:00
Camera warning if unplugged
This commit is contained in:
@@ -264,6 +264,7 @@ OpenPose Library - Release Notes
|
||||
1. Added initial single-person tracker for further speed up or visual smoothing (`--tracking` flag).
|
||||
2. Greedy body part connector implemented in CUDA: +~30% speed up in Nvidia (CUDA) version with default flags and +~10% in maximum accuracy configuration. In addition, it provides a small 0.2% boost in accuracy (default flags).
|
||||
3. OpenPose can be built as Unity plugin: Added flag `BUILD_UNITY_SUPPORT` and special Unity code.
|
||||
4. If camera is unplugged, OpenPose GUI and command line will display a warning and try to reconnect it.
|
||||
2. Functions or parameters renamed:
|
||||
1. By default, python example `2_pose_from_heatmaps.py` was using 2 scales starting at -1x736, changed to 1 scale at -1x368.
|
||||
3. Main bugs fixed:
|
||||
|
||||
@@ -26,6 +26,11 @@ namespace op
|
||||
|
||||
std::string getNextFrameName();
|
||||
|
||||
inline bool isOpened() const
|
||||
{
|
||||
return VideoCaptureReader::isOpened();
|
||||
}
|
||||
|
||||
inline double get(const int capProperty)
|
||||
{
|
||||
return VideoCaptureReader::get(capProperty);
|
||||
|
||||
@@ -36,10 +36,7 @@ namespace op
|
||||
|
||||
virtual std::string getNextFrameName() = 0;
|
||||
|
||||
inline bool isOpened() const
|
||||
{
|
||||
return mVideoCapture.isOpened();
|
||||
}
|
||||
virtual bool isOpened() const = 0;
|
||||
|
||||
void release();
|
||||
|
||||
@@ -52,6 +49,8 @@ namespace op
|
||||
|
||||
virtual std::vector<cv::Mat> getRawFrames() = 0;
|
||||
|
||||
void resetWebcam(const int index, const bool throwExceptionIfNoOpened);
|
||||
|
||||
private:
|
||||
cv::VideoCapture mVideoCapture;
|
||||
|
||||
|
||||
@@ -34,6 +34,11 @@ namespace op
|
||||
|
||||
std::string getNextFrameName();
|
||||
|
||||
inline bool isOpened() const
|
||||
{
|
||||
return VideoCaptureReader::isOpened();
|
||||
}
|
||||
|
||||
double get(const int capProperty);
|
||||
|
||||
void set(const int capProperty, const double value);
|
||||
|
||||
@@ -37,11 +37,14 @@ namespace op
|
||||
|
||||
std::string getNextFrameName();
|
||||
|
||||
bool isOpened() const;
|
||||
|
||||
double get(const int capProperty);
|
||||
|
||||
void set(const int capProperty, const double value);
|
||||
|
||||
private:
|
||||
const int mIndex;
|
||||
double mFps;
|
||||
long long mFrameNameCounter;
|
||||
bool mThreadOpened;
|
||||
@@ -49,6 +52,10 @@ namespace op
|
||||
std::mutex mBufferMutex;
|
||||
std::atomic<bool> mCloseThread;
|
||||
std::thread mThread;
|
||||
// Detect camera unplugged
|
||||
double mLastNorm;
|
||||
std::atomic<int> mDisconnectedCounter;
|
||||
Point<int> mResolution;
|
||||
|
||||
cv::Mat getRawFrame();
|
||||
|
||||
@@ -56,6 +63,8 @@ namespace op
|
||||
|
||||
void bufferingThread();
|
||||
|
||||
bool reset();
|
||||
|
||||
DELETE_COPY(WebcamReader);
|
||||
};
|
||||
}
|
||||
|
||||
@@ -184,9 +184,14 @@ namespace op
|
||||
mNumberEmptyFrames = 0;
|
||||
|
||||
if (mType != ProducerType::ImageDirectory
|
||||
&& (frame.cols != get(CV_CAP_PROP_FRAME_WIDTH) || frame.rows != get(CV_CAP_PROP_FRAME_HEIGHT)))
|
||||
&& ((frame.cols != get(CV_CAP_PROP_FRAME_WIDTH) && get(CV_CAP_PROP_FRAME_WIDTH) > 0)
|
||||
|| (frame.rows != get(CV_CAP_PROP_FRAME_HEIGHT)) && get(CV_CAP_PROP_FRAME_HEIGHT) > 0))
|
||||
{
|
||||
log("Frame size changed. Returning empty frame.", Priority::Max, __LINE__, __FUNCTION__, __FILE__);
|
||||
log("Frame size changed. Returning empty frame.\nExpected vs. received sizes: "
|
||||
+ std::to_string(get(CV_CAP_PROP_FRAME_WIDTH))
|
||||
+ "x" + std::to_string(get(CV_CAP_PROP_FRAME_HEIGHT))
|
||||
+ " vs. " + std::to_string(frame.cols) + "x" + std::to_string(frame.rows),
|
||||
Priority::Max, __LINE__, __FUNCTION__, __FILE__);
|
||||
frame = cv::Mat();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,11 @@
|
||||
namespace op
|
||||
{
|
||||
VideoCaptureReader::VideoCaptureReader(const int index, const bool throwExceptionIfNoOpened) :
|
||||
Producer{ProducerType::Webcam},
|
||||
mVideoCapture{index}
|
||||
Producer{ProducerType::Webcam}
|
||||
{
|
||||
try
|
||||
{
|
||||
// Make sure video capture was opened
|
||||
if (throwExceptionIfNoOpened && !isOpened())
|
||||
error("VideoCapture (webcam) could not be opened.", __LINE__, __FUNCTION__, __FILE__);
|
||||
resetWebcam(index, throwExceptionIfNoOpened);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
@@ -68,6 +65,19 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
bool VideoCaptureReader::isOpened() const
|
||||
{
|
||||
try
|
||||
{
|
||||
return mVideoCapture.isOpened();
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat VideoCaptureReader::getRawFrame()
|
||||
{
|
||||
try
|
||||
@@ -96,6 +106,22 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCaptureReader::resetWebcam(const int index, const bool throwExceptionIfNoOpened)
|
||||
{
|
||||
try
|
||||
{
|
||||
// Open webcam
|
||||
mVideoCapture = cv::VideoCapture{index};
|
||||
// Make sure video capture was opened
|
||||
if (throwExceptionIfNoOpened && !isOpened())
|
||||
error("VideoCapture (webcam) could not be opened.", __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
void VideoCaptureReader::release()
|
||||
{
|
||||
try
|
||||
|
||||
@@ -1,36 +1,43 @@
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <openpose/producer/webcamReader.hpp>
|
||||
#include <openpose/utilities/fastMath.hpp>
|
||||
#include <openpose/utilities/openCv.hpp>
|
||||
#include <openpose/producer/webcamReader.hpp>
|
||||
|
||||
namespace op
|
||||
{
|
||||
WebcamReader::WebcamReader(const int webcamIndex, const Point<int>& webcamResolution, const double fps,
|
||||
const bool throwExceptionIfNoOpened) :
|
||||
VideoCaptureReader{webcamIndex, throwExceptionIfNoOpened},
|
||||
mIndex{webcamIndex},
|
||||
mFps{fps},
|
||||
mFrameNameCounter{-1},
|
||||
mThreadOpened{false}
|
||||
mThreadOpened{std::atomic<bool>{false}},
|
||||
mResolution{webcamResolution}
|
||||
{
|
||||
try
|
||||
{
|
||||
if (isOpened())
|
||||
{
|
||||
mFrameNameCounter = 0;
|
||||
if (webcamResolution != Point<int>{})
|
||||
if (mResolution != Point<int>{})
|
||||
{
|
||||
set(CV_CAP_PROP_FRAME_WIDTH, webcamResolution.x);
|
||||
set(CV_CAP_PROP_FRAME_HEIGHT, webcamResolution.y);
|
||||
if ((int)get(CV_CAP_PROP_FRAME_WIDTH) != webcamResolution.x
|
||||
|| (int)get(CV_CAP_PROP_FRAME_HEIGHT) != webcamResolution.y)
|
||||
set(CV_CAP_PROP_FRAME_WIDTH, mResolution.x);
|
||||
set(CV_CAP_PROP_FRAME_HEIGHT, mResolution.y);
|
||||
if ((int)get(CV_CAP_PROP_FRAME_WIDTH) != mResolution.x
|
||||
|| (int)get(CV_CAP_PROP_FRAME_HEIGHT) != mResolution.y)
|
||||
{
|
||||
const std::string logMessage{ "Desired webcam resolution " + std::to_string(webcamResolution.x)
|
||||
+ "x" + std::to_string(webcamResolution.y)
|
||||
+ " could not being set. Final resolution: "
|
||||
+ std::to_string(intRound(get(CV_CAP_PROP_FRAME_WIDTH))) + "x"
|
||||
+ std::to_string(intRound(get(CV_CAP_PROP_FRAME_HEIGHT))) };
|
||||
const std::string logMessage{
|
||||
"Desired webcam resolution " + std::to_string(mResolution.x) + "x"
|
||||
+ std::to_string(mResolution.y) + " could not being set. Final resolution: "
|
||||
+ std::to_string(intRound(get(CV_CAP_PROP_FRAME_WIDTH))) + "x"
|
||||
+ std::to_string(intRound(get(CV_CAP_PROP_FRAME_HEIGHT))) };
|
||||
log(logMessage, Priority::Max, __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
}
|
||||
// Set resolution
|
||||
mResolution = Point<int>{
|
||||
intRound(get(CV_CAP_PROP_FRAME_WIDTH)),
|
||||
intRound(get(CV_CAP_PROP_FRAME_HEIGHT))};
|
||||
// Start buffering thread
|
||||
mThreadOpened = true;
|
||||
mThread = std::thread{&WebcamReader::bufferingThread, this};
|
||||
@@ -111,6 +118,19 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
bool WebcamReader::isOpened() const
|
||||
{
|
||||
try
|
||||
{
|
||||
return (VideoCaptureReader::isOpened() || mDisconnectedCounter > 0);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
double WebcamReader::get(const int capProperty)
|
||||
{
|
||||
try
|
||||
@@ -194,6 +214,7 @@ namespace op
|
||||
}
|
||||
}
|
||||
|
||||
const auto DISCONNETED_THRESHOLD = 15;
|
||||
void WebcamReader::bufferingThread()
|
||||
{
|
||||
try
|
||||
@@ -201,8 +222,29 @@ namespace op
|
||||
mCloseThread = false;
|
||||
while (!mCloseThread)
|
||||
{
|
||||
// Reset camera if disconnected
|
||||
bool cameraConnected = true;
|
||||
if (mDisconnectedCounter > DISCONNETED_THRESHOLD)
|
||||
cameraConnected = reset();
|
||||
// Get frame
|
||||
auto cvMat = VideoCaptureReader::getRawFrame();
|
||||
// Detect whether camera is connected
|
||||
const auto newNorm = (
|
||||
cvMat.empty() ? mLastNorm : cv::norm(cvMat.row(cvMat.rows/2)));
|
||||
if (mLastNorm == newNorm)
|
||||
mDisconnectedCounter++;
|
||||
else
|
||||
{
|
||||
mLastNorm = newNorm;
|
||||
mDisconnectedCounter = 0;
|
||||
}
|
||||
// Camera disconnected: black image
|
||||
if (!cameraConnected || cvMat.empty())
|
||||
{
|
||||
cvMat = cv::Mat(mResolution.y, mResolution.x, CV_8UC3, cv::Scalar{0,0,0});
|
||||
putTextOnCvMat(cvMat, "Camera disconnected, reconnecting...", {cvMat.cols/16, cvMat.rows/2},
|
||||
cv::Scalar{255, 255, 255}, false, 2.3*cvMat.cols);
|
||||
}
|
||||
// Move to buffer
|
||||
if (!cvMat.empty())
|
||||
{
|
||||
@@ -216,4 +258,33 @@ namespace op
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
}
|
||||
}
|
||||
|
||||
bool WebcamReader::reset()
|
||||
{
|
||||
try
|
||||
{
|
||||
// If unplugged
|
||||
log("Webcam was unplugged, trying to reconnect it.", Priority::Max,
|
||||
__LINE__, __FUNCTION__, __FUNCTION__);
|
||||
// Sleep
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds{1000});
|
||||
// Reset camera
|
||||
VideoCaptureReader::resetWebcam(mIndex, false);
|
||||
// Re-set resolution
|
||||
if (isOpened())
|
||||
{
|
||||
set(CV_CAP_PROP_FRAME_WIDTH, mResolution.x);
|
||||
set(CV_CAP_PROP_FRAME_HEIGHT, mResolution.y);
|
||||
}
|
||||
// Camera replugged?
|
||||
return (!isOpened()
|
||||
&& (mResolution.x != intRound(get(CV_CAP_PROP_FRAME_WIDTH))
|
||||
|| mResolution.y != intRound(get(CV_CAP_PROP_FRAME_HEIGHT))));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
error(e.what(), __LINE__, __FUNCTION__, __FILE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user