Merge pull request '对于视频流获取方面新加了一个用Mindvision官方说明的获取方式,测试了代码运行是内存占用高达1G' (#3) from Update into main
Reviewed-on: #3
This commit is contained in:
@@ -12,13 +12,15 @@ extern "C" {
|
|||||||
|
|
||||||
class MindVisionCamera {
|
class MindVisionCamera {
|
||||||
public:
|
public:
|
||||||
int camera_handle; // MindVision SDK中的相机句柄
|
CameraHandle camera_handle; // MindVision SDk中的相机句柄
|
||||||
bool is_opened;
|
bool is_opened;
|
||||||
std::string target_color;
|
std::string target_color;
|
||||||
int width;
|
int width;
|
||||||
int height;
|
int height;
|
||||||
int fps;
|
int fps;
|
||||||
unsigned char* g_pRgbBuffer; // 处理后数据缓存区
|
unsigned char* g_pRgbBuffer; // 处理后数据缓存区
|
||||||
|
tSdkCameraCapbility capability; // 相机能力信息
|
||||||
|
tSdkImageResolution image_resolution; // 分辨率信息
|
||||||
|
|
||||||
MindVisionCamera(int cam_id = 0, const std::string& target_color = "red");
|
MindVisionCamera(int cam_id = 0, const std::string& target_color = "red");
|
||||||
~MindVisionCamera();
|
~MindVisionCamera();
|
||||||
@@ -29,6 +31,10 @@ public:
|
|||||||
void release();
|
void release();
|
||||||
bool switch_color(const std::string& target_color);
|
bool switch_color(const std::string& target_color);
|
||||||
|
|
||||||
|
int get_width() const { return width; }
|
||||||
|
int get_height() const { return height; }
|
||||||
|
bool set_resolution(int width, int height);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void set_camera_parameters();
|
void set_camera_parameters();
|
||||||
bool initialize_camera(int cam_id);
|
bool initialize_camera(int cam_id);
|
||||||
|
|||||||
@@ -59,21 +59,19 @@ bool MindVisionCamera::initialize_camera(int cam_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 获取相机能力
|
// 获取相机能力
|
||||||
tSdkCameraCapbility capability;
|
|
||||||
iStatus = CameraGetCapability(camera_handle, &capability);
|
iStatus = CameraGetCapability(camera_handle, &capability);
|
||||||
if (iStatus != CAMERA_STATUS_SUCCESS) {
|
if (iStatus != CAMERA_STATUS_SUCCESS) {
|
||||||
std::cerr << "Failed to get camera capability! Error code: " << iStatus << std::endl;
|
std::cerr << "Failed to get camera capability! Error code: " << iStatus << std::endl;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 让SDK进入工作模式 - 根据原始OpenCv项目,应该在设置格式前调用
|
|
||||||
CameraPlay(camera_handle);
|
|
||||||
|
|
||||||
// 设置输出格式 - 保持与原始工作项目一致,直接设置为BGR8格式
|
// 设置输出格式 - 保持与原始工作项目一致,直接设置为BGR8格式
|
||||||
CameraSetIspOutFormat(camera_handle, CAMERA_MEDIA_TYPE_BGR8);
|
CameraSetIspOutFormat(camera_handle, CAMERA_MEDIA_TYPE_BGR8);
|
||||||
|
|
||||||
|
// 让SDK进入工作模式 - 根据原始OpenCv项目,应该在设置格式前调用
|
||||||
|
CameraPlay(camera_handle);
|
||||||
|
|
||||||
// 获取并设置分辨率为 640x480
|
// 获取并设置分辨率为 640x480
|
||||||
tSdkImageResolution image_resolution;
|
|
||||||
int status = CameraGetImageResolution(camera_handle, &image_resolution);
|
int status = CameraGetImageResolution(camera_handle, &image_resolution);
|
||||||
std::cout << "Default resolution query returned: " << status << std::endl;
|
std::cout << "Default resolution query returned: " << status << std::endl;
|
||||||
|
|
||||||
@@ -166,6 +164,18 @@ bool MindVisionCamera::read_frame(cv::Mat& frame) {
|
|||||||
|
|
||||||
// 获取一帧数据
|
// 获取一帧数据
|
||||||
if (CameraGetImageBuffer(camera_handle, &sFrameInfo, &pbyBuffer, 1000) == CAMERA_STATUS_SUCCESS) {
|
if (CameraGetImageBuffer(camera_handle, &sFrameInfo, &pbyBuffer, 1000) == CAMERA_STATUS_SUCCESS) {
|
||||||
|
// 直接使用CameraGetImageBufferEx获取处理后的RGB数据,提高效率
|
||||||
|
INT width, height;
|
||||||
|
unsigned char* pData = CameraGetImageBufferEx(camera_handle, &width, &height, 2000);
|
||||||
|
if(pData != NULL) {
|
||||||
|
// 创建OpenCV Mat对象,直接使用获取的数据
|
||||||
|
cv::Mat temp_mat(height, width, CV_8UC3, pData);
|
||||||
|
frame = temp_mat.clone(); // clone()确保数据被复制,而不是共享指针
|
||||||
|
|
||||||
|
// CameraGetImageBufferEx方式不需要手动释放缓冲区
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// 使用全局缓冲区处理图像数据 - 与原始项目一致
|
// 使用全局缓冲区处理图像数据 - 与原始项目一致
|
||||||
int status = CameraImageProcess(camera_handle, pbyBuffer, g_pRgbBuffer, &sFrameInfo);
|
int status = CameraImageProcess(camera_handle, pbyBuffer, g_pRgbBuffer, &sFrameInfo);
|
||||||
if (status != CAMERA_STATUS_SUCCESS) {
|
if (status != CAMERA_STATUS_SUCCESS) {
|
||||||
@@ -192,6 +202,38 @@ bool MindVisionCamera::read_frame_with_color_filter(cv::Mat& frame, cv::Mat& raw
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 尝试使用CameraGetImageBufferEx方式获取图像
|
||||||
|
INT width, height;
|
||||||
|
unsigned char* pData = CameraGetImageBufferEx(camera_handle, &width, &height, 2000);
|
||||||
|
if(pData != NULL) {
|
||||||
|
// 创建OpenCV Mat对象,直接使用获取的数据
|
||||||
|
cv::Mat original_img(height, width, CV_8UC3, pData);
|
||||||
|
frame = original_img.clone(); // clone()确保数据被复制,而不是共享指针
|
||||||
|
|
||||||
|
// 创建HSV图像用于颜色过滤
|
||||||
|
cv::Mat hsv_img;
|
||||||
|
cv::cvtColor(frame, hsv_img, cv::COLOR_BGR2HSV);
|
||||||
|
|
||||||
|
// 根据颜色创建原始掩码
|
||||||
|
if (target_color == "red") {
|
||||||
|
// Red color range in HSV
|
||||||
|
cv::Mat mask1, mask2;
|
||||||
|
cv::inRange(hsv_img, cv::Scalar(0, 43, 49), cv::Scalar(25, 255, 255), mask1);
|
||||||
|
cv::inRange(hsv_img, cv::Scalar(156, 46, 49), cv::Scalar(180, 255, 255), mask2);
|
||||||
|
raw_mask = mask1 | mask2;
|
||||||
|
} else if (target_color == "blue") {
|
||||||
|
// Blue color range in HSV
|
||||||
|
cv::inRange(hsv_img, cv::Scalar(83, 200, 44), cv::Scalar(130, 255, 255), raw_mask);
|
||||||
|
} else {
|
||||||
|
raw_mask = cv::Mat::zeros(hsv_img.size(), CV_8UC1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// CameraGetImageBufferEx方式不需要手动释放缓冲区
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 如果CameraGetImageBufferEx失败,回退到原来的方式
|
||||||
|
|
||||||
tSdkFrameHead sFrameInfo;
|
tSdkFrameHead sFrameInfo;
|
||||||
BYTE* pbyBuffer;
|
BYTE* pbyBuffer;
|
||||||
|
|
||||||
@@ -239,11 +281,16 @@ bool MindVisionCamera::read_frame_with_color_filter(cv::Mat& frame, cv::Mat& raw
|
|||||||
}
|
}
|
||||||
|
|
||||||
void MindVisionCamera::release() {
|
void MindVisionCamera::release() {
|
||||||
if (camera_handle >= 0) {
|
if (camera_handle != 0) {
|
||||||
// 停止采集,不管is_opened状态如何都尝试释放
|
// 停止采集,不管is_opened状态如何都尝试释放
|
||||||
|
CameraPause(camera_handle);
|
||||||
CameraUnInit(camera_handle);
|
CameraUnInit(camera_handle);
|
||||||
camera_handle = -1;
|
camera_handle = -1;
|
||||||
}
|
}
|
||||||
|
if(g_pRgbBuffer) {
|
||||||
|
free(g_pRgbBuffer);
|
||||||
|
g_pRgbBuffer = nullptr;
|
||||||
|
}
|
||||||
is_opened = false;
|
is_opened = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,4 +306,30 @@ bool MindVisionCamera::switch_color(const std::string& new_color) {
|
|||||||
return set_cam_params(); // 返回set_cam_params的结果
|
return set_cam_params(); // 返回set_cam_params的结果
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MindVisionCamera::set_resolution(int width, int height){
|
||||||
|
if (!is_opened) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
tSdkImageResolution res;
|
||||||
|
int status = CameraGetImageResolution(camera_handle, &res);
|
||||||
|
|
||||||
|
res.iIndex = 0xFF;
|
||||||
|
res.iWidth = width;
|
||||||
|
res.iHeight = height;
|
||||||
|
res.iWidthFOV = res.iWidth;
|
||||||
|
res.iHeightFOV = res.iHeight;
|
||||||
|
res.iHOffsetFOV = 0;
|
||||||
|
res.iVOffsetFOV = 0;
|
||||||
|
|
||||||
|
status = CameraSetImageResolution(camera_handle, &res);
|
||||||
|
if (status == CAMERA_STATUS_SUCCESS) {
|
||||||
|
this->width = width;
|
||||||
|
this->height = height;
|
||||||
|
image_resolution = res;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
@@ -50,18 +50,22 @@ void output_control_data(const cv::Point2f* ballistic_point,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_camera_resolution(MindVisionCamera& , int width, int height) {
|
void set_camera_resolution(MindVisionCamera& camera, int width, int height) {
|
||||||
// The resolution is set during camera initialization in MindVision
|
// The resolution is set during camera initialization in MindVision
|
||||||
// We need to implement a method in MindVisionCamera to change resolution
|
// We need to implement a method in MindVisionCamera to change resolution
|
||||||
// For now, we'll just log the intended change
|
// For now, we'll just log the intended change
|
||||||
std::cout << "Setting camera resolution to: " << width << "x" << height << std::endl;
|
if (camera.set_resolution(width, height)){
|
||||||
|
std::cout << "Successfully set camera resolution to: " << width << "x" << height << std::endl;
|
||||||
|
} else {
|
||||||
|
std::cerr << "Failed to set camera resolution to: " << width << "x" << height << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int /*argc*/, char* /*argv*/[]) {
|
int main(int /*argc*/, char* /*argv*/[]) {
|
||||||
std::string target_color = "red";
|
std::string target_color = "red";
|
||||||
int cam_id = 0;
|
int cam_id = 0;
|
||||||
cv::Size default_resolution(640, 480);
|
cv::Size default_resolution(640, 480);
|
||||||
bool use_ttl = true; // Set to false to disable TTL communication
|
bool use_ttl = false; // Set to false to disable TTL communication
|
||||||
|
|
||||||
// Define optional resolution list (adjust based on camera support)
|
// Define optional resolution list (adjust based on camera support)
|
||||||
std::vector<cv::Size> resolutions = {
|
std::vector<cv::Size> resolutions = {
|
||||||
|
|||||||
Reference in New Issue
Block a user