diff --git a/.gitignore b/.gitignore index 6345392..7af10d1 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,7 @@ *.swp *.db *key -*.log +*.log* google_signin_client_id db_url* schema.sql diff --git a/README.md b/README.md index e31e518..5cec137 100755 --- a/README.md +++ b/README.md @@ -1,21 +1,25 @@ # video-labeling-tool Demo: http://smoke.createlab.org -A tool for labeling video clips (both front-end and back-end). The back-end depends on the [thumbnail server](https://github.com/CMU-CREATE-Lab/timemachine-thumbnail-server) to provide video urls. The back-end is based on [flask](http://flask.pocoo.org/). A flask tutorial can be found on [this blog](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world). This tool is tested and worked on: +A tool for labeling video clips (both front-end and back-end). The back-end depends on the [thumbnail server](https://github.com/CMU-CREATE-Lab/timemachine-thumbnail-server) to provide video urls. The back-end is based on [flask](http://flask.pocoo.org/). A flask tutorial can be found on [this blog](https://blog.miguelgrinberg.com/post/the-flask-mega-tutorial-part-i-hello-world). + +The system defines the final label by aggregating answers from citizens and researchers. At least two volunteers or one researcher will review each video. If the answers from the two volunteers agree, the system marks the video according to the agreement. Otherwise, another volunteer or researcher will review the video, and the result is aggregated based on majority voting. + +This tool is tested and worked on: - macOS Mojave - - Chrome 76 + - Chrome 77 - Safari 12 - Firefox 68 - Windows 10 - - Chrome 76 + - Chrome 77 - Firefox 68 - Edge 44 -- Android 8 - - Chrome 76 +- Android 7, 8, 9, and 10 + - Chrome 77 - Firefox 68 -- iOS 12 - - Chrome 76 - - Safari 12 +- iOS 12 and 13 + - Chrome 77 + - Safari - Firefox 18 ### Table of Content @@ -78,8 +82,8 @@ drop database video_labeling_tool_development; # Setup back-end Install conda. This assumes that Ubuntu is installed. A detailed documentation is [here](https://conda.io/projects/conda/en/latest/user-guide/install/index.html). First visit [here](https://conda.io/miniconda.html) to obtain the downloading path. The following script install conda for all users: ```sh -wget https://repo.continuum.io/miniconda/Miniconda2-4.6.14-Linux-x86_64.sh -sudo sh Miniconda2-4.6.14-Linux-x86_64.sh -b -p /opt/miniconda3 +wget https://repo.continuum.io/miniconda/Miniconda3-4.7.12.1-Linux-x86_64.sh +sudo sh Miniconda3-4.7.12.1-Linux-x86_64.sh -b -p /opt/miniconda3 sudo vim /etc/bash.bashrc # Add the following lines to this file @@ -91,8 +95,8 @@ source /etc/bash.bashrc For Mac OS, I recommend installing conda by using [Homebrew](https://brew.sh/). ```sh brew cask install miniconda -echo 'export PATH="/usr/local/miniconda3/bin:$PATH"' >> ~/.bash_profile -echo '. /usr/local/miniconda3/etc/profile.d/conda.sh' >> ~/.bash_profile +echo 'export PATH="/usr/local/Caskroom/miniconda/base/bin:$PATH"' >> ~/.bash_profile +echo '. /usr/local/Caskroom/miniconda/base/etc/profile.d/conda.sh' >> ~/.bash_profile source ~/.bash_profile ``` Clone this repository and set the permission. @@ -109,13 +113,14 @@ Create conda environment and install packages. It is important to install pip fi ```sh conda create -n video-labeling-tool conda activate video-labeling-tool +conda install python=3.7 conda install pip which pip # make sure this is the pip inside the video-labeling-tool environment sh video-labeling-tool/back-end/install_packages.sh ``` If the environment already exists and you want to remove it before installing packages, use the following: ```sh -conda remove -n video-labeling-tool --all +conda env remove -n video-labeling-tool ``` Create a text file with name "google_signin_client_id" in the "back-end/data/" directory to store the client ID. For detailed documentation about how to obtain the client ID, refer to the [Google Sign-In API](https://developers.google.com/identity/sign-in/web/sign-in). In the Google Cloud Console, remember to go to "APIs & Services" -> "Credentials" and add the desired domain names (or IP addresses) to the "Authorized JavaScript origins" in the OAuth client. This makes it possible to call the Google Sign-In API from these desired domains. ```sh @@ -204,7 +209,7 @@ sudo mysql -u root -p video_labeling_tool_development 1: + if argv[1] == "confirm": + add_videos(update=True) + else: + add_videos(update=False) + print("Must confirm by running: python add_video_set_small.py confirm") + else: + add_videos(update=False) + print("Must confirm by running: python add_video_set_small.py confirm") print("END") if __name__ == "__main__": - main() + main(sys.argv) diff --git a/back-end/www/add_video_set_large.py b/back-end/www/add_video_set_large.py deleted file mode 100644 index 3213eaf..0000000 --- a/back-end/www/add_video_set_large.py +++ /dev/null @@ -1,66 +0,0 @@ -from application import add_video -import json -from os import listdir -from os.path import isfile, join -import requests -import sys - -# Return a list of all files in a folder -def get_all_file_names_in_folder(path): - return [f for f in listdir(path) if isfile(join(path, f))] - -# Return a thumbnail server url -# ds: date (str), "2015-05-22" -# b: bounding box (dictionary), {"left": 2330, "top": 690, "right": 3730, "bottom": 2090} -# w: width (int) -# h: height (int) -# sf: start frame number (int) -# fmt: format (str), "gif" or "mp4" or "png" -# fps: frames per second (int) -# nf: number of frames (int) -def get_url_part(ds=None, b=None, w=None, h=None, sf=None, fmt="mp4", fps=12, nf=None): - return "?root=http://tiles.cmucreatelab.org/ecam/timemachines/shenango1/%s.timemachine/&boundsLTRB=%r,%r,%r,%r&width=%r&height=%r&startFrame=%r&format=%s&fps=%r&tileFormat=mp4&nframes=%r" % (ds, b["left"], b["top"], b["right"], b["bottom"], w, h, sf, fmt, fps, nf) - -# Verify if the thumbnail server is happy for this url -def check_url(url_part): - video_url_root = "http://thumbnails.cmucreatelab.org/thumbnail" - url = video_url_root + url_part - r = requests.get(url) - if r.status_code == 200: - return True - else: - return False - -# Add videos -def add_video_set_large(): - b = {"left": 2330, "top": 690, "right": 3730, "bottom": 2090} # bounding box - w = 175 - h = 175 - s = (b["right"] - b["left"]) / w - p = "../data/video_set_large/" - do_url_check = True - for n in get_all_file_names_in_folder(p): - if ".json" not in n: continue - with open(p + n) as f: - data = json.load(f) - sf = data["frames_start"] - ef = data["frames_end"] - for i in range(len(sf)): - print("------------------------------------------------") - ds = n[6:-5] - u = get_url_part(ds=ds, b=b, w=w, h=h, sf=sf[i], nf=24) - if do_url_check and not check_url(u): - print("Fail to get video from: %s" % u) - continue - fn = "%s-%r-%r" % (ds, sf[i], ef[i]) - video = add_video(file_name=fn, start_time=0, end_time=0, width=w, height=h, scale=s, left=b["left"], top=b["top"], url_part=u) - print(video) - -argv = sys.argv -if len(argv) > 1: - if argv[1] == "confirm": - add_video_set_large() - else: - print("Must confirm by running: python add_video_set_large.py confirm") -else: - print("Must confirm by running: python add_video_set_large.py confirm") diff --git a/back-end/www/application.py b/back-end/www/application.py index b3c9c30..ead45c3 100644 --- a/back-end/www/application.py +++ b/back-end/www/application.py @@ -127,12 +127,16 @@ class Video(db.Model): label_state_admin = db.Column(db.Integer, nullable=False, default=-1, index=True) # The most recent epochtime that the label state is updated label_update_time = db.Column(db.Integer) + # The view id within the same camera id + view_id = db.Column(db.Integer, nullable=False, default=-1) + # The camera id of the video + camera_id = db.Column(db.Integer, nullable=False, default=-1) # Relationships label = db.relationship("Label", backref=db.backref("video", lazy=True), lazy=True) view = db.relationship("View", backref=db.backref("video", lazy=True), lazy=True) def __repr__(self): - return ("