Skip to content

Commit

Permalink
Release v1.1 (#76)
Browse files Browse the repository at this point in the history
* Fixes logging errors while creating new projects and adding new images.
  • Loading branch information
PastaTime authored Jul 28, 2020
1 parent d04c3a3 commit 16431df
Show file tree
Hide file tree
Showing 41 changed files with 4,552 additions and 0 deletions.
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -127,3 +127,11 @@ dmypy.json

# Pyre type checker
.pyre/

# PyCharm IDE Configuration
.idea/

# Data directory for Database
database/DATA


66 changes: 66 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,68 @@
# FastAnnotation
A tool which aims to streamline the annotation process for computer vision projects dealing with Object Detection, Instance Segmentation and Semantic Segmentation.


## Installation
### Requirements
Python 3.6 or greater

### Client
Note: For the following Installation steps please ensure pip is run with administrative privileges.

1. Kivy installation
1. Windows:
```
python -m pip install --upgrade pip wheel setuptools
python -m pip install docutils pygments pypiwin32 kivy.deps.sdl2 kivy.deps.glew
python -m pip install kivy.deps.gstreamer
python -m pip install kivy.deps.angle
python -m pip install kivy
```
2. Ubuntu:
```
python -m pip install -r client_requirements.txt
```
### Server
1. Flask installation
1.Windows installation
```
python -m pip install flask
python -m pip install flask-restplus
python -m pip install flask_negotiate
python -m pip install python-dateutil
python -m pip install mysql-connector-python
```
2. Ubuntu
```
python -m pip install -r server_requirements.txt
```
2. MySql Installation
1. Windows:
```
TODO
```
2. Ubuntu:
1. Install mysql
```
sudo apt-get install mysql-workbench
```
1. Create a connection to the database and run the `database/create_database.sql` script
1. (Optional) run the 'database/create_test_data.sql' script to populate tables with test data
3. Alternatively, Docker can be used to run a MySQL database for development.
1. Download and install Docker and Docker Compose
2. Start the container with
```
>> docker-compose up
```
3. Stop the container with
```
>> docker-compose down
```
4. To stop the container and delete the volume (deleting all data in the DB)
```
>> docker-compose down -v
```
Empty file added client/__init__.py
Empty file.
114 changes: 114 additions & 0 deletions client/annotation_client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import os
import sys
import traceback
from concurrent.futures import ThreadPoolExecutor

from kivy.app import App
from kivy.config import Config
from kivy.properties import StringProperty, NumericProperty
from kivy.resources import resource_add_path
from kivy.uix.screenmanager import ScreenManager

import client.utils as utils
from client.client_config import ClientConfig
from client.screens.common import Alert
from client.screens.image_view_screen import ImageViewScreen
from client.screens.instance_annotator_screen import InstanceAnnotatorScreen
from client.screens.project_select_screen import ProjectSelectScreen
from client.screens.project_tool_screen import ProjectToolScreen
from client.utils import ApiException

Config.set('input', 'mouse', 'mouse,disable_multitouch')


class MyScreenManager(ScreenManager):
"""
Defines the screens which should be included in the ScreenManager at launch.
Use the ScreenManager to handle transitions between Screens.
"""

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.add_widget(ProjectSelectScreen(name="ProjectSelect"))
self.add_widget(ProjectToolScreen(name="ProjectTool"))
self.add_widget(ImageViewScreen(name="ImageView"))
self.add_widget(InstanceAnnotatorScreen(name="InstanceAnnotator"))


class AnnotationClientApp(App):
"""
The launch point for the application itself.
"""

current_project_name = StringProperty("")
current_project_id = NumericProperty(0)
sm = None
thread_pool = ThreadPoolExecutor(
max_workers=ClientConfig.CLIENT_POOL_LIMIT)

def build(self):
print("Building")
self.sm = MyScreenManager()
return self.sm

def show_project_tools(self, name, id):
self.current_project_name = name
self.current_project_id = id
self.sm.current = "ProjectTool"

def show_home(self):
self.sm.current = "ProjectSelect"

def show_image_viewer(self):
self.sm.current = "ImageView"

def show_instance_annotator(self):
self.sm.current = "InstanceAnnotator"

def alert_user(self, future):
if not future.exception():
return

exception = future.exception()
try:
raise exception
except Exception:
tb = traceback.format_exc()
print(tb)

pop_up = Alert()
if isinstance(exception, ApiException):
pop_up.title = "Server Error: %d" % exception.code
else:
pop_up.title = "Unknown Error: %s" % type(exception).__name__
pop_up.alert_message = str(exception)
pop_up.open()


def resourcePath():
"""Returns path containing content - either locally or in pyinstaller tmp file"""
if hasattr(sys, '_MEIPASS'):
return os.path.join(sys._MEIPASS)

return os.path.join(os.path.abspath("."))


if __name__ == "__main__":
resource_add_path(resourcePath()) # add this line
app = AnnotationClientApp()
try:
app.run()
except Exception as e:
print(str(e))
tb = traceback.format_exc()
print(tb)
finally:
app.thread_pool.shutdown(wait=True)
open_images = app.sm.get_screen("InstanceAnnotator").model.active.copy()
print(open_images)
for iid in open_images:
response = utils.update_image_meta_by_id(iid, lock=False)
if response.status_code == 200:
print("Unlocked %d" % iid)
else:
print("Failed to unlock %d" % iid)
34 changes: 34 additions & 0 deletions client/build/windows/client.spec
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# -*- mode: python -*-

from kivy_deps import sdl2, glew

block_cipher = None


a = Analysis(['..\\..\\annotation_client.py'],
pathex=['..\\..'],
binaries=None,
datas=None,
hiddenimports=None,
hookspath=[],
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)

pyz = PYZ(a.pure, a.zipped_data,
cipher=block_cipher)


exe = EXE(pyz, Tree('..\\..\\data','client\\data'),
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
*[Tree(p) for p in (sdl2.dep_bins + glew.dep_bins)],
name='fastannotation',
debug=False,
strip=False,
upx=True,
console=True)
27 changes: 27 additions & 0 deletions client/client_config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import os

from definitions import ROOT_DIR


class ClientConfig:
""" A collection of constants utilized by the client """

SERVER_URL = "http://localhost:5001/"
# Switch to production URL before building executable
# SERVER_URL = "http://130.216.239.117:5000/"

SECONDS_PER_MINUTE = 60
SECONDS_PER_HOUR = 3600
SECONDS_PER_DAY = SECONDS_PER_HOUR * 24
SECONDS_PER_MONTH = SECONDS_PER_DAY * 30
SECONDS_PER_YEAR = SECONDS_PER_DAY * 365

CLIENT_HIGHLIGHT_1 = "#3AD6E7"
CLIENT_DARK_3 = "#0C273B"

BBOX_SELECT = "#ff0000"
BBOX_UNSELECT = "#ebcf1a"

DATA_DIR = os.path.join(ROOT_DIR, 'client', 'data')

CLIENT_POOL_LIMIT = 50
Empty file added client/controller/__init__.py
Empty file.
Loading

0 comments on commit 16431df

Please sign in to comment.