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:
2026-09-13 22:44:23 +08:00
parent 37548a92ad
commit 14d7f9e571
6 changed files with 240 additions and 86 deletions
+4
View File
@@ -7,3 +7,7 @@ build/
.vscode/.cache/ .vscode/.cache/
# wget 下载日志
wget.log
*.log
+6 -1
View File
@@ -1,6 +1,11 @@
[ [
{ {
"directory": "/home/mzxiang/opencv_project/27RM", "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" "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"
}] }]
+35
View File
@@ -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
+162
View File
@@ -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
View File
@@ -1,96 +1,43 @@
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
#include <stdio.h> #include "camera_set.hpp"
#include "CameraApi.h"
unsigned char * g_pRgbBuffer; // unsigned char * g_pRgbBuffer;
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
int iCameraCounts = 1; // 创建相机对象
int iStatus=-1; CameraGrabber cam;
tSdkCameraDevInfo tCameraEnumList;
int hCamera;
tSdkCameraCapbility tCapability; //设备描述信息
tSdkFrameHead sFrameInfo;
BYTE* pbyBuffer;
int iDisplayFrames = 10000;
int channel=3;
CameraSdkInit(1); // 初始化相机
if (!cam.initializeCamera())
//枚举设备,并建立设备列表 {
iStatus = CameraEnumerateDevice(&tCameraEnumList,&iCameraCounts); printf("initializeCamera failed.\n");
printf("state = %d\n", iStatus);
printf("count = %d\n", iCameraCounts);
//没有连接设备
if(iCameraCounts==0){
return -1; return -1;
} }
//相机初始化。初始化成功后,才能调用任何其他相机相关的操作接口 // 取流
iStatus = CameraInit(&tCameraEnumList,-1,-1,&hCamera); if (!cam.startCamera())
{
//初始化失败 printf("startCamera failed.\n");
printf("state = %d\n", iStatus);
if(iStatus!=CAMERA_STATUS_SUCCESS){
return -1; return -1;
} }
//获得相机的特性描述结构体。该结构体中包含了相机可设置的各种参数的范围信息。决定了相关函数的参数 // 循环取图并显示
CameraGetCapability(hCamera,&tCapability); cv::Mat frame;
// while(true)
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--)
{ {
if(CameraGetImageBuffer(hCamera,&sFrameInfo,&pbyBuffer,1000) == CAMERA_STATUS_SUCCESS) if (cam.getFrame(frame))
{ {
CameraImageProcess(hCamera, pbyBuffer, g_pRgbBuffer,&sFrameInfo); cv::imshow("Opencv Demo", frame);
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);
}
} }
CameraUnInit(hCamera); // 按 ESC 退出
//注意,现反初始化后再free if (cv::waitKey(5) == 27)
free(g_pRgbBuffer); {
break;
}
}
return 0; return 0;
} }
+2 -1
View File
@@ -6,7 +6,8 @@ set_languages("c++11")
target("27RM") target("27RM")
set_kind("binary") set_kind("binary")
add_files("src/*.cpp") add_files("$(scriptdir)/src/*.cpp")
add_includedirs("$(scriptdir)/inc/")
-- openCV配置 -- openCV配置
add_includedirs("/usr/local/include/opencv4") add_includedirs("/usr/local/include/opencv4")