I’m trying to build a fake camera source with my own specific pattern using opencv. However the camera starts but seems to never get picked up by the arvtools/arvviewer.
Here’s my code:
#include <arv.h>
#include <glib.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <signal.h>
// Define image properties
#define WIDTH 320
#define HEIGHT 240
#define PIXEL_FORMAT ARV_PIXEL_FORMAT_MONO8 // Using MONO8 for simplicity
struct FillPatternData {
guint64 frame_counter;
int width;
int height;
};
// Correct callback signature matching ArvFakeCameraFillPattern
void fill_pattern_callback(ArvBuffer *buffer, void *user_data, guint32 width,
guint32 height, guint32 padding_x) {
FillPatternData *data = static_cast<FillPatternData *>(user_data);
// Generate a new 8-bit grayscale image using OpenCV
cv::Mat gray_image(data->height, data->width, CV_8UC1, cv::Scalar(0));
// Create a dynamic pattern that changes with frame_counter
// For simplicity, we'll create a moving horizontal gradient
for (int y = 0; y < data->height; y++) {
for (int x = 0; x < data->width; x++) {
gray_image.at<uchar>(y, x) =
static_cast<uchar>((x + data->frame_counter) % 256);
}
}
// Get the buffer data pointer and size
size_t buffer_size;
void *buffer_data = (void *)arv_buffer_get_data(buffer, &buffer_size);
if (!buffer_data) {
std::cerr << "Failed to get buffer data" << std::endl;
return;
}
// Ensure that the generated image fits into the buffer
size_t image_size = data->width * data->height; // 1 byte per pixel for MONO8
if (image_size > buffer_size) {
std::cerr << "Image size exceeds buffer size. Image size: " << image_size
<< ", Buffer size: " << buffer_size << std::endl;
return;
}
// Copy the grayscale image data into the buffer
memcpy(buffer_data, gray_image.data, image_size);
// Increment frame counter
data->frame_counter++;
}
static gboolean stop = FALSE;
static void control_c_signal(int signal) { stop = TRUE; }
int main(int argc, char **argv) {
// Initialize the type system (required by GObject in older GLib versions)
#if !GLIB_CHECK_VERSION(2, 35, 0)
g_type_init();
#endif
// Initialize Aravis
arv_update_device_list();
// Set the GenICam XML file for the fake camera
arv_set_fake_camera_genicam_filename("fake_camera_genicam.xml");
// Create a fake GigE Vision camera
ArvFakeCamera *gv_fake_camera =
arv_fake_camera_new_full("3", "fake_camera_genicam.xml");
if (!gv_fake_camera) {
std::cerr << "Failed to create fake camera" << std::endl;
return EXIT_FAILURE;
}
// Initialize fill pattern data
FillPatternData fill_data;
fill_data.frame_counter = 0;
fill_data.width = WIDTH;
fill_data.height = HEIGHT;
// Set fill pattern callback with the correct signature
arv_fake_camera_set_fill_pattern(ARV_FAKE_CAMERA(gv_fake_camera),
fill_pattern_callback, &fill_data);
// Set trigger frequency (frame rate)
arv_fake_camera_set_trigger_frequency(ARV_FAKE_CAMERA(gv_fake_camera),
10.0); // 10 FPS
std::cout << "Fake Aravis camera is running. Press Ctrl+C to stop."
<< std::endl;
// Handle SIGINT and SIGTERM to allow graceful exit
signal(SIGINT, control_c_signal);
signal(SIGTERM, control_c_signal);
// Create and run the main loop
GMainLoop *main_loop = g_main_loop_new(NULL, FALSE);
// Run the main loop until interrupted
while (!stop) {
g_main_context_iteration(NULL, FALSE);
}
// Cleanup
g_main_loop_unref(main_loop);
g_object_unref(gv_fake_camera);
return EXIT_SUCCESS;
}
The xml context I used:
<?xml version="1.0" encoding="UTF-8"?>
<GenICamXML>
<Device>
<DeviceModelName>Fake_Aravis_Camera</DeviceModelName>
<DeviceVendorName>FakeVendor</DeviceVendorName>
<SerialNumber>3</SerialNumber>
<!-- Pixel Format Enumeration -->
<PixelFormat>
<EnumEntry name="Mono8">
<Value>0x01080001</Value> <!-- Standard GenICam value for Mono8 -->
</EnumEntry>
<!-- You can add more pixel formats here if needed -->
</PixelFormat>
<!-- Width Parameter -->
<Width>
<Int64Min>1</Int64Min>
<Int64Max>800</Int64Max>
<Int64Inc>1</Int64Inc>
<Int64Default>320</Int64Default>
</Width>
<!-- Height Parameter -->
<Height>
<Int64Min>1</Int64Min>
<Int64Max>600</Int64Max>
<Int64Inc>1</Int64Inc>
<Int64Default>240</Int64Default>
</Height>
<!-- Trigger Frequency Parameter -->
<TriggerFrequency>
<FloatMin>0.0</FloatMin>
<FloatMax>1000.0</FloatMax>
<FloatInc>0.1</FloatInc>
<FloatDefault>10.0</FloatDefault>
</TriggerFrequency>
<!-- Acquisition Mode Enumeration -->
<AcquisitionMode>
<EnumEntry name="Continuous">
<Value>0</Value>
</EnumEntry>
<EnumEntry name="SingleFrame">
<Value>1</Value>
</EnumEntry>
<EnumEntry name="MultiFrame">
<Value>2</Value>
</EnumEntry>
</AcquisitionMode>
<!-- Add more parameters as needed -->
</Device>
<GenICamXML/>
I can’t get the camera to appear in the viewer or Arvtoos
I’m working on:
- Aravis version 0.8.33
- OS: 5.10.192-tegra
- Hardware arm64