camera.h 如下,需要dalsa的sdk库和opencv的库
// camera.h: 标准系统包含文件的包含文件
// 或项目特定的包含文件。
#pragma once
#include <iostream>
#include "SapClassBasic.h"
#include <SapBuffer.h>
#include<conio.h>
#include <string>
#include <vector>
#include <io.h>
#include <opencv2/opencv.hpp>
#include <stdio.h>
#include <iostream>
#include <thread>
using namespace std;
using namespace cv;
#define IMAGE_CLOS 8192
#define IMAGE_ROWS 20000
#define IMAGE_SIZE IMAGE_CLOS*IMAGE_ROWS
#define CAMERA_CONFIG ".\\camera_config.ccf"
#define SVAE_IMAGE_PATH ".\\image"
int camera_init();//初始化相机
void camera_release();//释放相机
bool get_camera_status();//获取相机状态
void get_camera_image(cv::Mat* get_image);//获取相机图片
int image_delete_black(Mat* p);
void close_dalsa_camera(); // 关闭采集
void open_dalsa_camera(); // 开始采集
void abort_dalsa_camera();//中止采集
void wait_dalsa_camera(int time);//相机等待 time -- ms
void save_camera_image();//保存图片
// TODO: 在此处引用程序需要的其他标头。
camera.cpp
// camera.cpp: 定义应用程序的入口点。
//
#include "camera.h"
static SapManager *m_pManager;
static SapAcquisition *m_Acquisition; //采集卡需要的类
static SapBufferWithTrash *m_Buffers; //实时处理时建立trash buffer用于存放转换数据(常用于处理速度跟不上数据采集速度时)
static SapTransfer *m_Xfer; //进行数据传输需要使用的类
static SapView *m_View; //这个类是 Dalsa 根据 MFC 重新定义的一个显示类,基于 GUI 界面
static SapAcqDevice *m_AcqDevice;//相机类
static cv::Mat image(IMAGE_ROWS, IMAGE_CLOS, CV_8UC1);
cv::Mat cropped_img;
static void XferCallBack(SapXferCallbackInfo *pInfo) {
BYTE pData;
static int staticCount = 0;
void *pDataAddr = &pData;
int pitch = m_Buffers->GetPitch();
int context = (int) pInfo->GetContext();
int format = m_Buffers->GetFormat();
printf("pitch %d context %d format %d\n", pitch, context, format);
bool success = m_Buffers->GetAddress(staticCount, &pDataAddr);
if (!success) {
return;
}
int width = m_Buffers->GetWidth();
int height = m_Buffers->GetHeight();
//memset(&image, 0, image.cols * image.rows);
image = cv::Mat::zeros(image.rows, image.cols, image.type());
memcpy(image.data, pDataAddr, IMAGE_ROWS * IMAGE_CLOS);
//cv:; namedWindow("image", cv::WINDOW_NORMAL);
//cv::imshow("image", image);
//cv::waitKey(0);
//cv::destroyAllWindows();
if (staticCount == 0) {
staticCount = 1;
} else if (staticCount == 1) {
staticCount = 0;
}
// 保存文件:
if (m_Buffers != NULL && m_Buffers) {
image_delete_black(&image);
success = m_Buffers->ReleaseAddress(pDataAddr);
m_Buffers->Clear();
}
// static int mark = 0;
//if (0 == mark)
//{
// m_View->SetScalingMode(0.2, 0.2, TRUE);
// //mark = 1;
//}
//m_View->Show();
}
bool initDevice(char *m_serverName, const char *ccfpath) {
printf("Sapera Console Grab Example (C++ version)\n");
//采集卡索引
SapLocation loc(m_serverName, 0);
//获取采集卡上可用资源的数量,该函数返回一个整数值,表示可用资源的数量。
if (SapManager::GetResourceCount(m_serverName, SapManager::ResourceAcq) > 0) {
//初始化
m_Acquisition = new SapAcquisition(loc, ccfpath);
m_Buffers = new SapBufferWithTrash(2, m_Acquisition);
//m_View = new SapView(m_Buffers, SapHwndAutomatic);
m_Xfer = new SapAcqToBuf(m_Acquisition, m_Buffers, XferCallBack);/*,m_View*);*/
}
//下面是一些初始化的参数的判断
if (m_Acquisition && !*m_Acquisition && !m_Acquisition->Create()) return FALSE;
if (m_Buffers && !*m_Buffers) {
if (!m_Buffers->Create()) {
return FALSE;
}
m_Buffers->Clear();
}
//if (m_View && !*m_View && !m_View->Create()) {
// return FALSE;
//}
// Set next empty with trash cycle mode for transfer
if (m_Xfer && m_Xfer->GetPair(0)) {
if (!m_Xfer->GetPair(0)->SetCycleMode(SapXferPair::CycleNextWithTrash)) {
return FALSE;
}
}
// Create transfer object 创建传输对象
if (m_Xfer && !*m_Xfer && !m_Xfer->Create()) {
return FALSE;
}
return true;
}
int image_delete_black(Mat *p) {
Mat img = *p;
for (int i = 0; i < img.rows; ++i) {
double row_sum = 0;
for (int j = 0; j < img.cols; ++j) {
row_sum += static_cast<double>(img.at<uchar>(i, j)); // 计算当前行所有像素的和
}
double average = row_sum / img.cols; // 计算当前行的平均值
if (average != 0.0) { // 如果平均值不等于0,则截取从这一行到图片底部的所有行
cropped_img = img(cv::Rect(0, i, img.cols, img.rows - i));
break; // 找到第一个非零均值行后即可停止循环
}
}
return 0;
}
int camera_init()
{
BYTE* pData;
//cout << "Hello CMake." << endl;
char* m_SerName = new char[MAX_PATH];//采集卡名称
string ccf_path = CAMERA_CONFIG;
//返回当前正在使用的采集卡的名称。此功能可用于确定摄像机正在使用的采集卡,并更改正在使用的采集卡。
m_pManager->GetServerName(0, SapManager::ResourceAcq, m_SerName);
//初始化设备
if (initDevice(m_SerName, ccf_path.c_str())) {
cout << "Open " << m_SerName << " Success!" << endl;
}
else {
printf("m_SerName: %s \n", m_SerName);
printf("configFilename: %s \n", ccf_path);
cout << "Open " << m_SerName << " Failed!" << endl;
return -1;
}
//开始采集
if (!m_Xfer->IsGrabbing()) {
std::cout << "Grab" << std::endl;
m_Xfer->Grab();
m_Buffers->GetAddress((void**)&pData);
int width = m_Buffers->GetWidth();
int height = m_Buffers->GetHeight();
}
m_Xfer->Freeze();
return 0;
}
void camera_release() {
// Destroy transfer object
if (m_Xfer && *m_Xfer) m_Xfer->Destroy();
// if (m_View && *m_View) m_View->Destroy();
if (m_Buffers && *m_Buffers) m_Buffers->Destroy();
if (m_Acquisition && *m_Acquisition) m_Acquisition->Destroy();
//Delete all pointer
//if (m_View) delete m_View;
if (m_Buffers) delete m_Buffers;
if (m_Xfer) delete m_Xfer;
if (m_Acquisition) delete m_Acquisition;
}
void open_dalsa_camera() {
if (!m_Xfer->IsGrabbing()) {
m_Xfer->Grab();
}
}
void close_dalsa_camera() {
if (m_Xfer->IsGrabbing()) {
m_Xfer->Freeze();
}
}
void abort_dalsa_camera() {
if (m_Xfer->IsGrabbing()) {
m_Xfer->Abort();
}
}
void wait_dalsa_camera(int time) {
if (m_Xfer->IsGrabbing()) {
m_Xfer->Wait(time);
}
}
void save_camera_image() {
std::stringstream save_path;
static int framcount = 0;
save_path.clear();
save_path << SVAE_IMAGE_PATH << "\\print" << framcount << ".bmp";
const char* savename = save_path.str().c_str();
printf("savename : %s \n ", savename);
framcount++;
cv::imwrite(savename, cropped_img);
}
void get_camera_image(Mat *get_image) {
if (cropped_img.empty())
{
return;
}
*get_image = cropped_img.clone();
}
bool get_camera_status() {
if (m_Acquisition && m_Acquisition->IsSignalStatusAvailable())
{
return 1;
std::cout << "camera connect succeed " << std::endl;
}
else {
return 0;
std::cout << "camera connect fail" << std::endl;
}
}
dasla的sdk代码网上太难搞了,陆陆续续搞了一个月,大家随便看看,还请指正。