An advanced in-memory image visualization plugin for GDB and LLDB on Linux, with experimental support for MacOS and Windows. Previously known as gdb-imagewatch.
Open Image Debugger is a tool for visualizing in-memory buffers during debug
sessions, compatible with both GDB and LLDB. It works out of the box with
instances of the OpenCV Mat
class and Eigen
matrices, but can also be
customized to work with any arbitrary data structure.
[0, 1]
, where 0
represents black and 1
represents white.apt install
Note: this list might get out-of-date by accident. For a more accurate list of requirements, please check what is used in https://github.com/OpenImageDebugger/OpenImageDebugger/blob/main/.github/workflows/build.yml.
On Ubuntu, you can install most of the dependencies with the following command:
sudo apt install build-essential libpython3-dev python3-dev cmake
Clone the source code to any folder you prefer and initialize the submodules:
git clone https://github.com/OpenImageDebugger/OpenImageDebugger.git
cd OpenImageDebugger
git submodule init
git submodule update
Now run the following commands to build it:
cmake -S . -B build -DCMAKE_INSTALL_PREFIX=/path/to/installation/folder
cmake --build build --config Release --target install -j 4
GDB integration: Edit the file ~/.gdbinit
(create it if it doesn't exist)
and append the following line:
source /path/to/OpenImageDebugger/oid.py
LLDB integration: Edit the file ~/.lldbinit
(create it if it doesn't
exist) and append the following line:
command script import /path/to/OpenImageDebugger/oid.py
For information on how to build the plugin on MacOS, refer to the wiki page Building on MacOS.
After compiling the plugin, you can test it by running the following command:
python /path/to/OpenImageDebugger/oid.py --test
If the installation was succesful, you should see the Open Image Debugger window
with the buffers sample_buffer_1
and sample_buffer_2
.
If you are using QtCreator, you can change your Qt version under Tools->Options->Build & Run->Kits. Make sure you have Qt >= 5.6 selected.
When the debugger hits a breakpoint, the Open Image Debugger window will be
opened. You only need to type the name of the buffer to be watched in the
"add symbols" input, and press <enter>
.
The (min) and (max) fields on top of the buffer view can be changed to control autocontrast settings. By default, Open Image Debugger will automatically fill these fields with the mininum and maximum values inside the entire buffer, and the channel values will be normalized from these values to the range [0, 1] inside the renderer.
Sometimes, your buffer may contain trash, uninitialized values that are either too large or too small, making the entire image look flat because of this normalization. If you know the expected range for your image, you can manually change the (min) and (max) values to focus on the range that you are interested.
Sometimes you want to compare two buffers being visualized, and need to zoom in
different places of these buffers. If they are large enough, this can become a
very hard task, especially if you are comparing pixel values. This task is made
easier by the lock buffers
tool (which is toggled by the button with a chain
icon).
When it is activated, all buffers are moved/zoomed simultaneously by the same
amount. This means you only need to align the buffers being compared once;
after activating the lock buffers
mode, you can zoom in anywhere you wish in
one buffer that all other buffers will be zoomed in the same location.
If you need to quickly move to any pixel location, then the go to
functionality is what you are looking for. Press Ctrl+L and two input fields
corresponding to the target destination in format <x, y>
will appear at the
bottom right corner of the buffer screen. Type the desired location, then press
enter to quickly zoom into that location.
Sometimes you may want to export your buffers to be able to process them in an external tool. In order to do that, right click the thumbnail corresponding to the buffer you wish to export on the left pane and select "export buffer".
Open Image Debugger supports two export modes. You can save your buffer as a PNG
(which may result in loss of data if your buffer type is not uint8_t
) or as a
binary file that can be opened with any tool.
Buffers exported in the Octave matrix
format can be loaded with the function
oid_load.m
, which is available in the matlab
folder. To use it, add this
folder to Octave/Matlab path
variable and call
oid_load('/path/to/buffer.dump')
.
The settings file for the plugin can be located under
$HOME/.config/OpenImageDebugger.ini
. You can change the following settings:
left
Default value.right
top
bottom
true
Places min/max intensity controller in the same row with the toolbar.false
Places min/max intensity controller below the toolbar. Default value.rgba
Default value.bgra
By default, the plugin works with several data types, including OpenCV's Mat
and CvMat
and Eigen's Matrix
.
If you use a different buffer type, you can create a python parser inside the
folder resources/oidscripts/oidtypes
. This is actually pretty simple and
only involves implementing a class according to the interface
TypeInspectorInterface
defined in
resources/oidscripts/oidtypes/interface.py
. This interface only defines the
methods get_buffer_metadata()
and is_symbol_observable()
.
The function get_buffer_metadata()
must return a dictionary with the following
fields:
1 <= channels <= 3
)resources/oidscripts/symbols.py
, are:
OID_TYPES_UINT8
= 0OID_TYPES_UINT16
= 2OID_TYPES_INT16
= 3OID_TYPES_INT32
= 4OID_TYPES_FLOAT32
= 5OID_TYPES_FLOAT64
= 6'bgra'
, and 'rgba'
for images of 1 and 2 channels. This string must
contain exactly four characters, and each one must be one of 'r'
, 'g'
,
'b'
or 'a'
. Repeated channels, such as 'rrgg' are also valid.The function is_symbol_observable()
receives a symbol and a string
containing the variable name, and must only return True
if that symbol is of
the observable type (the buffer you are dealing with).
It is possible to debug your custom inspector methods by using the python
decorators @interface.debug_buffer_metadata
and
@interface.debug_symbol_observable
in the methods get_buffer_metadata
and
is_symbol_observable
, respectively. This will print information about all
analyzed symbols in the debugger console every time a breakpoint is hit.