/rvimage

Remote image viewer in Rust

Primary LanguageRustMIT LicenseMIT

Crate CI workflow dependency status

RV Image

RV Image is a remote viewer for images written in Rust. You can view images, e.g., on remote SSH servers or Azure blob storages. Further, RV Image comes with a bounding box, polygon, and brush labeling tool supporting import and export of the Coco-format. So far tested on Windows 10, WSL, and Mac OS. RV Image is mainly based on egui and image.

rvimage_screen

Installation

We have a few pre-built binaries for Windows and MacOS on the releases page.

With Rust installed you can also

cargo install rvimage

to install the latest stable release.

Connect to remote

RV Image connects to

  • SSH/SCP using the ssh2 crate,
  • local folders that might be mounts of remote storage,
  • http-servers spawned via python -m http.server, and
  • Azure blob storages*.

Example configuration for the connection types can be found below. Images are cached locally in a temporary directory.

Optional http navigation server

When RV Image is started, also an http server is launched as aditional navigation option besides the graphical user interface. The default address is 127.0.0.1:5432. If occupied, the port will be increased. When sending a get-request to /file_label the image file_label is loaded. For this to work, file_label must be in the currently opened folder.

Configuration

When you start RV Image for the first time, a config-file rv_cfg.toml in %USERPROFILE%/.rvimage/rv_cfg.toml (or probably $HOME/.rvimage/rv_cfg.toml under Linux, untested) is created for you. In the following we describe some of the options. For SSH currently, only authorization with key-files without passphrase is supported.

 # We support the connections "Local", "Ssh", "PyHttp", or "AzureBlob"
connection = "Ssh"

# "NoCache" for not caching at all or "FileCache" for caching files in a temp dir.
cache = "FileCache"  

# Address of the http control server, default is 127.0.0.1:5432
# http_address = address:port

# If you do not want to use the temporary directory of your OS, you can add something else.
# tmpdir = 

[file_cache_args]
n_prev_images = 2  # number of images to be cached previous to the selected one
n_next_images = 8  # number of images to be cached following the selected one
n_threads = 4  # number of threads to be used for background file caching

[ssh_cfg]             
# Local folders can interactively be chosen via file dialog. Remote folders are restricted to one of the following list. 
remote_folder_paths = [
    "folder on your server", 
    "another folder"
]
address = "address:port"  # port is usually 22
user = "your username"
ssh_identity_file_path = "somepath/.ssh/id_file_with_private_key"

[py_http_reader_cfg]
# The server is expected to be started via `python -m http.server` in some folder.
# The content of this folder is than accessible.  
server_addresses = ['http://localhost:8000/']

[azure_blob_cfg]
# With a connection string you can view the images inside a blob storage.
# The connection_string_path should point to file that only contains the 
# connection string.
connection_string_path = ''
container_name = ''
# The prefix is also called folder in the Microsoft Azure Storage Explorer.
# Currently, you cannot choose this interactively.
prefix = ''


Labeling Tools

RV Image comes with two labeling tools:

  1. Draw bounding boxes and polygons and export in the Coco format.
  2. Draw brush lines and export as Coco-file with run-length-encodings. Thereby, we ignore the iscrowd=true convention that usually comes with run-length-encoded annotations in Coco-files.

All annotations are also stored in the project file in json format.

Besides labeling tools we also provide means to filter the images to select from and different ways to zoom in and out.

Zoom

You can zoom anytime with holding Ctrl and pressing + or -.

You can also use the separate zoom tool and draw a box on the image area you want to see enlarged.

To move the zoomed area hold Ctrl and drag with the left mouse button.

Filter Expressions for Image Files

You can filter for image files to appear in the left selection area. The entered string will reveal those images that contain the string in their pathname.

Besides based on the pathname, you can also filter based on the labels and attributes you have used:

  1. nolabel reveals all images that have not been labeled with the currently active tool.
  2. anylabel reveals all images that have been labeled with the currently active tool.
  3. label(<label-name>) reveals all images that have a label of the class <label-name> for the currently active tool. For instance, if the bounding box tool is active label(foreground) will reveal all images that contain bounding boxes or polygons of the class foreground. Some special characters in the label names might lead to troubles.
  4. tool(<tool-name>) reveals all images that have been labeled with the tool <tool-name>. For instance, tool(Brush) will reveal all images that have been labeled with the brush tool.
  5. attr(<attr-name>:<attr-val>) reveals all images that have the attribute <attr-name> set to <attr-val>.
  6. attr(<attr-name>:<attr-val-min>-<attr-val-max) reveals all images that have the attribute <attr-name> set between <attr-val-min> and <attr-val-max>.

Filter strings can be combined with &&, ||, and !. For instance

  • !nolabel corresponds to anylabel
  • 1055.png || label(cat) reveals all iamges that either have a 1055.png as part of their full pathname or contain the label cat from the currently active labeling tool.

Bounding Boxes and Polygons

RV Image comes with a simple bounding box and polygon labeling tool that can export to and import from the Coco format. For an import to work, the folder that contains the images needs to be opened beforehand. To filter for files that contain bounding boxes of a specific label, one can put label(<name-of-label>) into the filter text field. Thereby, <name-of-label> needs to be replaced by the real name of the label. To filter for unlabeled files use nolabel. Filters including filename-strings can be combined with &&, ||, and !.

There two main ways to draw a polygon or a box:

  1. One corner per left-click for a polygon. Finish by right-click. One left-click and one right-clicks for a box.
  2. Drag the left mouse button. A polygon will follow you mouse.
event action
drag and release left mouse draw polygon
first left click start drawing mode
$n$-th left click with $n&gt;1$ add polygon vertex
right click finish drawing box or polygon
Alt + left click during box/polygon drawing delete last vertex added
left click on corner of box start drawing mode and move vertex
Ctrl + left click on box select box
Alt + left click on box select box and deselect others and switch to currently selected label
hold right button move selected boxes
Shift + left click on box select all boxes with overlap with the maximal span of this box and other selected boxes
Ctrl + A select all boxes
Delete remove selected boxes
Ctrl + D deselect all boxes
Ctrl + H hide all boxes
C clone selected boxes at mouse position and move selection to new box
Ctrl + C copy all selected boxes to clipboard
Ctrl + V paste boxes without existing duplicate from clipboard
V activate auto-paste on image change
Left⬅/Right➡/Up⬆/Down⬇ move bottom right corner of all selected boxes
Ctrl + Left⬅/Right➡/Up⬆/Down⬇ move top left corner of all selected boxes
Alt + Left⬅/Right➡/Up⬆/Down⬇ move all selected boxes
change label labels of selected boxes/polygons are changed

Brush Tool

event action
left click draw circle if not in erase mode, else erase close brush stroke
hold left mouse draw brush if not in erase mode
E activate erase mode
Ctrl + click with left mouse select brush
Ctrl + C/V/A/H/D see bounding box tool
Delete delete selected strokes
change label labels of selected strokes are changed
T/I increase thickness/intensity
Alt + T/I decrease thickness/intensity

* The connection to Azure blob storages has tokio, futures, azure_storage, and azure_storage_blob as additional dependencies, since the used Azure SDK is implemented asynchronously and needs tokio. However, the rest of RV Image uses its own small threadpool implementation. Hence, the Azure blob storage connection is implemented as Cargo-feature azure_blob that is enabled by default.