Esempio n. 1
0
def preprocess_timelapse(self, user_id, video_path, filename):
    tmp_file_path = os.path.join(tempfile.gettempdir(), video_path)
    converted_mp4_path = tmp_file_path + '.mp4'
    Path(tmp_file_path).parent.mkdir(parents=True, exist_ok=True)
    with open(tmp_file_path, 'wb') as file_obj:
        retrieve_to_file_obj(f'uploaded/{video_path}',
                             file_obj,
                             settings.PICS_CONTAINER,
                             long_term_storage=False)

    subprocess.run(
        f'ffmpeg -y -i {tmp_file_path} -c:v libx264 -pix_fmt yuv420p {converted_mp4_path}'
        .split(),
        check=True)

    _print = Print.objects.create(user_id=user_id,
                                  filename=filename,
                                  uploaded_at=timezone.now())
    with open(converted_mp4_path, 'rb') as mp4_file:
        _, video_url = save_file_obj(f'private/{_print.id}.mp4', mp4_file,
                                     settings.TIMELAPSE_CONTAINER)
    _print.video_url = video_url
    _print.save()

    detect_timelapse.delay(_print.id)
    os.remove(tmp_file_path)
    os.remove(converted_mp4_path)
Esempio n. 2
0
def save_print_snapshot(_print, input_path, unrotated_jpg_path=None, rotated_jpg_path=None, to_container=settings.TIMELAPSE_CONTAINER, to_long_term_storage=True):
    if not input_path:
        return (None, None)

    to_dir = tempfile.mkdtemp()
    shutil.rmtree(to_dir, ignore_errors=True)
    os.mkdir(to_dir)
    unrotated_jpg = os.path.join(to_dir, 'unrotated.jpg')
    with open(unrotated_jpg, 'wb') as file_obj:
        retrieve_to_file_obj(input_path, file_obj, settings.PICS_CONTAINER, long_term_storage=False)

    (unrotated_jpg_url, rotated_jpg_url) = (None, None)

    if unrotated_jpg_path:
        with open(unrotated_jpg, 'rb') as file_obj:
            _, unrotated_jpg_url = save_file_obj(unrotated_jpg_path, file_obj, to_container, long_term_storage=to_long_term_storage)

    if rotated_jpg_path:
        ffmpeg_extra_options = orientation_to_ffmpeg_options(_print.printer.settings)
        rotated_jpg = os.path.join(to_dir, 'rotated.jpg')
        cmd = f'ffmpeg -y -i {unrotated_jpg} {ffmpeg_extra_options} {rotated_jpg}'
        subprocess.run(cmd.split(), check=True)
        with open(rotated_jpg, 'rb') as file_obj:
            _, rotated_jpg_url = save_file_obj(rotated_jpg_path, file_obj, to_container, long_term_storage=to_long_term_storage)

    shutil.rmtree(to_dir, ignore_errors=True)

    return (unrotated_jpg_url, rotated_jpg_url)
Esempio n. 3
0
def save_print_snapshot(printer,
                        input_path,
                        dest_jpg_path,
                        rotated=False,
                        to_container=settings.PICS_CONTAINER,
                        to_long_term_storage=True):
    if not input_path:
        return None

    img_bytes = io.BytesIO()
    retrieve_to_file_obj(input_path,
                         img_bytes,
                         settings.PICS_CONTAINER,
                         long_term_storage=False)
    img_bytes.seek(0)
    tmp_img = Image.open(img_bytes)
    if rotated:
        if printer.settings['webcam_flipH']:
            tmp_img = tmp_img.transpose(Image.FLIP_LEFT_RIGHT)
        if printer.settings['webcam_flipV']:
            tmp_img = tmp_img.transpose(Image.FLIP_TOP_BOTTOM)
        if printer.settings['webcam_rotate90']:
            tmp_img = tmp_img.transpose(Image.ROTATE_90)

    img_bytes = io.BytesIO()
    tmp_img.save(img_bytes, "JPEG")
    img_bytes.seek(0)
    _, dest_jpg_url = save_file_obj(dest_jpg_path,
                                    img_bytes,
                                    to_container,
                                    long_term_storage=to_long_term_storage)
    return dest_jpg_url
def download_files(filenames, to_dir, container=settings.PICS_CONTAINER):
    output_files = []
    for filename in filenames:
        output_path = Path(os.path.join(to_dir, filename))
        output_path.parent.mkdir(parents=True, exist_ok=True)
        with open(output_path, 'wb') as file_obj:
            retrieve_to_file_obj(filename, file_obj, container)
        output_files += [output_path]

    return output_files
Esempio n. 5
0
def save_print_snapshot(_print, rotated_jpg_path, rotated_jpg_container,
                        rotated_jpg_long_term):
    pic_dir = f'{_print.printer.id}/{_print.id}'
    print_pics = list_dir(f'raw/{pic_dir}/',
                          settings.PICS_CONTAINER,
                          long_term_storage=False)
    if not print_pics:
        return (None, None)
    print_pics.sort()

    to_dir = os.path.join(tempfile.gettempdir(), str(_print.id))
    shutil.rmtree(to_dir, ignore_errors=True)
    os.mkdir(to_dir)
    unrotated_jpg = os.path.join(to_dir, 'unrotated.jpg')
    with open(unrotated_jpg, 'wb') as file_obj:
        retrieve_to_file_obj(print_pics[-1],
                             file_obj,
                             settings.PICS_CONTAINER,
                             long_term_storage=False)

    with open(unrotated_jpg, 'rb') as file_obj:
        _, unrotated_jpg_url = save_file_obj(
            f'raw/{_print.printer.id}/unrotated.jpg',
            file_obj,
            settings.PICS_CONTAINER,
            long_term_storage=False)

    ffmpeg_extra_options = orientation_to_ffmpeg_options(
        _print.printer.settings)
    rotated_jpg = os.path.join(to_dir, 'rotated.jpg')
    cmd = f'ffmpeg -y -i {unrotated_jpg} {ffmpeg_extra_options} {rotated_jpg}'
    subprocess.run(cmd.split(), check=True)
    with open(rotated_jpg, 'rb') as file_obj:
        _, rotated_jpg_url = save_file_obj(
            rotated_jpg_path,
            file_obj,
            rotated_jpg_container,
            long_term_storage=rotated_jpg_long_term)

    shutil.rmtree(to_dir, ignore_errors=True)

    return (unrotated_jpg_url, rotated_jpg_url)
Esempio n. 6
0
def generate_print_poster(_print):
    pic_dir = f'{_print.printer.id}/{_print.id}'
    print_pics = list_dir(f'raw/{pic_dir}/',
                          settings.PICS_CONTAINER,
                          long_term_storage=False)
    if not print_pics:
        return
    print_pics.sort()

    to_dir = os.path.join(tempfile.gettempdir(), str(_print.id))
    shutil.rmtree(to_dir, ignore_errors=True)
    os.mkdir(to_dir)
    unrotated_jpg = os.path.join(to_dir, 'ss.jpg')
    with open(unrotated_jpg, 'wb') as file_obj:
        retrieve_to_file_obj(print_pics[-1],
                             file_obj,
                             settings.PICS_CONTAINER,
                             long_term_storage=False)

    with open(unrotated_jpg, 'rb') as unrotated_jpg_file:
        _, ss_url = save_file_obj(f'raw/{_print.printer.id}/ss.jpg',
                                  unrotated_jpg_file,
                                  settings.PICS_CONTAINER,
                                  long_term_storage=False)
    redis.printer_pic_set(_print.printer.id, {'img_url': ss_url},
                          ex=IMG_URL_TTL_SECONDS)

    ffmpeg_extra_options = orientation_to_ffmpeg_options(
        _print.printer.settings)
    rotated_jpg = os.path.join(to_dir, 'rotated.jpg')
    cmd = f'ffmpeg -y -i {unrotated_jpg} {ffmpeg_extra_options} {rotated_jpg}'
    subprocess.run(cmd.split(), check=True)
    with open(rotated_jpg, 'rb') as poster_file:
        _, poster_file_url = save_file_obj(
            'private/{}_poster.jpg'.format(_print.id), poster_file,
            settings.TIMELAPSE_CONTAINER)

    _print.poster_url = poster_file_url
    _print.save()

    shutil.rmtree(to_dir, ignore_errors=True)
Esempio n. 7
0
def save_print_snapshot(_print,
                        input_path,
                        dest_jpg_path,
                        rotated=False,
                        to_container=settings.PICS_CONTAINER,
                        to_long_term_storage=True):
    if not input_path:
        return None

    to_dir = tempfile.mkdtemp()
    shutil.rmtree(to_dir, ignore_errors=True)
    os.mkdir(to_dir)
    temp_jpg = os.path.join(to_dir, 'unrotated.jpg')
    with open(temp_jpg, 'wb') as file_obj:
        retrieve_to_file_obj(input_path,
                             file_obj,
                             settings.PICS_CONTAINER,
                             long_term_storage=False)

    if not rotated:
        dest_jpg = temp_jpg
    else:
        ffmpeg_extra_options = orientation_to_ffmpeg_options(
            _print.printer.settings)
        dest_jpg = os.path.join(to_dir, 'rotated.jpg')
        cmd = f'ffmpeg -y -i {temp_jpg} {ffmpeg_extra_options} {dest_jpg}'
        subprocess.run(cmd.split(), check=True)

    with open(dest_jpg, 'rb') as file_obj:
        _, dest_jpg_url = save_file_obj(dest_jpg_path,
                                        file_obj,
                                        to_container,
                                        long_term_storage=to_long_term_storage)
    shutil.rmtree(to_dir, ignore_errors=True)

    return dest_jpg_url
Esempio n. 8
0
def detect_timelapse(self, print_id):
    MAX_FRAME_NUM = 750

    _print = Print.objects.get(pk=print_id)
    tmp_dir = os.path.join(tempfile.gettempdir(), str(_print.id))
    mp4_filepath = f'private/{_print.id}.mp4'
    tl_path = os.path.join(tmp_dir, mp4_filepath)
    Path(tl_path).parent.mkdir(parents=True, exist_ok=True)
    with open(tl_path, 'wb') as file_obj:
        retrieve_to_file_obj(mp4_filepath, file_obj,
                             settings.TIMELAPSE_CONTAINER)

    jpgs_dir = os.path.join(tmp_dir, 'jpgs')
    shutil.rmtree(jpgs_dir, ignore_errors=True)
    os.makedirs(jpgs_dir)
    tagged_jpgs_dir = os.path.join(tmp_dir, 'tagged_jpgs')
    shutil.rmtree(tagged_jpgs_dir, ignore_errors=True)
    os.makedirs(tagged_jpgs_dir)

    ffprobe_cmd = subprocess.run(
        f'ffprobe -v error -count_frames -select_streams v:0 -show_entries stream=nb_read_frames -of default=nokey=1:noprint_wrappers=1 {tl_path}'
        .split(),
        stdout=subprocess.PIPE)
    frame_num = int(ffprobe_cmd.stdout.strip())
    fps = 30 * MAX_FRAME_NUM / frame_num if frame_num > MAX_FRAME_NUM else 30
    subprocess.run(
        f'ffmpeg -y -i {tl_path} -vf fps={fps} -qscale:v 2 {jpgs_dir}/%5d.jpg'.
        split())

    predictions = []
    last_prediction = PrinterPrediction()
    jpg_filenames = sorted(os.listdir(jpgs_dir))
    for jpg_path in jpg_filenames:
        jpg_abs_path = os.path.join(jpgs_dir, jpg_path)
        with open(jpg_abs_path, 'rb') as pic:
            pic_path = f'{_print.user.id}/{_print.id}/{jpg_path}'
            internal_url, _ = save_file_obj(f'uploaded/{pic_path}',
                                            pic,
                                            settings.PICS_CONTAINER,
                                            long_term_storage=False)
            req = requests.get(settings.ML_API_HOST + '/p/',
                               params={'img': internal_url},
                               headers=ml_api_auth_headers(),
                               verify=False)
            req.raise_for_status()
            detections = req.json()['detections']
            update_prediction_with_detections(last_prediction, detections)
            predictions.append(last_prediction)

            if is_failing(last_prediction, 1, escalating_factor=1):
                _print.alerted_at = timezone.now()

            last_prediction = copy.deepcopy(last_prediction)
            detections_to_visualize = [
                d for d in detections if d[1] > VISUALIZATION_THRESH
            ]
            overlay_detections(Image.open(jpg_abs_path),
                               detections_to_visualize).save(
                                   os.path.join(tagged_jpgs_dir, jpg_path),
                                   "JPEG")

    predictions_json = serializers.serialize("json", predictions)
    _, json_url = save_file_obj(f'private/{_print.id}_p.json',
                                io.BytesIO(str.encode(predictions_json)),
                                settings.TIMELAPSE_CONTAINER)

    mp4_filename = f'{_print.id}_tagged.mp4'
    output_mp4 = os.path.join(tmp_dir, mp4_filename)
    subprocess.run(
        f'ffmpeg -y -r 30 -pattern_type glob -i {tagged_jpgs_dir}/*.jpg -c:v libx264 -pix_fmt yuv420p -vf pad=ceil(iw/2)*2:ceil(ih/2)*2 {output_mp4}'
        .split(),
        check=True)
    with open(output_mp4, 'rb') as mp4_file:
        _, mp4_file_url = save_file_obj(f'private/{mp4_filename}', mp4_file,
                                        settings.TIMELAPSE_CONTAINER)

    with open(os.path.join(jpgs_dir, jpg_filenames[-1]), 'rb') as poster_file:
        _, poster_file_url = save_file_obj(f'private/{_print.id}_poster.jpg',
                                           poster_file,
                                           settings.TIMELAPSE_CONTAINER)

    _print.tagged_video_url = mp4_file_url
    _print.prediction_json_url = json_url
    _print.poster_url = poster_file_url
    _print.save()

    shutil.rmtree(tmp_dir, ignore_errors=True)
    send_timelapse_detection_done_email(_print)
    delete_dir(f'uploaded/{_print.user.id}/{_print.id}/',
               settings.PICS_CONTAINER,
               long_term_storage=False)