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/
|
.vscode/.cache/
|
||||||
|
|
||||||
|
# wget 下载日志
|
||||||
|
wget.log
|
||||||
|
*.log
|
||||||
|
|||||||
Vendored
+6
-1
@@ -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"
|
||||||
}]
|
}]
|
||||||
|
|||||||
@@ -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 <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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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")
|
||||||
|
|||||||
Reference in New Issue
Block a user