Skip to content

Commit

Permalink
Fix #16
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinitnelav committed Dec 27, 2022
1 parent d7e3896 commit 9b476b9
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 29 deletions.
54 changes: 30 additions & 24 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ How to use the free functionality of the [xlwings](https://www.xlwings.org/) lib

The Syrphid image was downloaded from [wikipedia](https://en.wikipedia.org/wiki/Hover_fly#/media/File:ComputerHotline_-_Syrphidae_sp._(by)_(3).jpg)

Why use Excel for image annotation workflows?
This is because it is familiar to many people, especially when you need to add many annotation metadata fields and filter data.

In our AI object detection project, we used [VGG Image Annotator (VIA)](https://www.robots.ox.ac.uk/~vgg/software/via/) to manually annotate insects in images, that is, manually place a bounding box and add record taxa information together with custom metadata. However, it is difficult to filter and edit metadata fields with VIA, while Excel is more user friendly for such tasks. Therefore, it was necessary to visualize the annotated images directly from Excel.
In our AI object detection project, we used [VGG Image Annotator (VIA)](https://www.robots.ox.ac.uk/~vgg/software/via/) to manually annotate insects in images, that is, manually place a bounding box and general taxa information. However, it is difficult to filter and edit metadata fields with VIA, while Excel is more user friendly for such tasks. Therefore, it was necessary to visualize the annotated images directly from Excel.

This repository provides the tools to view images directly from within Excel, together with the associated bounding box of an annotated object.

From within Excel, one can click on any row, and a Python script will read the image path together with the coordinates of the bounding box and display the image in a window together with the box placed on the object of interest.
From Excel, one can click on any row, and a Python script will read the image path together with the coordinates of the bounding box and display the image in a window together with the bounding box.

# Installation - How to make it work?
## Installation of dependencies (for Windows)

## Installation of xlwings addin (for Windows)

- The xlwings addin needs [conda](https://www.anaconda.com/products/distribution/start-coding-immediately) to be installed and with it, Python will also be installed. Follow this tutorial from Anaconda's documentation: [Installing on Windows](https://docs.anaconda.com/anaconda/install/windows/). To test if it is already installed, from the Start menu, open the Anaconda Prompt (or Anaconda Powershell Prompt), then type the command `conda list`. A list of installed packages should appear.
- You also need git installed and you can download the executable file from [here](https://git-scm.com/download/win)
Expand All @@ -32,7 +30,19 @@ From within Excel, one can click on any row, and a Python script will read the i
Type "help", "copyright", "credits" or "license" for more information.
>>>
```
- Clone this repository at your favorite location, for example, to `C:\Users\your_user_name\Documents` and then install the dependencies:
- Install the Excel add-in with the commands:
```sh
pip install xlwings
xlwings addin install
# You should see something like:
# xlwings version: 0.28.5
# Successfully installed the xlwings add-in!
```
- In a/any Excel file, you need to enable the macro options: menu File > Options > Trust Center > Trust Center Settings > Macro Settings > “Enable all macros...". For safety reasons, you can disable this after you are done with your work.
- In a/any Excel file enable the xlwings add-in: menu File > Options > Add-ins > button "Go..." (usually at the bottom, to the right of "Manage: Excel Add-ins"); Click “Browse” and search for a path similar to this one `C:\Users\you_user_name\AppData\Roaming\Microsoft\Excel\XLSTART`; Select the file `xlwings.xlam`; OK; YES (if asked to replace the existing file); OK again;
- At his point, you should see a new menu/tab named "xlwings" in the Excel file (after the Help menu/tab);
Optionally, if you prefer to run the boxel tool from command line, then clone this repository at your favorite location, for example, to `C:\Users\your_user_name\Documents` and then install the dependencies:
```sh
cd C:\Users\%USERNAME%\Documents
git clone https://github.com/valentinitnelav/img-with-box-from-excel
Expand All @@ -43,17 +53,6 @@ pip install -r requirements.txt
# If they are already installed, then you will see messages like:
# "Requirement already satisfied: ..."
```
- Then install the Excel add-in with the command
```sh
xlwings addin install
# You should see something like:
# xlwings version: 0.28.5
# Successfully installed the xlwings add-in!
```
- In a/any Excel file, you need to enable the macro options: menu File > Options > Trust Center > Trust Center Settings > Macro Settings > “Enable all macros...". For safety reasons, you can disable this after you are done with your work.
- In a/any Excel file enable the xlwings add-in: menu File > Options > Add-ins > button "Go..." (usually at the bottom, to the right of "Manage: Excel Add-ins"); Click “Browse” and search for a path similar to this one `C:\Users\you_user_name\AppData\Roaming\Microsoft\Excel\XLSTART`; Select the file `xlwings.xlam`; OK; YES (if asked to replace the existing file); OK again;
- At his point, you should see a new menu/tab named "xlwings" in the Excel file (after the Help menu/tab);
## Excel data structure:
- In our case, the annotation data can be stored in an Excel file (we'll call it further `data_file.xlsx`) in which each row represents information about a single bounding box.
Expand All @@ -65,11 +64,21 @@ xlwings addin install
## Run the tool
### Via the Graphical user interface (GUI)
### Via the Graphical User Interface (GUI)
Download the file `boxcel.exe` from this repository and save it anywhere on your computer.
Or if you already cloned this repository (see above), then navigate with Windows Explorer to the folder where you cloned this repository and there you find `boxcel.exe`. This file can be moved anywhere on your computer and it will still execute the Python tool with the associated GUI without the need of installing Python. However, the 3rd party software, xlwings addin, requires conda to be installed (see above).
Open `boxcel.exe`. Click the button "Browse & execute". Choose the desired Excel file (e.g. `data_file.xlsx`). The file must respect the mentioned data structure - see above. Click "Open", Then the tool will create the needed Python file (e.g. `data_file.py`) in the same folder with the Excel file. If successful, you will be notified with a message like "All good! Python code generated. Choose another file or close the application."
Open the Excel file, click on any cell, go to the xlwings menu, and press the green play button named "Run main". The tool will read the current row information with the image path from the column `windows_img_path`, the `id_box` and the box coordinates from `x`, `y`, `width` & `height` columns, and will display the image with its bounding box and a label with the box id.
It will work on any sheet in your `data_file.xlsx` file as long as it can find the required columns mentioned above and they contain valid values.
Alternatively, if all Python dependencies are in place you can also run the tool like this:
To make use of the GUI, navigate with Windows Explorer to the folder where you cloned this repository, then to the `img-with-box-from-excel\src\boxcel` and right-click on the `gui.py` file and choose "Open with..." then Python. This will start the GUI.
Navigate with Windows Explorer to the folder where you cloned this repository, then to the `img-with-box-from-excel\src\boxcel` and right-click on the `gui.py` file and choose "Open with..." then Python. This will start the GUI.
If this fails you can also start the GUI script from command line:
If the above fails, then you can also start the GUI script from command line:
```sh
# In a terminal/command line navigate to the cloned repository and then to the src/boxcel folder
cd C:\Users\%USERNAME%\Documents\img-with-box-from-excel\src\boxcel
Expand All @@ -93,9 +102,6 @@ python start_project.py path\to\your\data_file.xlsx # or python3 ...
```
This just created the `data_file.py` in the same folder with `data_file.xlsx`.
Open the Excel file, click on any cell, go to the xlwings menu, and press the green play button named "Run main". The tool will read the current row information with the image path from the column `windows_img_path`, the `id_box` and the box coordinates from `x`, `y`, `width` & `height` columns, and will display the image with its bounding box and a label with the box id.
It will work on any sheet in your `data_file.xlsx` file as long as it can find the required columns mentioned above and they contain valid values.
Additional resources for [xlwings](https://docs.xlwings.org/en/latest/) and the xlwings add-in:
- [How to Supercharge Excel With Python](https://towardsdatascience.com/how-to-supercharge-excel-with-python-726b0f8e22c2) by Costas Andreou;
Expand Down
41 changes: 36 additions & 5 deletions src/boxcel/start_project.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,43 @@
# Run the script like this:
# This is the main script that is executed when the user clicks the button
# "Browse & execute" in the GUI.
# The start_project function from this script is responsible for generating the
# Python code that enables the xlwings functionality for the Excel file.
# This script can also be executed from the command line like this:
# python3 start_project.py path/to/file.xlsx
# or
# python start_project.py path/to/file.xlsx

import sys
import os

# Function to get the absolute path to the current working directory
# This is to fix errors like this:
# "[Error 2] No such file or directory:
# 'C:\\Users\\user\\AppData\\Local\\Temp\\_MEI112962\\base_library.zip\\display_images.py'"
# This is because the script is executed from a temporary directory when using PyInstaller.
# PyInstaller creates a temp folder and stores path in _MEIPASS2 or ._MEIPASS
# See https://stackoverflow.com/a/13790741/5193830
# Also https://pyinstaller.org/en/stable/runtime-information.html#run-time-information
def get_work_dir_path():
""" Get absolute path to current working directory"""
try:
base_path = sys._MEIPASS2
except Exception:
base_path = sys._MEIPASS
else:
# When running in "normal" Python environment.
# For example, when running from the command line:
# python3 start_project.py path/to/file.xlsx
# sys.path[0] returns something like path/to/src/boxcel
base_path = sys.path[0]

return base_path


def start_project(xlsx_file):
"""
This function writes the needed code to the *.py file corresponding to the *.xlsx file.
""" Writes the needed code to the *.py file corresponding to the *.xlsx file.
The code is copied from the script display_images.py and the name of the
corresponding xlsx file is inserted after the line if __name__ == "__main__":
"""

# Test if the xlsx file exists
Expand Down Expand Up @@ -35,8 +66,8 @@ def start_project(xlsx_file):
# if __name__ == "__main__":

# Get the path to the directory where this script file is located & executed from:
path_to_dir_boxcel = sys.path[0] # this should return path/to/img-with-box-from-excel/src/boxcel
display_images_py_file = os.path.join(path_to_dir_boxcel, "display_images.py")
print('get_work_dir_path():', get_work_dir_path()) # print kept for debugging purposes
display_images_py_file = os.path.join(get_work_dir_path(), "display_images.py")

target_py_file = os.path.join(path_to_xlsx_file, xlsx_file_name_without_extension + ".py")

Expand Down

0 comments on commit 9b476b9

Please sign in to comment.