Add CameraGrabber camera wrapper and refactor main loop
- 新增 inc/camera_set.hpp + src/camera_set.cpp:封装相机初始化、启停、参数设置与取帧 - main.cpp 改用 CameraGrabber,取流循环支持 ESC 退出 - xmake.lua 增加 inc/ 头文件目录与绝对路径 - .gitignore 忽略 wget 日志
This commit is contained in:
@@ -7,3 +7,7 @@ build/
|
||||
|
||||
|
||||
.vscode/.cache/
|
||||
|
||||
# wget 下载日志
|
||||
wget.log
|
||||
*.log
|
||||
|
||||
Vendored
+6
-1
@@ -1,6 +1,11 @@
|
||||
[
|
||||
{
|
||||
"directory": "/home/mzxiang/opencv_project/27RM",
|
||||
"arguments": ["/usr/bin/g++", "-c", "-m64", "-g", "-O0", "-std=c++11", "-I/usr/local/include/opencv4", "-I/home/mzxiang/MindVisionSDK/include", "-o", "build/.objs/27RM/linux/x86_64/debug/src/main.cpp.o", "src/main.cpp"],
|
||||
"arguments": ["/usr/bin/g++", "-c", "-m64", "-g", "-O0", "-std=c++11", "-I/home/mzxiang/opencv_project/27RM/inc", "-I/usr/local/include/opencv4", "-I/home/mzxiang/MindVisionSDK/include", "-o", "build/.objs/27RM/linux/x86_64/debug/src/main.cpp.o", "src/main.cpp"],
|
||||
"file": "src/main.cpp"
|
||||
},
|
||||
{
|
||||
"directory": "/home/mzxiang/opencv_project/27RM",
|
||||
"arguments": ["/usr/bin/g++", "-c", "-m64", "-g", "-O0", "-std=c++11", "-I/home/mzxiang/opencv_project/27RM/inc", "-I/usr/local/include/opencv4", "-I/home/mzxiang/MindVisionSDK/include", "-o", "build/.objs/27RM/linux/x86_64/debug/src/camera_set.cpp.o", "src/camera_set.cpp"],
|
||||
"file": "src/camera_set.cpp"
|
||||
}]
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#ifndef CAMERA_SET_HPP
|
||||
#define CAMERA_SET_HPP
|
||||
|
||||
#include "CameraDefine.h" // 类型定义
|
||||
#include <opencv2/opencv.hpp>
|
||||
|
||||
|
||||
class CameraGrabber
|
||||
{
|
||||
public:
|
||||
CameraGrabber(); // 构造函数声明
|
||||
~CameraGrabber(); // 析构函数声明
|
||||
|
||||
bool initializeCamera(); // 初始化相机
|
||||
bool startCamera(); // 启动相机
|
||||
bool stopCamera(); // 停止相机
|
||||
bool setExposureTime(double exposureTime); // 设置曝光时间
|
||||
bool setGain(double gain); // 设置增益
|
||||
bool setWhiteBalance(double redGain, double blueGain); // 设置白平衡
|
||||
bool setResolution(int width, int height); // 设置分辨率
|
||||
bool setFrameRate(double frameRate); // 设置帧率
|
||||
bool getFrame(cv::Mat &frame); // 获取一帧图像
|
||||
|
||||
private:
|
||||
CameraHandle hCamera = -1; // 相机句柄
|
||||
tSdkCameraCapbility capability; // 相机能力描述
|
||||
unsigned char *pRgbBuffer = nullptr; // 图像处理缓冲区
|
||||
int channel = 3; // 通道数:1 灰度,3 彩色
|
||||
bool isInitialized = false; // 是否已初始化
|
||||
bool isPlaying = false; // 是否已启动取流
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,162 @@
|
||||
#include "camera_set.hpp"
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include "CameraApi.h"
|
||||
#include <cstdlib>
|
||||
|
||||
bool CameraGrabber::initializeCamera()
|
||||
{
|
||||
// 初始化检查,防止重复初始化
|
||||
if (isInitialized)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
int iStatus=-1; // SDK函数返回状态
|
||||
tSdkCameraDevInfo tCameraEnumList; // 枚举设备信息列表
|
||||
int iCameraCounts = 1; // 设备数量
|
||||
|
||||
// 初始化相机SDK
|
||||
CameraSdkInit(1);
|
||||
|
||||
//枚举设备,并建立设备列表
|
||||
iStatus = CameraEnumerateDevice(&tCameraEnumList,&iCameraCounts);
|
||||
|
||||
// printf("state = %d\n", CameraGrabber::iStatus);
|
||||
// printf("count = %d\n", CameraGrabber::iCameraCounts);
|
||||
|
||||
// 没有连接设备
|
||||
if(iCameraCounts == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 相机初始化。初始化成功后,才能调用任何其他相机相关的操作接口
|
||||
iStatus = CameraInit(&tCameraEnumList,-1,-1,&hCamera);
|
||||
|
||||
// 初始化失败
|
||||
// printf("state = %d\n", CameraGrabber::iStatus);
|
||||
if(iStatus != CAMERA_STATUS_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获得相机的特性描述结构体。该结构体中包含了相机可设置的各种参数的范围信息。决定了相关函数的参数
|
||||
CameraGetCapability(hCamera,&capability);
|
||||
|
||||
// 分配图像处理缓冲区
|
||||
pRgbBuffer = (unsigned char*)malloc(capability.sResolutionRange.iHeightMax*capability.sResolutionRange.iWidthMax*3);
|
||||
//g_readBuf = (unsigned char*)malloc(tCapability.sResolutionRange.iHeightMax*tCapability.sResolutionRange.iWidthMax*3);
|
||||
|
||||
// 设置图像输出格式
|
||||
if(capability.sIspCapacity.bMonoSensor)
|
||||
{
|
||||
channel=1;
|
||||
CameraSetIspOutFormat(hCamera,CAMERA_MEDIA_TYPE_MONO8);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel=3;
|
||||
CameraSetIspOutFormat(hCamera,CAMERA_MEDIA_TYPE_BGR8);
|
||||
}
|
||||
|
||||
isInitialized = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CameraGrabber::startCamera()
|
||||
{
|
||||
// 初始化检查
|
||||
if (!isInitialized)
|
||||
{
|
||||
printf("startCamera failed: camera not initialized.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// 防止重复启动
|
||||
if (isPlaying)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// 开始接收图像
|
||||
CameraSdkStatus status = CameraPlay(hCamera);
|
||||
if (status != CAMERA_STATUS_SUCCESS)
|
||||
{
|
||||
printf("CameraPlay failed, status = %d\n", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
// 标记状态
|
||||
isPlaying = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CameraGrabber::stopCamera()
|
||||
{
|
||||
// 停止取流
|
||||
if (isPlaying)
|
||||
{
|
||||
CameraPause(hCamera);
|
||||
isPlaying = false;
|
||||
}
|
||||
|
||||
// 反初始化相机,释放 SDK 内部资源
|
||||
if (hCamera != -1)
|
||||
{
|
||||
CameraUnInit(hCamera);
|
||||
hCamera = -1;
|
||||
}
|
||||
|
||||
// 释放图像缓冲区
|
||||
if (pRgbBuffer)
|
||||
{
|
||||
free(pRgbBuffer);
|
||||
pRgbBuffer = nullptr;
|
||||
}
|
||||
|
||||
// 复位
|
||||
isInitialized = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CameraGrabber::getFrame(cv::Mat &frame)
|
||||
{
|
||||
// 前者条件检查
|
||||
if (!isInitialized || !isPlaying || hCamera == -1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
tSdkFrameHead sFrameInfo; // 图像帧头信息
|
||||
BYTE *pbyBuffer = nullptr; // 图像缓冲区指针
|
||||
|
||||
// 获取图像缓冲区
|
||||
if (CameraGetImageBuffer(hCamera, &sFrameInfo, &pbyBuffer, 1000) != CAMERA_STATUS_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// 图像处理,将原始图像转换为 RGB 格式
|
||||
CameraImageProcess(hCamera, pbyBuffer, pRgbBuffer, &sFrameInfo);
|
||||
|
||||
// 将图像数据转换为 OpenCV 的 Mat 对象,并深拷贝
|
||||
frame = cv::Mat(
|
||||
cv::Size(sFrameInfo.iWidth, sFrameInfo.iHeight),
|
||||
sFrameInfo.uiMediaType == CAMERA_MEDIA_TYPE_MONO8 ? CV_8UC1 : CV_8UC3,
|
||||
pRgbBuffer
|
||||
).clone();
|
||||
|
||||
// 释放图像缓冲区
|
||||
CameraReleaseImageBuffer(hCamera, pbyBuffer);
|
||||
return true;
|
||||
}
|
||||
|
||||
CameraGrabber::CameraGrabber()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CameraGrabber::~CameraGrabber()
|
||||
{
|
||||
stopCamera();
|
||||
}
|
||||
+23
-76
@@ -1,96 +1,43 @@
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <stdio.h>
|
||||
#include "CameraApi.h"
|
||||
#include "camera_set.hpp"
|
||||
|
||||
unsigned char * g_pRgbBuffer;
|
||||
// unsigned char * g_pRgbBuffer;
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int iCameraCounts = 1;
|
||||
int iStatus=-1;
|
||||
tSdkCameraDevInfo tCameraEnumList;
|
||||
int hCamera;
|
||||
tSdkCameraCapbility tCapability; //设备描述信息
|
||||
tSdkFrameHead sFrameInfo;
|
||||
BYTE* pbyBuffer;
|
||||
int iDisplayFrames = 10000;
|
||||
int channel=3;
|
||||
// 创建相机对象
|
||||
CameraGrabber cam;
|
||||
|
||||
CameraSdkInit(1);
|
||||
|
||||
//枚举设备,并建立设备列表
|
||||
iStatus = CameraEnumerateDevice(&tCameraEnumList,&iCameraCounts);
|
||||
printf("state = %d\n", iStatus);
|
||||
|
||||
printf("count = %d\n", iCameraCounts);
|
||||
//没有连接设备
|
||||
if(iCameraCounts==0){
|
||||
// 初始化相机
|
||||
if (!cam.initializeCamera())
|
||||
{
|
||||
printf("initializeCamera failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//相机初始化。初始化成功后,才能调用任何其他相机相关的操作接口
|
||||
iStatus = CameraInit(&tCameraEnumList,-1,-1,&hCamera);
|
||||
|
||||
//初始化失败
|
||||
printf("state = %d\n", iStatus);
|
||||
if(iStatus!=CAMERA_STATUS_SUCCESS){
|
||||
// 取流
|
||||
if (!cam.startCamera())
|
||||
{
|
||||
printf("startCamera failed.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
//获得相机的特性描述结构体。该结构体中包含了相机可设置的各种参数的范围信息。决定了相关函数的参数
|
||||
CameraGetCapability(hCamera,&tCapability);
|
||||
// 循环取图并显示
|
||||
cv::Mat frame;
|
||||
|
||||
//
|
||||
g_pRgbBuffer = (unsigned char*)malloc(tCapability.sResolutionRange.iHeightMax*tCapability.sResolutionRange.iWidthMax*3);
|
||||
//g_readBuf = (unsigned char*)malloc(tCapability.sResolutionRange.iHeightMax*tCapability.sResolutionRange.iWidthMax*3);
|
||||
|
||||
/*让SDK进入工作模式,开始接收来自相机发送的图像
|
||||
数据。如果当前相机是触发模式,则需要接收到
|
||||
触发帧以后才会更新图像。 */
|
||||
CameraPlay(hCamera);
|
||||
|
||||
/*其他的相机参数设置
|
||||
例如 CameraSetExposureTime CameraGetExposureTime 设置/读取曝光时间
|
||||
CameraSetImageResolution CameraGetImageResolution 设置/读取分辨率
|
||||
CameraSetGamma、CameraSetConrast、CameraSetGain等设置图像伽马、对比度、RGB数字增益等等。
|
||||
本例程只是为了演示如何将SDK中获取的图像,转成OpenCV的图像格式,以便调用OpenCV的图像处理函数进行后续开发
|
||||
*/
|
||||
|
||||
if(tCapability.sIspCapacity.bMonoSensor){
|
||||
channel=1;
|
||||
CameraSetIspOutFormat(hCamera,CAMERA_MEDIA_TYPE_MONO8);
|
||||
}else{
|
||||
channel=3;
|
||||
CameraSetIspOutFormat(hCamera,CAMERA_MEDIA_TYPE_BGR8);
|
||||
}
|
||||
|
||||
|
||||
//循环显示1000帧图像
|
||||
while(iDisplayFrames--)
|
||||
while(true)
|
||||
{
|
||||
if(CameraGetImageBuffer(hCamera,&sFrameInfo,&pbyBuffer,1000) == CAMERA_STATUS_SUCCESS)
|
||||
if (cam.getFrame(frame))
|
||||
{
|
||||
CameraImageProcess(hCamera, pbyBuffer, g_pRgbBuffer,&sFrameInfo);
|
||||
|
||||
cv::Mat matImage(
|
||||
cv::Size(sFrameInfo.iWidth, sFrameInfo.iHeight),
|
||||
sFrameInfo.uiMediaType == CAMERA_MEDIA_TYPE_MONO8 ? CV_8UC1 : CV_8UC3,
|
||||
g_pRgbBuffer
|
||||
);
|
||||
imshow("Opencv Demo", matImage);
|
||||
|
||||
cv::waitKey(5);
|
||||
|
||||
//在成功调用CameraGetImageBuffer后,必须调用CameraReleaseImageBuffer来释放获得的buffer。
|
||||
//否则再次调用CameraGetImageBuffer时,程序将被挂起一直阻塞,直到其他线程中调用CameraReleaseImageBuffer来释放了buffer
|
||||
CameraReleaseImageBuffer(hCamera,pbyBuffer);
|
||||
|
||||
}
|
||||
cv::imshow("Opencv Demo", frame);
|
||||
}
|
||||
|
||||
CameraUnInit(hCamera);
|
||||
//注意,现反初始化后再free
|
||||
free(g_pRgbBuffer);
|
||||
// 按 ESC 退出
|
||||
if (cv::waitKey(5) == 27)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user