Pythonic Hikrobot MVS camera SDK wrapper for USB3 and GigE cameras
Project description
hgrabber-sdk
Small Python wrapper around Hikrobot MVS MvCameraControl for USB3 and GigE cameras.
Подробная документация по использованию: docs/USAGE.md.
The package vendors the official generated Python MvImport files from:
C:\Program Files (x86)\MVS\Development\Samples\Python\MvImport
The native Hikrobot MVS runtime is not bundled in this package. Install MVS separately on the
target machine, or point the package at the native library with HIK_CAMERA_SDK_MVS_LIBRARY.
Setup with uv
This project is configured for uv and pins Python through .python-version.
pip install hgrabber-sdk
uv sync --dev
uv run python -c "import hgrabber_sdk; print(hgrabber_sdk.__all__)"
uv run pytest
uv run python examples/list_devices.py
uv run python examples/gige_grab.py --ip 192.168.10.20
The import check does not load the native Hikrobot runtime. Commands that enumerate or open cameras
load MvCameraControl lazily.
Native MVS runtime
Install Hikrobot MVS from the official installer for the target OS.
The loader checks these locations in order:
HIK_CAMERA_SDK_MVS_LIBRARY: full path toMvCameraControl.dllorlibMvCameraControl.so.- Windows: the standard MVS runtime folder under
Common Files\MVS\Runtime, then normalPATH. - Linux:
MVCAM_COMMON_RUNENVpointing to a runtime root that contains64/libMvCameraControl.so,aarch64/libMvCameraControl.so, or another matching architecture directory. Common install paths such as/opt/MVS/libare also checked.
Windows override example:
$env:HIK_CAMERA_SDK_MVS_LIBRARY = "C:\Program Files (x86)\Common Files\MVS\Runtime\Win64_x64\MvCameraControl.dll"
Linux root example:
export MVCAM_COMMON_RUNENV=/opt/MVS/lib
Linux exact library override:
export HIK_CAMERA_SDK_MVS_LIBRARY=/opt/MVS/lib/64/libMvCameraControl.so
Build and publish
Build a pure Python wheel. It contains the wrapper code only, not Hikrobot's native runtime:
uv sync --dev
uv build
uv run --dev twine check dist\*
Upload to TestPyPI first, then PyPI:
uv run --dev twine upload --repository testpypi dist\*.whl
uv run --dev twine upload dist\*.whl
Linux Docker Smoke Test
Build the Linux image and run package tests without native MVS libraries:
docker build -t hgrabber-sdk-linux .
docker run --rm hgrabber-sdk-linux
To test the native Hikrobot SDK and camera discovery, install or extract the Linux MVS runtime on
the host and mount the runtime directory into /opt/mvs. The mounted directory must contain the
architecture subdirectory expected by the loader, for example:
/path/to/mvs-runtime/
64/libMvCameraControl.so
GigE camera discovery is easiest with host networking:
docker run --rm --network host \
-e MVCAM_COMMON_RUNENV=/opt/mvs \
-v /path/to/mvs-runtime:/opt/mvs:ro \
hgrabber-sdk-linux \
python examples/linux_smoke.py
For USB cameras, run on a real Linux host and pass USB devices through:
docker run --rm --network host --privileged \
-e MVCAM_COMMON_RUNENV=/opt/mvs \
-v /dev/bus/usb:/dev/bus/usb \
-v /path/to/mvs-runtime:/opt/mvs:ro \
hgrabber-sdk-linux \
python examples/linux_smoke.py
Docker Desktop/WSL may not expose industrial USB/GigE cameras reliably; use a native Linux host for hardware validation.
Supported flows
- USB3 and GigE discovery by serial number, user name, model name, or GigE IP.
- Synchronous grabbing with
GetImageBuffer. - Async polling worker.
asynciomethods for non-blocking application code.- Native SDK image callback mode.
- Continuous acquisition.
- Software trigger.
- Hardware line trigger:
Line0,Line1,Line2,Line3, with activation, delay, cache, debouncer. - GigE action trigger:
Action1with device/group keys and broadcast address. - PTP helpers for GigE: enable
GevIEEE1588, wait forMaster/Slave, latch timestamp, scheduled action command. - Multi-camera group API.
- Direct GenICam feature passthrough for extra settings.
Quick start
from hgrabber_sdk import HikCamera
config = (
HikCamera.builder("left")
.usb("02K09720174")
.settings(exposure_us=8000, gain=4.0, pixel_format="BayerRG8")
.continuous()
.build()
)
with HikCamera(config) as camera:
frame = camera.grab(timeout_ms=1000)
print(frame.width, frame.height, frame.pixel_format, frame.image.shape)
Software trigger
from hgrabber_sdk import HikCamera
config = (
HikCamera.builder("top")
.gige("192.168.10.20")
.software_trigger()
.settings(exposure_us=6000, gain=2.0)
.build()
)
with HikCamera(config) as camera:
frame = camera.grab() # sends TriggerSoftware, then waits for the frame
Threaded streaming
from hgrabber_sdk import HikCamera
def on_frame(frame):
print(frame.camera_name, frame.frame_number, frame.device_ticks)
config = HikCamera.builder("preview").usb("SERIAL").continuous().build()
with HikCamera(config) as camera:
camera.start_stream(on_frame)
frame = camera.next_frame(timeout_ms=1000)
start_async and stop_async are kept as compatibility aliases for the threaded API.
Asyncio grabbing
All blocking SDK calls have asyncio wrappers. They run the MVS calls in worker threads, so
MV_CC_GetImageBuffer, software trigger, PTP waits, and action commands do not block the event loop.
import asyncio
from hgrabber_sdk import HikCamera
async def main():
config = (
HikCamera.builder("cam")
.gige("192.168.10.20")
.software_trigger()
.build()
)
async with HikCamera(config) as camera:
frame = await camera.async_grab(timeout_ms=1000)
print(frame.frame_number)
asyncio.run(main())
For continuous streaming into an asyncio.Queue:
async with HikCamera(config) as camera:
frames = await camera.async_start_stream(queue_size=4)
frame = await asyncio.wait_for(frames.get(), timeout=2.0)
await camera.async_stop_stream(frames)
Native SDK callback
config = (
HikCamera.builder("callback")
.gige("192.168.10.21")
.sdk_callback()
.continuous()
.build()
)
Callback mode registers MV_CC_RegisterImageCallBackEx before MV_CC_StartGrabbing.
Line trigger
config = (
HikCamera.builder("io")
.usb("SERIAL")
.line_trigger("Line0", activation="RisingEdge", delay_us=0, line_debouncer_us=50)
.build()
)
For line-scan cameras, set another trigger selector:
.line_trigger("Line1", selector="LineStart")
Multi-camera GigE action/PTP
from hgrabber_sdk import HikCamera, HikCameraGroup
left = (
HikCamera.builder("left")
.gige("192.168.10.21")
.ptp(wait_synchronized=True)
.action_trigger(device_key=1, group_key=1, group_mask=1)
.build()
)
right = (
HikCamera.builder("right")
.gige("192.168.10.22")
.ptp(wait_synchronized=True)
.action_trigger(device_key=1, group_key=1, group_mask=1)
.build()
)
with HikCameraGroup([left, right]) as cameras:
cameras.start_async(queue_size=4)
results = cameras.issue_action_after(delay_ticks=10_000_000)
frames = {name: camera.next_frame(timeout_ms=2000) for name, camera in cameras.cameras.items()}
Asyncio group variant:
async with HikCameraGroup([left, right]) as cameras:
queues = await cameras.async_start_stream(queue_size=4)
await cameras.async_issue_action_after(delay_ticks=10_000_000)
frames = {
name: await asyncio.wait_for(queue.get(), timeout=2.0)
for name, queue in queues.items()
}
delay_ticks is in camera timestamp ticks. On most GigE Vision PTP setups this is nanoseconds,
but validate this against the exact camera model before using scheduled actions in production.
Raw feature passthrough
Any extra GenICam feature can be passed through the builder:
config = (
HikCamera.builder("cam")
.gige("192.168.10.20")
.feature("GammaEnable", True)
.feature("Gamma", 0.7)
.feature("AcquisitionBurstFrameCount", 3)
.build()
)
String values are first attempted as enum symbols and then as string nodes.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file hgrabber_sdk-0.1.4.tar.gz.
File metadata
- Download URL: hgrabber_sdk-0.1.4.tar.gz
- Upload date:
- Size: 119.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e67fcd0927e4381e1091ce1528a8094ce62197cd6b0a95d77cee9eca68bd728c
|
|
| MD5 |
a6c12c0f30b2ee8a675b16ea3f28d2e2
|
|
| BLAKE2b-256 |
ffdfbc7153ca3d6bcdac68099c92d4ae62bc9276ad3d9f61ca335d581f5fdd38
|
File details
Details for the file hgrabber_sdk-0.1.4-py3-none-any.whl.
File metadata
- Download URL: hgrabber_sdk-0.1.4-py3-none-any.whl
- Upload date:
- Size: 62.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e906c9b92f3a58d4b8f99f4c9a8da0608399f6f4ca3b76cc8bcdd07effb95155
|
|
| MD5 |
4d177af11cf84ef292f0f5d1ad52834a
|
|
| BLAKE2b-256 |
21924598bcddbf61514c9af1b5c4d0cd648d01b9452b8ecc2539ccefd1b5ae44
|