camerabase done

This commit is contained in:
AiYangSky 2023-12-19 18:44:25 +08:00
parent dd3216e19e
commit a0d3e258d9
4 changed files with 478 additions and 0 deletions

79
include/sv_camera.h Normal file
View File

@ -0,0 +1,79 @@
#ifndef __SV_CAMERA__
#define __SV_CAMERA__
#include "opencv2/opencv.hpp"
namespace sv
{
enum class CameraType : int
{
// 未知相机
NONE = 0X00001000,
// 标准opencv框架下的相机
WEBCAM = 0X00001001,
V4L2CAM = 0X00001002,
// 视频文件
VIDEOFILE = 0X00002001,
// 普通流媒体相机
STREAMING = 0X00004001,
// 普通的MIPI-CSI相机
MIPI = 0X00008001,
// 进行了传输优化适配的相机
G1 = 0X00010001,
Q10 = 0X00010002,
GX40 = 0X00010003,
MC1 = 0X00010004,
// 虚拟的相机设备 主要仿真接入
VIRTUAL = 0X00020001,
};
class Camera
{
private:
void *dev;
public:
// 构建时根据相机类型实例化对应的相机类
// timeOut: 相机连接超时时间;超过该时间没有读取到新的帧,则认为相机失去连接 单位ms
Camera(CameraType type, int timeOut = 500);
// 基本配置 必须调用下述的一个接口后才能open
bool setStream(const std::string &ip, int port);
bool setName(const std::string &name);
bool setIndex(int index);
// 基础功能
bool open(void);
bool read(cv::Mat &image);
bool readNoBlock(cv::Mat &image);
void release(void);
// 属性配置
void setWH(int width, int height);
void setFps(int fps);
void setBrightness(double brightness);
void setContrast(double contrast);
void setSaturation(double saturation);
void setHue(double hue);
void setExposure(double exposure);
// 获取属性
bool isActive(void);
CameraType getType(void);
std::string getName(void);
int getW(void);
int getH(void);
int getExpectFps(void);
double getFps(void);
double getBrightness(void);
double getContrast(void);
double getSaturation(void);
double getHue(void);
double getExposure(void);
~Camera();
};
}
#endif

179
video_io/sv_camera.cpp Normal file
View File

@ -0,0 +1,179 @@
#include "sv_camera_privately.h"
#include "sv_camera.h"
#include <map>
#include <iterator>
typedef sv_p::CameraBase *(*cameraCreat)(int timeOut);
static std::map<sv::CameraType, cameraCreat> svCameraList =
{
{sv::CameraType::NONE, nullptr},
{sv::CameraType::WEBCAM, nullptr},
{sv::CameraType::V4L2CAM, nullptr},
{sv::CameraType::VIDEOFILE, nullptr},
{sv::CameraType::STREAMING, nullptr},
{sv::CameraType::MIPI, nullptr},
{sv::CameraType::G1, nullptr},
{sv::CameraType::Q10, nullptr},
{sv::CameraType::GX40, nullptr},
{sv::CameraType::MC1, nullptr},
{sv::CameraType::VIRTUAL, nullptr}};
static sv_p::CameraBase *svCreatCamera(sv::CameraType type, int timeOut)
{
std::map<sv::CameraType, cameraCreat>::iterator temp = svCameraList.find(type);
if (temp != svCameraList.end())
{
return temp->second(timeOut);
}
return nullptr;
}
sv::Camera::Camera(CameraType type, int timeOut)
{
this->dev = svCreatCamera(type,timeOut);
}
sv::Camera::~Camera()
{
// 休眠50ms 以便能退出线程
std::this_thread::sleep_for(std::chrono::milliseconds(50));
delete (sv_p::CameraBase *)dev;
}
sv_p::CameraBase::~CameraBase()
{
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
readThreadHandle = readThreadHandle == 0 ? 0 : pthread_cancel(readThreadHandle);
release();
}
bool sv::Camera::setStream(const std::string &ip, int port)
{
return ((sv_p::CameraBase *)dev)->setStream(ip, port);
}
bool sv::Camera::setName(const std::string &name)
{
return ((sv_p::CameraBase *)dev)->setName(name);
}
bool sv::Camera::setIndex(int index)
{
return ((sv_p::CameraBase *)dev)->setIndex(index);
}
bool sv::Camera::open(void)
{
return ((sv_p::CameraBase *)dev)->open();
}
bool sv::Camera::read(cv::Mat &image)
{
return ((sv_p::CameraBase *)dev)->read(image);
}
bool sv::Camera::readNoBlock(cv::Mat &image)
{
return ((sv_p::CameraBase *)dev)->readNoBlock(image);
}
void sv::Camera::release(void)
{
((sv_p::CameraBase *)dev)->release();
}
void sv::Camera::setWH(int width, int height)
{
((sv_p::CameraBase *)dev)->setWH(width, height);
}
void sv::Camera::setFps(int fps)
{
((sv_p::CameraBase *)dev)->setFps(fps);
}
void sv::Camera::setBrightness(double brightness)
{
((sv_p::CameraBase *)dev)->setBrightness(brightness);
}
void sv::Camera::setContrast(double contrast)
{
((sv_p::CameraBase *)dev)->setContrast(contrast);
}
void sv::Camera::setSaturation(double saturation)
{
((sv_p::CameraBase *)dev)->setSaturation(saturation);
}
void sv::Camera::setHue(double hue)
{
((sv_p::CameraBase *)dev)->setHue(hue);
}
void sv::Camera::setExposure(double exposure)
{
((sv_p::CameraBase *)dev)->setExposure(exposure);
}
bool sv::Camera::isActive(void)
{
return ((sv_p::CameraBase *)dev)->isActive();
}
sv::CameraType sv::Camera::getType(void)
{
return ((sv_p::CameraBase *)dev)->getType();
}
std::string sv::Camera::getName(void)
{
return ((sv_p::CameraBase *)dev)->getName();
}
int sv::Camera::getW(void)
{
return ((sv_p::CameraBase *)dev)->getW();
}
int sv::Camera::getH(void)
{
return ((sv_p::CameraBase *)dev)->getH();
}
int sv::Camera::getExpectFps(void)
{
return ((sv_p::CameraBase *)dev)->getExpectFps();
}
double sv::Camera::getFps(void)
{
return ((sv_p::CameraBase *)dev)->getFps();
}
double sv::Camera::getBrightness(void)
{
return ((sv_p::CameraBase *)dev)->getBrightness();
}
double sv::Camera::getContrast(void)
{
return ((sv_p::CameraBase *)dev)->getContrast();
}
double sv::Camera::getSaturation(void)
{
return ((sv_p::CameraBase *)dev)->getSaturation();
}
double sv::Camera::getHue(void)
{
return ((sv_p::CameraBase *)dev)->getHue();
}
double sv::Camera::getExposure(void)
{
return ((sv_p::CameraBase *)dev)->getExposure();
}

136
video_io/sv_camera_def.cpp Normal file
View File

@ -0,0 +1,136 @@
#include "sv_camera_privately.h"
sv_p::CameraBase::CameraBase(int timeOut)
{
this->_timeOut = timeOut;
}
void sv_p::CameraBase::readThread(void)
{
int count = 0;
while (this->cap.isOpened())
{
if (this->cap.grab())
{
std::lock_guard<std::mutex> locker(this->frameMutex);
this->cap.retrieve(this->imageBuff);
this->frameEmpty.notify_all();
count = 0;
isGot = true;
}
else
{
count++;
if (count > this->_timeOut)
{
this->cap.release();
// 抛出异常 并返回
throw std::runtime_error("SpireCV (101) Camera has offline, check CAMERA!");
return;
}
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
}
}
#define PARAM_SET_CHECK(param, value) param = (value > 0 ? value : param)
void sv_p::CameraBase::setWH(int width, int height)
{
if (!this->cap.isOpened())
{
PARAM_SET_CHECK(this->_width, width);
PARAM_SET_CHECK(this->_height, height);
}
}
void sv_p::CameraBase::setFps(int fps)
{
PARAM_SET_CHECK(this->_fps, fps);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_FPS, fps);
}
}
void sv_p::CameraBase::setBrightness(double brightness)
{
PARAM_SET_CHECK(this->_brightness, brightness);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_BRIGHTNESS, brightness);
}
}
void sv_p::CameraBase::setContrast(double contrast)
{
PARAM_SET_CHECK(this->_contrast, contrast);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_CONTRAST, contrast);
}
}
void sv_p::CameraBase::setSaturation(double saturation)
{
PARAM_SET_CHECK(this->_saturation, saturation);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_SATURATION, saturation);
}
}
void sv_p::CameraBase::setHue(double hue)
{
PARAM_SET_CHECK(this->_hue, hue);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_HUE, hue);
}
}
void sv_p::CameraBase::setExposure(double exposure)
{
PARAM_SET_CHECK(this->_exposure, exposure);
if (this->cap.isOpened())
{
this->cap.set(cv::CAP_PROP_EXPOSURE, exposure);
}
}
bool sv_p::CameraBase::open(void)
{
}
bool sv_p::CameraBase::read(cv::Mat &image)
{
bool ret = false;
std::lock_guard<std::mutex> locker(this->frameMutex);
if (this->frameEmpty.wait_for(this->frameMutex, std::chrono::milliseconds(this->_timeOut)) == std::cv_status::no_timeout)
{
// 获取图像
this->imageBuff.copyTo(image);
ret = true;
}
return ret;
}
bool sv_p::CameraBase::readNoBlock(cv::Mat &image)
{
bool ret = false;
std::lock_guard<std::mutex> locker(this->frameMutex);
if (this->isGot)
{
this->imageBuff.copyTo(image);
isGot = false;
}
return ret;
}
void sv_p::CameraBase::release(void)
{
if (this->cap.isOpened())
{
this->cap.release();
}
}

View File

@ -0,0 +1,84 @@
#ifndef __SV_CAMERA_PRIVATELY__
#define __SV_CAMERA_PRIVATELY__
#include "opencv2/opencv.hpp"
#include <stdint.h>
#include <thread>
#include <mutex>
#include <condition_variable>
#include "sv_camera.h"
namespace sv_p
{
class CameraBase
{
private:
// 图像的属性
int _width = 1280;
int _height = 720;
int _fps = 30;
double _brightness = -1;
double _contrast = -1;
double _saturation = -1;
double _hue = -1;
double _exposure = -1;
int _timeOut = 500;
// 内部状态
double fpsCurr = -1;
bool isGot = false;
// 内部变量
cv::Mat imageBuff;
cv::VideoCapture cap;
std::mutex frameMutex;
std::condition_variable_any frameEmpty;
std::thread::native_handle_type readThreadHandle = 0;
// 获取图像的线程 在这个线程中查询、提取图像
virtual void readThread(void);
public:
// 属性设置的接口
virtual void setWH(int width, int height);
// 基本属性 至少实现1个
virtual bool setStream(const std::string &ip, uint16_t port) { return false; }
virtual bool setName(const std::string &name) { return false; }
virtual bool setIndex(int index) { return false; }
// 扩展属性设置 默认调用opencv的实现
virtual void setFps(int fps);
virtual void setBrightness(double brightness);
virtual void setContrast(double contrast);
virtual void setSaturation(double saturation);
virtual void setHue(double hue);
virtual void setExposure(double exposure);
// 属性获取的接口
virtual sv::CameraType getType(void) { return sv::CameraType::NONE; }
virtual std::string getName(void) { return "\0"; };
virtual bool isActive(void) { return (readThreadHandle == 0 ? false : true); }
int getW(void) { return _width; }
int getH(void) { return _height; }
int getExpectFps(void) { return _fps; }
double getFps(void) { return fpsCurr; }
double getBrightness(void) { return _brightness; }
double getContrast(void) { return _contrast; }
double getSaturation(void) { return _saturation; }
double getHue(void) { return _hue; }
double getExposure(void) { return _exposure; }
// 功能接口函数
virtual bool open(void);
virtual bool read(cv::Mat &image);
virtual bool readNoBlock(cv::Mat &image);
virtual void release(void);
CameraBase(int timeOut);
~CameraBase();
};
}
#endif