Open Camera
Task goal
Explain clearly "where event data comes from". An event camera has two typical entry points; choosing the right one is the prerequisite for all subsequent processing:
| Entry point | Use case | Classes involved |
|---|---|---|
| Real-time camera (USB / MIPI / Ethernet) | Real-time capture | Shimeta::hv::Camera + Shimeta::hv::DeviceConfig |
| Recording file | Offline analysis, no-hardware debugging | Shimeta::io::EventReader |
In v2.0 the three backends (USB / MIPI / Ethernet) are unified into a single
CameraAPI; the backend is selected viaDeviceConfig.backend, and there are no longer separate USB / MIPI camera classes.
Entry 1: Real-time camera
Unified lifecycle: construct Camera → fill in DeviceConfig → Init(cfg) → StartStream() → get frames / register callbacks → StopStream() → Destroy(). Init does not block on opening the hardware; the actual connection happens in StartStream.
USB camera (x86_64)
The USB backend selects the device by VID/PID:
#include <shimetapi/hv/camera.h>
#include <shimetapi/hv/device_config.h>
#include <iostream>
int main() {
Shimeta::hv::Camera cam;
Shimeta::hv::DeviceConfig cfg;
cfg.backend = Shimeta::hv::Backend::Usb;
cfg.vendor_id = 0x1d6b; // Replace with your device's actual VID/PID
cfg.product_id = 0x0105;
cfg.event_fmt = Shimeta::hv::EventFormat::Evt2;
cam.Init(cfg);
if (!cam.StartStream()) {
std::cerr << "打开相机失败,请检查 USB 连接与权限。" << std::endl;
return 1;
}
std::cout << "相机已就绪" << std::endl;
// Get frames with GetFrame / register a callback here; see Guide 02
Shimeta::Frame f;
while (cam.GetFrame(f, 1000)) { /* f.evs / f.aps */ }
cam.StopStream();
cam.Destroy();
return 0;
}USB permissions
If the first run reports Cannot open device: LIBUSB_ERROR_ACCESS, the recommended fix is a udev rule (no sudo needed, persistent):
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="1d6b", ATTR{idProduct}=="0105", MODE="0666"' \
| sudo tee /etc/udev/rules.d/99-hv-camera.rules
sudo udevadm control --reload-rules && sudo udevadm triggerFull troubleshooting (no match devices found, VID/PID confirmation, etc.) at Toolkit — Troubleshooting.
MIPI camera (ARM64 / RDK)
MIPI is not a USB device: instead of VID/PID, it is opened with a sensor index, a device node, and an I2C bus. Choose the backend Backend::Mipi (EVS events only) or Backend::MipiHvs (dual VC: VC0 events + VC1 APS):
#include <shimetapi/hv/camera.h>
#include <shimetapi/hv/device_config.h>
int main() {
Shimeta::hv::Camera cam;
Shimeta::hv::DeviceConfig cfg;
cfg.backend = Shimeta::hv::Backend::MipiHvs; // or Backend::Mipi (events only)
cfg.device_node = "/dev/video0";
cfg.sensor_index = 9; // Current apx003cc config on S100; X5 uses the index configured in its SDK (49 in the current sample)
cfg.i2c_bus = 1; // I2C bus for secure-chip authentication
cfg.evs_fps = 0; // 0 = default 240; optional 120/240/300/500/750/1000
cam.Init(cfg);
if (!cam.StartStream()) return 1;
// Frame capture: see Guides 02 / 07; note that MipiHvs Frame.evs is a RAW8
// sub-frame stream that must be decoded with MipiRaw8Decoder (see Guide 02 / MIPI API)
cam.StopStream();
cam.Destroy();
return 0;
}sensor_index / i2c_bus must match the carrier board and sensor — do not copy the values from the USB example. The MIPI backend is ARM-only and requires cross-compiling against the RDK sysroot (build instructions at Toolkit — Quick Start); USB permission and lsusb troubleshooting do not apply, and you should also make sure no other process is using the sensor. Full MIPI differences at Toolkit C++ API — MIPI.
| Platform | Release libs | MIPI HVS events | MIPI HVS APS | Build target |
|---|---|---|---|---|
| S100 | lib/s100 | RAW8, MipiRaw8Decoder | NV12 | ./run.sh build s100 |
| X5 | lib/x5 | RAW8, MipiRaw8Decoder | Gray8 | ./run.sh build x5 |
Both platforms share the same API, but you must use the prebuilt libraries and SDK/sysroot for the corresponding architecture; do not copy S100 libraries or sensor indices to the X5.
The minimal runnable example corresponds to samples/cpp/get_started in the repo: ./hv_sample_get_started (USB, default 0x1d6b:0x0105) or ./hv_sample_get_started --mipi (MIPI).
Ethernet camera (DVS1 protocol)
The Ethernet backend connects via IP + port (POSIX TCP, no extra dependencies):
Shimeta::hv::Camera cam;
Shimeta::hv::DeviceConfig cfg;
cfg.backend = Shimeta::hv::Backend::Ethernet;
cfg.ip = "192.168.1.100"; // Camera IP
// data_port=8000 / ctrl_port=8001 are the defaults; when the camera acts as the server, use listen_port / bind_ip instead
cam.Init(cfg);
cam.StartStream();Entry 2: Recording file
For offline scenarios, use Shimeta::io::EventReader to open a RAW file; it auto-detects EVT2/EVT3 from the file header's ev_version. Check the resolution and format first:
#include <shimetapi/io/event_reader.h>
#include <iostream>
int main() {
Shimeta::io::EventReader reader;
if (!reader.open("events.raw")) {
std::cerr << "打开事件文件失败" << std::endl;
return 1;
}
auto [width, height] = reader.imageSize();
std::cout << "格式: " << static_cast<int>(reader.format()) << "\n" // 0=Evt2, 1=Evt3
<< "分辨率: " << width << " x " << height << std::endl;
// Reading and decoding events: Guide 02; replay: Guide 03
reader.close();
return 0;
}File formats (EVT2 / RAW8 / CSV) and conversion at Data Formats; sample recordings at Downloads.
Further reading
- Full API: Toolkit C++ API
- How to use the data you read: Guide 02 — Read Events
- Preview without writing code: MultiVision Studio
About the Metavision / OpenEB ecosystem
The v2.0 toolkit is fully decoupled from third-party event SDKs and no longer ships a Metavision HAL plugin (the old flow of copying libhal_camera_hal.so into the Metavision plugin directory no longer works). If you need to use it within the Metavision ecosystem, see Hybrid Vision Algo.
