Hi guys,
I am using the class camera below to communicate with a Dalsa gige camera.
I am using this class in this way inside a ROS node and it works fine when I just want to try and get one image periodically. I am using aravis 0.8
cv::Mat AcquireImageAravis(int exposure, std::string camSerialNo)
{
Camera cam2(camSerialNo,false);
//Camera cam2("S1171401",false);
cam2.setProperties("EXP_TIME", exposure);
cv::Mat img = cam2.snapFrame();
cam2.releaseCamera();
return img;
}
Now, I would like to get a live image every second in a seperate ROS node, by snapping an image, converting it to an opencv cv::Mat format as I am currently doing.
My questions are
-
Is there is a better way that what I have described to stream the images by building on the code i have? I still need to send each one as opencv mat.
-
From the initial tests I have done it seems very hit a miss as to whether I can get a connection to the camera when I ‘release’ one connection from one node in ROS to go to a connection in another node in ROS. Is there a best practice for this? Do I need a delay?
-
What happens when you try to connect to a camera and it is already in use? Can you forcefully take control?
#include "Camera.hpp"
Camera::Camera(bool automode){
camera = arv_camera_new(NULL, NULL);
if(camera != NULL){
std::cout << "Initialized ArvCamera@"<<camera << std::endl;
std::cout << "AUTO Prop Mode : " << automode << std::endl;
if(!automode){
disable_auto();
}
return;
}
camera = NULL;
return;
}
Camera::~Camera(){}
Camera::Camera(std::string camera_id, bool automode){
/*
params : camera_id : type string
camera_id : e.g. Aravis-GV01, TIS-11714131 (for The Imaging Source <Serial No> Cameras)
params : automode : type bool
automode: bool flag to enable or disable auto mode. (automode = true) for enabling auto mode.
*/
camera = arv_camera_new(camera_id.c_str(), NULL);
if(camera != NULL){
std::cout << "Initialized ArvCamera@"<<camera << std::endl;
std::cout << "AUTO Prop Mode : " << automode << std::endl;
if(!automode){
disable_auto();
}
return;
}
camera = NULL;
return;
}
void Camera::disable_auto(){
printf("Disable Auto Property\n");
arv_camera_set_exposure_time_auto(camera, ARV_AUTO_OFF, NULL);
arv_camera_set_gain_auto(camera, ARV_AUTO_OFF, NULL);
// write support for other properties
}
void Camera::setProperties(std::string property_name, double property_value){
if(property_name == "GAIN"){
arv_camera_set_gain(camera, property_value, NULL);
}else if(property_name == "EXP_TIME"){
arv_camera_set_exposure_time(camera, property_value, NULL);
}else if(property_name == "FPS"){
arv_camera_set_frame_rate(camera, property_value, NULL);
}
return ;
}
double Camera::getProperties(std::string property_name){
if(property_name == "EXP_TIME"){
return arv_camera_get_exposure_time (camera, NULL);
}
}
void Camera::setTrigger(bool val){
issetTrigger = val;
if(val){
arv_camera_set_trigger(camera, "Line1", NULL);
}
}
cv::Mat Camera::snapFrame()
{
void *framebuffer;
framebuffer = NULL;
IplImage *frame;
frame = NULL;
cv::Mat matImage;
buffer = arv_camera_acquisition (camera, 0, NULL);
if (ARV_IS_BUFFER (buffer)){
printf ("Image successfully acquired\n");
printf (" Converting Image to MAT\n");
IplImage src;
size_t buffer_size;
framebuffer = (void*)arv_buffer_get_data (buffer, &buffer_size);
cvInitImageHeader( &src, cvSize( 2464, 2056 ), IPL_DEPTH_8U, 1, IPL_ORIGIN_TL, 4 );
cvSetData(&src, framebuffer, src.widthStep);
if ( !frame || frame->width != src.width || \
frame->height != src.height || \
frame->depth != src.depth || \
frame->nChannels != src.nChannels) {
cvReleaseImage( &frame );
frame = cvCreateImage( cvGetSize(&src), src.depth, 1 );
}
cvCopy(&src, frame);
matImage = cv::cvarrToMat(frame);
}
else{
printf ("Failed to acquire a single image\n");
}
return matImage;
}
void Camera::releaseCamera(){
g_clear_object (&camera);
g_clear_object (&buffer);
}