Hello,
I am following the examples for using the aravis c++ library from here
https://github.com/AravisProject/aravis-c-examples
But I am not able to use the camera data for further processing.
Is there an example how to store the camera data as i.e bmp, jpg or how to fill an opencv mat object?
That is missing in the examples.
Thanks in advance.
Aravis does not handle this itself directly. This would be the procedure to follow (writing from thetop of my head):
-
pop new buffer from Aravis stream; if it is valid,continue;
-
get pixel format from buffer via arv_buffer_get_image_pixel_format
(or parts metadata, for multi-part buffers, via arv_buffer_get_part_pixel_format
); also get the image dimensions.
-
get the payload pointer (via arv_buffer_get_image_data
or arv_buffer_get_part_data
);
-
use all that to create cv::Mat around the existing payload (see e.g. here as an example).
-
use color conversions to convert the cv::Mat to your desired pixel format (such as RGB);
-
push the buffer back to Aravis (since onw you won’t use the original payload anymore) so that it can be re-used for incoming data.
-
work with your cv::Mat in the way you need now (e.g. save via imwrite
).
Thanks for the answer.
But I would need a complete example implementation.
The provided arv-viewer can do it.
There is this “take snapshot” function which allows me to store an image on disk.
It also takes care of the image data transformation. In my case the data is in BayerRG8 format.
I am able to get the buffer but then I am stuck.
I also tried some examples from the internet.
I.e. the one that stores the image as png.
https://github.com/szmoore/aravis-save-png/blob/master/arvsavepng.c
But when I try this example I just get an invalid png file and run in a segmentation fault.
Meanwhile I figured out how to process the buffer data I am getting from camera.
2 things I needed to add.
- Calling arv_buffer_get_data to get the proper image data
- Converting the image data to RGB
int main(int argc, char **argv)
{
ArvCamera *camera;
ArvBuffer *buffer;
GError *error = NULL;
/* Connect to the first available camera */
camera = arv_camera_new(NULL, &error);
if (ARV_IS_CAMERA(camera))
{
printf("Model name: '%s'\n", arv_camera_get_model_name(camera, NULL));
printf("Serial number: '%s'\n", arv_camera_get_device_serial_number(camera, NULL));
/* Acquire a single buffer */
buffer = arv_camera_acquisition(camera, 1000000, &error);
if (ARV_IS_BUFFER(buffer))
{
/* Display some informations about the retrieved buffer */
int width = arv_buffer_get_image_width(buffer);
int height = arv_buffer_get_image_height(buffer);
printf("Acquired %d×%d buffer\n", width, height);
int bit_depth = ARV_PIXEL_FORMAT_BIT_PER_PIXEL(arv_buffer_get_image_pixel_format(buffer));
printf("bit_depth: %d\n", bit_depth);
int arv_row_stride = width * bit_depth / 8;
printf("RowStride: %d\n", arv_row_stride);
size_t buffer_size;
void *framebuffer = (void *)arv_buffer_get_data(buffer, &buffer_size);
printf("buffer_size: %ld\n", buffer_size);
cv::Mat image(height, width, CV_8UC1, (unsigned char *)framebuffer);
//This is specific to the BayerRG8 format I am getting from the camera
cv::cvtColor(image, image, cv::COLOR_BayerRG2RGB);
// Save the image to a file
cv::imwrite("final_image.jpg", image);
/* Destroy the buffer */
g_clear_object(&buffer);
}
/* Destroy the camera instance */
g_clear_object(&camera);
}
if (error != NULL)
{
/* An error happened, display the correspdonding message */
printf("Error: %s\n", error->message);
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}