208 lines
7.1 KiB
C++
208 lines
7.1 KiB
C++
#include "MindVisionCamera.h"
|
|
#include <iostream>
|
|
|
|
MindVisionCamera::MindVisionCamera(int cam_id, const std::string& target_color)
|
|
: camera_handle(-1), is_opened(false), width(640), height(480), fps(30) {
|
|
|
|
if (!initialize_camera(cam_id)) {
|
|
throw std::runtime_error("Cannot initialize MindVision camera!");
|
|
}
|
|
|
|
is_opened = true;
|
|
this->target_color = target_color;
|
|
if (this->target_color != "red" && this->target_color != "blue") {
|
|
throw std::invalid_argument("Only 'red' or 'blue' colors are supported");
|
|
}
|
|
|
|
set_cam_params();
|
|
}
|
|
|
|
bool MindVisionCamera::initialize_camera(int cam_id) {
|
|
// 初始化SDK
|
|
CameraSdkInit(1);
|
|
|
|
int iCameraCounts = 10;
|
|
tSdkCameraDevInfo tCameraEnumList[10]; // 声明为数组而不是指针
|
|
|
|
// 枚举设备,并建立设备列表
|
|
int iStatus = CameraEnumerateDevice(tCameraEnumList, &iCameraCounts);
|
|
std::cout << "CameraEnumerateDevice returned: " << iStatus << std::endl;
|
|
std::cout << "Found " << iCameraCounts << " cameras" << std::endl;
|
|
|
|
if (iCameraCounts <= 0) {
|
|
std::cerr << "No MindVision cameras found!" << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// 选择指定ID的相机
|
|
if (cam_id >= iCameraCounts) {
|
|
std::cerr << "Camera ID " << cam_id << " not found! Only " << iCameraCounts << " cameras detected." << std::endl;
|
|
return false;
|
|
}
|
|
|
|
std::cout << "Initializing camera " << cam_id << ": " << tCameraEnumList[cam_id].acFriendlyName << std::endl;
|
|
|
|
// 相机初始化
|
|
iStatus = CameraInit(&tCameraEnumList[cam_id], -1, -1, &camera_handle);
|
|
std::cout << "CameraInit returned: " << iStatus << std::endl;
|
|
|
|
if (iStatus != CAMERA_STATUS_SUCCESS) {
|
|
std::cerr << "Failed to initialize camera! Error code: " << iStatus << std::endl;
|
|
return false;
|
|
}
|
|
|
|
// 获取相机能力
|
|
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;
|
|
}
|
|
|
|
// 设置输出格式
|
|
if (capability.sIspCapacity.bMonoSensor) {
|
|
CameraSetIspOutFormat(camera_handle, CAMERA_MEDIA_TYPE_MONO8);
|
|
} else {
|
|
CameraSetIspOutFormat(camera_handle, CAMERA_MEDIA_TYPE_BGR8);
|
|
}
|
|
|
|
// 让SDK进入工作模式
|
|
CameraPlay(camera_handle);
|
|
|
|
// 获取并设置分辨率为 640x480
|
|
tSdkImageResolution image_resolution;
|
|
int status = CameraGetImageResolution(camera_handle, &image_resolution);
|
|
std::cout << "Default resolution query returned: " << status << std::endl;
|
|
|
|
// 设置分辨率为 640x480
|
|
image_resolution.iIndex = 0xFF; // Use custom resolution (0xFF typically indicates custom resolution)
|
|
image_resolution.iWidth = 640;
|
|
image_resolution.iHeight = 480;
|
|
image_resolution.iWidthFOV = image_resolution.iWidth;
|
|
image_resolution.iHeightFOV = image_resolution.iHeight;
|
|
image_resolution.iHOffsetFOV = 0;
|
|
image_resolution.iVOffsetFOV = 0;
|
|
|
|
status = CameraSetImageResolution(camera_handle, &image_resolution);
|
|
if (status != CAMERA_STATUS_SUCCESS) {
|
|
std::cout << "Failed to set resolution to 640x480, using default settings" << std::endl;
|
|
// Try to get the current resolution after failed set
|
|
CameraGetImageResolution(camera_handle, &image_resolution);
|
|
} else {
|
|
std::cout << "Successfully set camera resolution to: " << image_resolution.iWidth << "x" << image_resolution.iHeight << std::endl;
|
|
}
|
|
|
|
width = image_resolution.iWidth;
|
|
height = image_resolution.iHeight;
|
|
|
|
// 开启自动曝光
|
|
CameraSetAeState(camera_handle, true);
|
|
|
|
// 设置帧率
|
|
CameraSetFrameSpeed(camera_handle, 10); // 设置为中等帧率
|
|
|
|
std::cout << "Initialized camera with resolution: " << width << "x" << height << std::endl;
|
|
|
|
return true;
|
|
}
|
|
|
|
MindVisionCamera::~MindVisionCamera() {
|
|
release();
|
|
}
|
|
|
|
void MindVisionCamera::set_camera_parameters() {
|
|
// 先设置为手动曝光模式
|
|
CameraSetAeState(camera_handle, false);
|
|
|
|
// 根据颜色设置曝光参数
|
|
if (target_color == "red") {
|
|
CameraSetExposureTime(camera_handle, 10000); // 5ms曝光时间
|
|
} else if (target_color == "blue") {
|
|
CameraSetExposureTime(camera_handle, 4000); // 8ms曝光时间
|
|
}
|
|
|
|
// 设置白平衡
|
|
CameraSetWbMode(camera_handle, false); // 关闭自动白平衡
|
|
CameraSetOnceWB(camera_handle); // 一次性白平衡
|
|
|
|
// 设置其他参数
|
|
CameraSetTriggerMode(camera_handle, 0); // 连续采集模式
|
|
}
|
|
|
|
void MindVisionCamera::set_cam_params() {
|
|
set_camera_parameters();
|
|
|
|
// Ensure resolution remains 640x480 after setting other parameters
|
|
tSdkImageResolution image_resolution;
|
|
image_resolution.iIndex = 0xFF; // Use custom resolution (0xFF typically indicates custom resolution)
|
|
image_resolution.iWidth = 640;
|
|
image_resolution.iHeight = 480;
|
|
image_resolution.iWidthFOV = image_resolution.iWidth;
|
|
image_resolution.iHeightFOV = image_resolution.iHeight;
|
|
image_resolution.iHOffsetFOV = 0;
|
|
image_resolution.iVOffsetFOV = 0;
|
|
|
|
int status = CameraSetImageResolution(camera_handle, &image_resolution);
|
|
if (status != CAMERA_STATUS_SUCCESS) {
|
|
std::cout << "Failed to maintain resolution at 640x480 in set_cam_params" << std::endl;
|
|
} else {
|
|
std::cout << "Confirmed camera resolution: " << image_resolution.iWidth << "x" << image_resolution.iHeight << std::endl;
|
|
}
|
|
}
|
|
|
|
bool MindVisionCamera::read_frame(cv::Mat& frame) {
|
|
if (!is_opened) {
|
|
return false;
|
|
}
|
|
|
|
tSdkFrameHead sFrameInfo;
|
|
BYTE* pbyBuffer;
|
|
|
|
// 获取一帧数据
|
|
if (CameraGetImageBuffer(camera_handle, &sFrameInfo, &pbyBuffer, 1000) == CAMERA_STATUS_SUCCESS) {
|
|
// 处理图像数据
|
|
unsigned char* g_pRgbBuffer = new unsigned char[sFrameInfo.iWidth * sFrameInfo.iHeight * 3];
|
|
CameraImageProcess(camera_handle, pbyBuffer, g_pRgbBuffer, &sFrameInfo);
|
|
|
|
// 创建OpenCV Mat对象
|
|
frame = cv::Mat(
|
|
cv::Size(sFrameInfo.iWidth, sFrameInfo.iHeight),
|
|
sFrameInfo.uiMediaType == CAMERA_MEDIA_TYPE_MONO8 ? CV_8UC1 : CV_8UC3,
|
|
g_pRgbBuffer
|
|
).clone(); // clone()确保数据被复制,而不是共享指针
|
|
|
|
// 释放原始缓冲区
|
|
CameraReleaseImageBuffer(camera_handle, pbyBuffer);
|
|
|
|
// 释放临时缓冲区
|
|
delete[] g_pRgbBuffer;
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void MindVisionCamera::release() {
|
|
if (is_opened && camera_handle >= 0) {
|
|
// 停止采集
|
|
CameraUnInit(camera_handle);
|
|
camera_handle = -1;
|
|
is_opened = false;
|
|
}
|
|
}
|
|
|
|
bool MindVisionCamera::switch_color(const std::string& new_color) {
|
|
std::string lower_color = new_color;
|
|
// Convert to lowercase manually
|
|
for (auto& c : lower_color) {
|
|
c = std::tolower(c);
|
|
}
|
|
|
|
if ((lower_color == "red" || lower_color == "blue") && lower_color != target_color) {
|
|
target_color = lower_color;
|
|
set_cam_params();
|
|
return true;
|
|
}
|
|
return false;
|
|
} |