English | 简体中文
A desktop acquisition console for synchronized four-camera recording and dual-foot pressure sensor visualization.
This project is a Python + PyQt5 desktop application that combines:
- four-channel Hikrobot MVS GigE industrial camera preview
- synchronized recording and snapshot capture
- dual-foot pressure sensor acquisition over USB serial
- real-time heatmap visualization
- session-based file output
- runtime memory monitoring for large buffered recordings
This GitHub repository contains the complete Python application, runtime assets, and deployment scripts needed for acquisition and packaging.
The current main window is organized into three layers:
- A compact top toolbar for subject name, trial index, recording control, snapshot, settings, and current status.
- A central work area with resizable four-camera views on the left and dual-foot pressure heatmaps on the right.
- A bottom information zone for runtime status, memory monitoring, and pressure sensor state/log feedback.
This layout is optimized for live acquisition workflows where operators need to watch video, sensor response, and system health at the same time.
The images below are illustrative previews generated from the current UI layout, including the updated shoe-sole pressure contour visualization.
| Module | Description |
|---|---|
| Four-camera preview | Live previews for channels 1 / 2 / 3 / 4, with resizable panes |
| Recording and snapshots | Recording exports mp4 + per-frame images; snapshots are stored in the image/ directory |
| Dual-foot pressure capture | Independent left/right serial sensors with fixed-size binary frame parsing |
| Real-time heatmaps | Pressure heatmaps are rendered live in the main window |
| Session-based storage | Each recording creates its own subject/trial directory |
| Memory monitoring | Tracks system memory, process memory, and recording buffer estimates |
| Path | Purpose |
|---|---|
python_app/ |
Main application package |
python_app/ui/ |
Main window, settings dialog, styles, and visualization widgets |
python_app/mvs.py |
Hikrobot MVS GigE SDK adapter and pixel conversion layer |
python_app/mvs_vendor/ |
Bundled MVS Python ctypes wrapper files |
foot_sensor_layout/ |
Shoe-sole contour and sensor-point CSV assets used by the pressure visualization |
pressure_sensor_layout/ |
Foot pressure sensor layout definitions used for heatmap point placement |
python_app/assets/branding/ |
Logo, wordmark, and application icon assets |
docs/screenshots/ |
README interface preview images |
python_app/tests/ |
Basic configuration tests |
scripts/ |
Helper scripts for branding assets, README previews, portable runtime staging, driver install, and release packaging |
run_python_app.py |
Application entry point |
settings.json |
Default runtime configuration |
SubjectList.txt |
Subject list used by the UI |
- Windows 10/11 64-bit
- Python 3.13+ (64-bit)
- Hikrobot MVS Runtime files
- PyQt5
- opencv-python
- pyserial
- numpy
- av
- psutil
Install dependencies:
python -m pip install -r requirements.txtThis application now supports an app-local MVS runtime. It searches in this order:
runtime/mvs/Win64_x64/next torun_python_app.pyor the packaged.exeC:\Program Files (x86)\Common Files\MVS\Runtime\Win64_x64
That means you can either:
- install Hikrobot MVS on the machine, or
- copy the runtime DLL folder into
runtime/mvs/Win64_x64/inside this project or packaged release
Start the application:
python run_python_app.pyRegenerate branding assets only:
python scripts/generate_branding_assets.pyRegenerate README preview images:
python scripts/generate_readme_screenshots.pyStage MVS runtime files into the current Software/ folder for portable copy:
powershell -ExecutionPolicy Bypass -File scripts/stage_mvs_runtime.ps1- Install 64-bit Python on the target machine.
- Copy the repository folder to the target machine.
- Install dependencies:
python -m pip install -r requirements.txt- Prepare the MVS runtime in one of these two ways:
- install Hikrobot MVS Runtime / Client on the target machine, or
- run
scripts/stage_mvs_runtime.ps1on the build machine first so the folder already containsruntime/mvs/Win64_x64/
- Review
settings.jsonand bind cameras by serial number if needed. - Launch:
python run_python_app.pyA Windows packaging helper is included:
powershell -ExecutionPolicy Bypass -File scripts/build_release.ps1This produces:
dist/ISCamRecorder-Python/— packaged application folderdist/ISCamRecorder-Python-YYYYMMDD-HHMMSS.zip— portable zip for delivery
The packaged output includes:
- the Python application
- UI assets and shoe-sole pressure contour resources
- pressure layout JSON files
- shoe-sole contour CSV files
- bundled MVS runtime DLLs under
runtime/mvs/Win64_x64/ - optional GigE driver installer files under
drivers/mvs_gige/ - default
settings.json SubjectList.txt- English and Chinese README files
The target machine does not need the full Hikrobot MVS Client when you use this packaged release, because the build script bundles the required MVS runtime DLLs. If GigE discovery or performance still needs the vendor network driver, run install_mvs_gige_driver.ps1 as administrator on the target machine.
The current camera backend is Hikrobot MVS GigE only. OpenCV index probing is no longer used for the four recording channels.
The recommended workflow is:
- Bind physical cameras from Settings -> Camera Mapping.
- Tune exposure, frame rate, gain, gamma, and black level from Settings -> Industrial Camera Parameters.
The matching configuration section in settings.json is camera_bindings[]. Each camera entry contains:
slot: internal slot identifierdevice_serial: stable camera serial number used for bindingoutput_id: saved channel label, currently1 / 2 / 3 / 4record_enabled: whether the camera participates in recordingsnapshot_enabled: whether the camera participates in snapshotsexposure_time_us: exposure time in microsecondsacquisition_frame_rate_fps: requested acquisition frame rategain_db: analog gaingamma_value: gamma correction valueblack_level: black level offset
Example:
{
"camera_bindings": [
{
"slot": "top",
"device_serial": "00C86123456",
"output_id": "1",
"record_enabled": true,
"snapshot_enabled": true,
"exposure_time_us": 20000.0,
"acquisition_frame_rate_fps": 30.0,
"gain_db": 0.0,
"gamma_value": 1.0,
"black_level": 0.0
},
{
"slot": "left",
"device_serial": "00C86123457",
"output_id": "2",
"record_enabled": true,
"snapshot_enabled": true,
"exposure_time_us": 20000.0,
"acquisition_frame_rate_fps": 30.0,
"gain_db": 0.0,
"gamma_value": 1.0,
"black_level": 0.0
}
]
}At runtime the UI still shows model name / user-defined name / serial / IP, but only the serial is written back to configuration so that camera bindings survive IP or display-name changes.
The parameter page reads the active camera node ranges when possible and constrains the controls to the detected limits. Exposure time and acquisition frame rate are also linked together: a longer exposure lowers the maximum achievable FPS, and a higher FPS target lowers the allowed exposure ceiling.
If the application cannot load MvCameraControl.dll, the UI will show an explicit SDK warning instead of crashing.
Pressure sensors are configured separately for the left and right foot in Settings -> Foot Pressure Sensors.
The current implementation expects fixed-size binary frames. Each sensor entry currently supports the following fields:
| Field | Description |
|---|---|
sensor_id |
Fixed to left_foot or right_foot |
enabled |
Whether this sensor is enabled |
port |
Serial port, such as COM3 |
baud_rate |
Serial baud rate |
frame_size_bytes |
Total bytes per frame |
frame_header_hex |
Optional frame header used for frame resynchronization |
layout_file |
JSON layout file that maps each sensor point to a heatmap coordinate |
Example:
{
"pressure_sensors": [
{
"sensor_id": "left_foot",
"enabled": true,
"port": "COM4",
"baud_rate": 115200,
"frame_size_bytes": 111,
"frame_header_hex": "FF66",
"layout_file": "pressure_sensor_layout/left_foot.json"
},
{
"sensor_id": "right_foot",
"enabled": true,
"port": "COM5",
"baud_rate": 115200,
"frame_size_bytes": 111,
"frame_header_hex": "FF66",
"layout_file": "pressure_sensor_layout/right_foot.json"
}
]
}The layout files in pressure_sensor_layout/ define how the 1D sensor values are expanded onto the rendered foot heatmap. If a layout file is missing or fails to load, the application falls back to a linear placement and writes a warning to the runtime log.
Each recording creates a dedicated session directory:
recYYYYMMDD_HHMMSS_<subject>_<trial>
A typical output structure looks like this:
rec20260325_213000_TestSubject_1/
├─ 1_20260325_213000.mp4
├─ 2_20260325_213000.mp4
├─ 3_20260325_213000.mp4
├─ 4_20260325_213000.mp4
├─ 1/
│ ├─ 1_213000.001.jpg
│ ├─ 1_213000.026.jpg
│ └─ ...
├─ 2/
├─ 3/
├─ 4/
└─ Pressure_20260325_213000.csv
Where:
1 / 2 / 3 / 4 .mp4are the recorded camera videos1 / 2 / 3 / 4 /contain exported frame imagesPressure_*.csvstores the pressure matrix data for both feet
Pressure data is stored in a long-table format so it is easy to analyze, resample, or visualize later.
| Column | Meaning |
|---|---|
timestamp |
Timestamp of the pressure frame |
elapsed_ms |
Milliseconds since recording start |
sensor_id |
left_foot or right_foot |
frame_index |
Frame index for that sensor |
grid_rows |
Matrix row count |
grid_cols |
Matrix column count |
row |
Row index of the current cell |
col |
Column index of the current cell |
raw_value |
Raw sensor value |
normalized_value |
Normalized value in the range 0.0 - 1.0 |
- Install dependencies.
- Launch the application.
- Bind the four cameras in Settings.
- Configure left and right foot serial ports and protocol parameters.
- Return to the main window and verify that camera previews and pressure heatmaps are updating correctly.
- Enter the subject name and confirm the trial index.
- Check runtime status, memory usage, and pressure sensor connectivity.
- Click
Start Recording. - Observe the four camera views and both foot heatmaps during acquisition.
- Click
Stop Recordingand wait for the save stage to finish.
- Verify that the session directory was created.
- Verify that all four
mp4files exist and are complete. - Verify that per-frame image directories were generated.
- Verify that
Pressure_*.csvcontains continuous records.
Run:
python -m pip install -r requirements.txtCheck the following first:
- the correct
device_nameis bound in Settings - the camera is not already occupied by another application
- Windows camera access is enabled for desktop applications
Check the following first:
- the sensor is enabled
- the serial port and baud rate are correct
frame_size_bytes,payload_offset,rows, andcolsmatch the real sensor protocol- if the stream contains a frame header,
frame_header_hexis set correctly
The current design uses a buffer first, save later model. Long recordings and high-resolution streams can consume significant RAM.
Recommended mitigations:
- shorten a single recording session
- reduce camera resolution or frame rate
- watch the memory monitor before starting a very long acquisition
This repository is intended to be the maintained codebase for the Python desktop acquisition system.
If you plan to extend the project, the current repository is the recommended base for future work, for example:
- persisting splitter layouts
- adding more pressure sensor protocol adapters
- building data playback or export tools
- writing full hardware integration guides


