Compare commits

7 Commits

4 changed files with 118 additions and 15 deletions

View File

@@ -75,4 +75,7 @@ make -j$(nproc)
1. 检查相机是否正确连接
2. 确认MindVision相机驱动是否正确安装
3. 验证相机ID是否正确
4. 检查权限可能需要将用户添加到video组
4. 检查权限可能需要将用户添加到video组
## MindVision-SDK
`Linux`: >**wget https://www.mindvision.com.cn/wp-content/uploads/2023/08/linuxSDK_V2.1.0.37.tar.gz**

View File

@@ -12,13 +12,15 @@ extern "C" {
class MindVisionCamera {
public:
int camera_handle; // MindVision SDK中的相机句柄
CameraHandle camera_handle; // MindVision SDk中的相机句柄
bool is_opened;
std::string target_color;
int width;
int height;
int fps;
unsigned char* g_pRgbBuffer; // 处理后数据缓存区
tSdkCameraCapbility capability; // 相机能力信息
tSdkImageResolution image_resolution; // 分辨率信息
MindVisionCamera(int cam_id = 0, const std::string& target_color = "red");
~MindVisionCamera();
@@ -29,6 +31,10 @@ public:
void release();
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:
void set_camera_parameters();
bool initialize_camera(int cam_id);

View File

@@ -59,21 +59,19 @@ bool MindVisionCamera::initialize_camera(int cam_id) {
}
// 获取相机能力
tSdkCameraCapbility capability;
iStatus = CameraGetCapability(camera_handle, &capability);
if (iStatus != CAMERA_STATUS_SUCCESS) {
std::cerr << "Failed to get camera capability! Error code: " << iStatus << std::endl;
return false;
}
// 让SDK进入工作模式 - 根据原始OpenCv项目应该在设置格式前调用
CameraPlay(camera_handle);
// 设置输出格式 - 保持与原始工作项目一致直接设置为BGR8格式
CameraSetIspOutFormat(camera_handle, CAMERA_MEDIA_TYPE_BGR8);
// 让SDK进入工作模式 - 根据原始OpenCv项目应该在设置格式前调用
CameraPlay(camera_handle);
// 获取并设置分辨率为 640x480
tSdkImageResolution image_resolution;
int status = CameraGetImageResolution(camera_handle, &image_resolution);
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) {
// 直接使用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);
if (status != CAMERA_STATUS_SUCCESS) {
@@ -192,6 +202,38 @@ bool MindVisionCamera::read_frame_with_color_filter(cv::Mat& frame, cv::Mat& raw
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;
BYTE* pbyBuffer;
@@ -239,11 +281,16 @@ bool MindVisionCamera::read_frame_with_color_filter(cv::Mat& frame, cv::Mat& raw
}
void MindVisionCamera::release() {
if (camera_handle >= 0) {
if (camera_handle != 0) {
// 停止采集不管is_opened状态如何都尝试释放
CameraPause(camera_handle);
CameraUnInit(camera_handle);
camera_handle = -1;
}
if(g_pRgbBuffer) {
free(g_pRgbBuffer);
g_pRgbBuffer = nullptr;
}
is_opened = false;
}
@@ -259,4 +306,30 @@ bool MindVisionCamera::switch_color(const std::string& new_color) {
return set_cam_params(); // 返回set_cam_params的结果
}
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 = capability.sResolutionRange.iWidthMax;
res.iHeightFOV = capability.sResolutionRange.iHeightMax;
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 true;
}
return false;
}

View File

@@ -1,3 +1,4 @@
#include <cstdlib>
#include <iostream>
#include <string>
#include <vector>
@@ -29,8 +30,14 @@ void output_control_data(const cv::Point2f* ballistic_point,
std::ostringstream send_str;
// Calculate offset (based on actual image center)
int ballistic_offset_x = static_cast<int>(ballistic_point->x - img_center.x);
int ballistic_offset_y = static_cast<int>(img_center.y - ballistic_point->y);
int ballistic_offset_x = -static_cast<int>(ballistic_point->x - img_center.x);
if ( abs(ballistic_offset_x) > 320){
ballistic_offset_x = ( ballistic_offset_x / abs( ballistic_offset_x ) ) * 320 ;
}
int ballistic_offset_y = -static_cast<int>(img_center.y - ballistic_point->y);
if ( abs(ballistic_offset_y) > 180 ) {
ballistic_offset_y = ( ballistic_offset_x / abs( ballistic_offset_x ) ) * 180 ;
}
// Color simplification mapping
std::string simplified_color = target_color;
@@ -38,7 +45,7 @@ void output_control_data(const cv::Point2f* ballistic_point,
else if (target_color == "blue") simplified_color = "b";
// Construct send string
send_str << "s " << simplified_color << " " << std::to_string(ballistic_offset_x) << " " << std::to_string(ballistic_offset_y) << "\n";
send_str << "#s " << simplified_color << " " << std::to_string(ballistic_offset_x) << " " << std::to_string(ballistic_offset_y) << "*\n";
// Send data
if (ttl_communicator != nullptr) {
@@ -50,19 +57,32 @@ 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
// We need to implement a method in MindVisionCamera to change resolution
// 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*/[]) {
static int Numbe = 0;
std::string target_color = "red";
int cam_id = 0;
cv::Size default_resolution(640, 480);
bool use_ttl = true; // Set to false to disable TTL communication
cv::Size default_resolution(1280, 720);
bool use_ttl = false; // Set to false to disable TTL communication
if (Numbe == 0) {
// 执行 shell 命令(注意安全风险!)
std::system("sudo chmod 777 /dev/tty*");
Numbe++;
}
return 0;
// Define optional resolution list (adjust based on camera support)
std::vector<cv::Size> resolutions = {
cv::Size(320, 240), // Low resolution, high frame rate
@@ -125,6 +145,7 @@ int main(int /*argc*/, char* /*argv*/[]) {
try {
while (true) {
// 使用新的颜色过滤方法同时获取图像和原始掩码
cv::Mat raw_mask;
if (!camera.read_frame_with_color_filter(frame, raw_mask, target_color)) {
std::cout << "Cannot read from MindVision camera, exiting!HERERER" << std::endl;