OpenBiDexHand / app.py
quantumiracle-git's picture
Update app.py
83e5a4c
raw
history blame
8.6 kB
import gradio as gr
import os
import random
import numpy as np
import gdown
import base64
from time import gmtime, strftime
from csv import writer
from datasets import load_dataset
from hfserver import HuggingFaceDatasetSaver, HuggingFaceDatasetJSONSaver
# download data from huggingface dataset
# dataset = load_dataset("quantumiracle-git/robotinder-data")
LOAD_DATA_GOOGLE_DRIVE = True
if LOAD_DATA_GOOGLE_DRIVE: # download data from google drive
# url = 'https://drive.google.com/drive/folders/1JuNQS4R7axTezWj1x4KRAuRt_L26ApxA?usp=sharing' # './processed/' folder in google drive
url = 'https://drive.google.com/drive/folders/1WWOzM9T4HUvuB6gUYPqIEOb_aZwUULNA?usp=sharing' # './processed_zip/' folder in google drive
output = './'
id = url.split('/')[-1]
os.system(f"gdown --id {id} -O {output} --folder --no-cookies --remaining-ok")
VIDEO_PATH = 'processed_zip'
import zipfile
from os import listdir
from os.path import isfile, join, isdir
# unzip the zip files to the same location and delete zip files
path_to_zip_file = VIDEO_PATH
zip_files = [join(path_to_zip_file, f) for f in listdir(path_to_zip_file)]
for f in zip_files:
if f.endswith(".zip"):
directory_to_extract_to = path_to_zip_file # extracted file itself contains a folder
print(f'extract data {f} to {directory_to_extract_to}')
with zipfile.ZipFile(f, 'r') as zip_ref:
zip_ref.extractall(directory_to_extract_to)
os.remove(f)
else: # local data
VIDEO_PATH = 'robotinder-data'
def inference(video_path):
with open(video_path, "rb") as f:
data = f.read()
b64 = base64.b64encode(data).decode()
html = (
f"""
<video controls autoplay muted loop>
<source src="data:video/mp4;base64,{b64}" type="video/mp4">
</video>
"""
)
return html
def video_identity(video):
return video
def nan():
return None
FORMAT = ['mp4', 'gif'][0]
def get_huggingface_dataset():
try:
import huggingface_hub
except (ImportError, ModuleNotFoundError):
raise ImportError(
"Package `huggingface_hub` not found is needed "
"for HuggingFaceDatasetSaver. Try 'pip install huggingface_hub'."
)
HF_TOKEN = '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' # my HF token
DATASET_NAME = 'crowdsourced-robotinder-demo'
FLAGGING_DIR = 'flag/'
path_to_dataset_repo = huggingface_hub.create_repo(
repo_id=DATASET_NAME,
token=HF_TOKEN,
private=False,
repo_type="dataset",
exist_ok=True,
)
dataset_dir = os.path.join(DATASET_NAME, FLAGGING_DIR)
repo = huggingface_hub.Repository(
local_dir=dataset_dir,
clone_from=path_to_dataset_repo,
use_auth_token=HF_TOKEN,
)
repo.git_pull(lfs=True)
log_file = os.path.join(dataset_dir, "flag_data.csv")
return repo, log_file
def update(user_choice, left, right, data_folder=VIDEO_PATH, flag_to_huggingface=True):
global last_left_video_path
global last_right_video_path
global last_infer_left_video_path
global last_infer_right_video_path
if flag_to_huggingface: # log
env_name = str(last_left_video_path).split('/')[1] # 'robotinder-data/ENV_NAME/'
current_time = strftime("%Y-%m-%d-%H-%M-%S", gmtime())
info = [env_name, user_choice, last_left_video_path, last_right_video_path, current_time]
print(info)
repo, log_file = get_huggingface_dataset()
with open(log_file, 'a') as file: # incremental change of the file
writer_object = writer(file)
writer_object.writerow(info)
file.close()
if int(current_time.split('-')[-2]) % 5 == 0: # push only on certain minutes
try:
repo.push_to_hub(commit_message=f"Flagged sample at {current_time}")
except:
repo.git_pull(lfs=True) # sync with remote first
repo.push_to_hub(commit_message=f"Flagged sample at {current_time}")
envs = parse_envs()
env_name = envs[random.randint(0, len(envs)-1)]
# choose video
videos = os.listdir(os.path.join(data_folder, env_name))
video_files = []
for f in videos:
if f.endswith(f'.{FORMAT}'):
video_files.append(os.path.join(data_folder, env_name, f))
# randomly choose two videos
selected_video_ids = np.random.choice(len(video_files), 2, replace=False)
left = video_files[selected_video_ids[0]]
right = video_files[selected_video_ids[1]]
last_left_video_path = left
last_right_video_path = right
last_infer_left_video_path = inference(left)
last_infer_right_video_path = inference(right)
return last_infer_left_video_path, last_infer_right_video_path
def replay(left, right):
return left, right
def parse_envs(folder=VIDEO_PATH):
envs = []
for f in os.listdir(folder):
if os.path.isdir(os.path.join(folder, f)):
envs.append(f)
return envs
def build_interface(iter=3, data_folder=VIDEO_PATH):
import sys
import csv
csv.field_size_limit(sys.maxsize)
HF_TOKEN = os.getenv('HF_TOKEN')
print(HF_TOKEN)
HF_TOKEN = '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' # my HF token
# hf_writer = gr.HuggingFaceDatasetSaver(HF_TOKEN, "crowdsourced-robotinder-demo") # HuggingFace logger instead of local one: https://github.com/gradio-app/gradio/blob/master/gradio/flagging.py
hf_writer = HuggingFaceDatasetSaver(HF_TOKEN, "crowdsourced-robotinder-demo")
# callback = gr.CSVLogger()
callback = hf_writer
# build gradio interface
with gr.Blocks() as demo:
gr.Markdown("Here is RoboTinder!")
gr.Markdown("Select the best robot behaviour in your choice!")
with gr.Row():
# some initial values
envs = parse_envs()
env_name = envs[random.randint(0, len(envs)-1)] # random pick an env
# choose video
videos = os.listdir(os.path.join(data_folder, env_name))
video_files = []
for f in videos:
if f.endswith(f'.{FORMAT}'):
video_files.append(os.path.join(data_folder, env_name, f))
# randomly choose two videos
selected_video_ids = np.random.choice(len(video_files), 2, replace=False)
left_video_path = video_files[selected_video_ids[0]]
right_video_path = video_files[selected_video_ids[1]]
if FORMAT == 'mp4':
# left = gr.PlayableVideo(left_video_path, label="left_video")
# right = gr.PlayableVideo(right_video_path, label="right_video")
infer_left_video_path = inference(left_video_path)
infer_right_video_path = inference(right_video_path)
right = gr.HTML(infer_right_video_path, label="right_video")
left = gr.HTML(infer_left_video_path, label="left_video")
else:
left = gr.Image(left_video_path, shape=(1024, 768), label="left_video")
# right = gr.Image(right_video_path).style(height=768, width=1024)
right = gr.Image(right_video_path, label="right_video")
global last_left_video_path
last_left_video_path = left_video_path
global last_right_video_path
last_right_video_path = right_video_path
global last_infer_left_video_path
last_infer_left_video_path = infer_left_video_path
global last_infer_right_video_path
last_infer_right_video_path = infer_right_video_path
btn1 = gr.Button("Replay")
user_choice = gr.Radio(["Left", "Right", "Not Sure"], label="Which one is your favorite?")
btn2 = gr.Button("Next")
# This needs to be called at some point prior to the first call to callback.flag()
callback.setup([user_choice, left, right], "flagged_data_points")
btn1.click(fn=replay, inputs=[left, right], outputs=[left, right])
btn2.click(fn=update, inputs=[user_choice, left, right], outputs=[left, right])
# We can choose which components to flag -- in this case, we'll flag all of them
btn2.click(lambda *args: callback.flag(args), [user_choice, left, right], None, preprocess=False)
return demo
if __name__ == "__main__":
last_left_video_path = None
last_right_video_path = None
demo = build_interface()
# demo.launch(share=True)
demo.launch(share=False)