From d3edd36d8e56adf72d6d05fe2f5bd0cb62a1e7c3 Mon Sep 17 00:00:00 2001 From: Mike Abbott Date: Sat, 4 Feb 2023 21:30:38 -0700 Subject: [PATCH] Checking in today's work. The code is basically functional. I wouldn't call it robust, but it does return generally correct results. --- .devcontainer/Dockerfile | 3 ++ .gitignore | 2 + convert.py | 5 ++ klipper/__init__.py | 0 klipper/gcode.py | 79 ++++++++++++++++++++++++++++ main.py | 111 ++++++++++++++++++++++++--------------- record.py | 41 +++++++++++++++ 7 files changed, 198 insertions(+), 43 deletions(-) create mode 100644 convert.py create mode 100644 klipper/__init__.py create mode 100644 klipper/gcode.py create mode 100644 record.py diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index dc6d900..dd8a9a5 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -7,3 +7,6 @@ RUN pip3 install opencv-python-headless # RUN pip3 install --upgrade pip setuptools wheel # RUN pip3 install opencv-python # RUN apt-get update && apt-get install ffmpeg libsm6 libxext6 -y +RUN apt-get update && apt-get install -y git +RUN pip3 install aiohttp requests +RUN apt-get update && apt-get install -y ffmpeg \ No newline at end of file diff --git a/.gitignore b/.gitignore index a5cb84e..9f31e2c 100644 --- a/.gitignore +++ b/.gitignore @@ -153,3 +153,5 @@ cython_debug/ frame_data/ .idea/ +*.gif +*.mp4 \ No newline at end of file diff --git a/convert.py b/convert.py new file mode 100644 index 0000000..626e5c5 --- /dev/null +++ b/convert.py @@ -0,0 +1,5 @@ +from glob import glob +import os +from pathlib import Path +for file_name in glob("sample_data/*"): + os.system(f"ffmpeg -i {file_name} gif/{Path(file_name).stem}.gif") \ No newline at end of file diff --git a/klipper/__init__.py b/klipper/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/klipper/gcode.py b/klipper/gcode.py new file mode 100644 index 0000000..4abced1 --- /dev/null +++ b/klipper/gcode.py @@ -0,0 +1,79 @@ +# import asyncio +# import aiohttp +import requests + +# HOST = 'fluiddpi.local' +HOST = 'http://192.168.1.64' +GCODE_ENDPOINT = '/printer/gcode/script' +OBJECTS_ENDPOINT = '/printer/objects/query' + +# Helper function to automatically generate the coordinate strings +# for G0 commands. +def format_move(x: float = None, y: float = None, z: float = None, f: float = None): + def format_string(value, prefix): + return f" {prefix}{value}" if value is not None else "" + return "".join(format_string(value, prefix) for value, prefix in [(x, "x"), (y, "y"), (z, "z"), (f, "f")]) + + +def move_absolute(x: float = None, y: float = None, z: float = None, f: float = None): + return send_gcode(f""" + G90 + G0{format_move(x, y, z, f)} + """) + + +def move_relative(x: float = None, y: float = None, z: float = None, f: float = None): + return send_gcode(f""" + G91 + G0{format_move(x, y, z, f)} + """) + + +# async def send_gcode(gcode: str): +# async with aiohttp.ClientSession() as session: +# json_data = { +# "script": gcode +# } +# async with session.post(HOST + GCODE_ENDPOINT, json=json_data) as resp: +# return await resp.json() + +def send_gcode(gcode: str): + json_data = { + "script": gcode + } + resp = requests.post(HOST + GCODE_ENDPOINT, json=json_data) + return resp.json() + + +def home(): + return send_gcode('G28') + + +def has_homed(): + resp = requests.get(HOST + OBJECTS_ENDPOINT, params="toolhead") + result = resp.json()["result"] + return result["status"]["toolhead"]["homed_axes"] == "xyz" + +def do_initialization_routine(): + if not has_homed(): + print("Homing") + home() + print("Quad Gantry Level") + send_gcode("QUAD_GANTRY_LEVEL") + print("Rehoming Z") + send_gcode("G28 Z") + +def main(): + do_initialization_routine() + print("Finished initializing") + + # move_absolute(150, 150, 16, 1000000) + # move_absolute(10, 10, 20, 1000000) + # move_absolute(150, 150, 16, 1000000) + print("Done") + + +if __name__ == "__main__": + main() + +# start at x=45, y=305, end at x=109 (leaving 8mm off the start and end for now) diff --git a/main.py b/main.py index 7dc4f0a..b720213 100644 --- a/main.py +++ b/main.py @@ -1,55 +1,80 @@ import cv2 import numpy as np +from glob import glob # result = cv2.imread("2023-01-16-213226.jpg") +ranking = [] -video_data = cv2.VideoCapture("sample_video.mp4") +for video_file in sorted(glob("sample_data2/*")): + video_data = cv2.VideoCapture(video_file) + + out = cv2.VideoWriter("out.avi", cv2.VideoWriter_fourcc('M','J','P','G'), 30, (400,400)) + + mid_y = 720//2 + mid_x = 1280//2 + + + frame_index = 0 + + video_std = [] + while video_data.isOpened(): + ret, frame = video_data.read() + if not ret: + break + frame = frame[mid_y-100:mid_y+100, mid_x+100:mid_x+300] + + lowerb = np.array([0, 0, 120]) + upperb = np.array([255, 255, 255]) + red_line = cv2.inRange(frame, lowerb, upperb) + + masked_video = cv2.bitwise_and(frame,frame,mask = red_line) + # cv2.imwrite("test.png", masked_video) + # exit() + # out.write(masked_video) + + gray = cv2.cvtColor(masked_video, cv2.COLOR_BGR2GRAY) + gray = cv2.GaussianBlur(gray, (3, 3), 0) + gray = cv2.GaussianBlur(gray, (3, 3), 0) + gray = cv2.GaussianBlur(gray, (11, 11), 0) + gray = cv2.GaussianBlur(gray, (11, 11), 0) + + frame_brightest_x = [] + + for line in gray: + # find the 4 brightest pixels + if line.max() > 0: + brightest_pixels = np.argsort(line)[-4:] + line_brightest_x = np.average(brightest_pixels) + frame_brightest_x.append(line_brightest_x) + + gray = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR) + + if len(frame_brightest_x) > 0: + # out.write(gray) + # cv2.imwrite(f"frame_data/{frame_index}.png", gray) + + frame_std = np.std(frame_brightest_x) + # print(frame_index, frame_std) + video_std.append(frame_std) + frame_index += 1 + # red_line = cv2.cvtColor(red_line, cv2.COLOR_GRAY2BGR) + # out.write(red_line) + # out.release() + print(video_file, np.std(video_std)) + + # if True: + # # if "line7.mp4" in video_file: + # break + + ranking.append((video_file, np.std(video_std))) + +print('\nSCORES\n') + +[ print(x) for x in sorted(ranking, key=lambda x: x[1])] -out = cv2.VideoWriter("out.avi", cv2.VideoWriter_fourcc('M','J','P','G'), 14.97, (400,400)) -mid_y = 2592//2 -mid_x = 1944//2 - -frame_index = 0 - -while video_data.isOpened(): - ret, frame = video_data.read() - if not ret: - break - frame = frame[mid_y-200:mid_y+200, mid_x+400:mid_x+800] - - lowerb = np.array([0, 0, 150]) - upperb = np.array([255, 255, 255]) - red_line = cv2.inRange(frame, lowerb, upperb) - - masked_video = cv2.bitwise_and(frame,frame,mask = red_line) - # out.write(masked_video) - - gray = cv2.cvtColor(masked_video, cv2.COLOR_BGR2GRAY) - gray = cv2.GaussianBlur(gray, (11, 11), 0) - - frame_brightest_x = [] - - for line in gray: - # find the 4 brightest pixels - if line.max() > 0: - brightest_pixels = np.argsort(line)[-4:] - line_brightest_x = np.average(brightest_pixels) - frame_brightest_x.append(line_brightest_x) - - gray = cv2.cvtColor(gray, cv2.COLOR_GRAY2BGR) - - if len(frame_brightest_x) > 0: - out.write(gray) - cv2.imwrite(f"frame_data/{frame_index}.png", gray) - - print(frame_index, np.std(frame_brightest_x)) - frame_index += 1 - # red_line = cv2.cvtColor(red_line, cv2.COLOR_GRAY2BGR) - # out.write(red_line) -out.release() # cv2.imwrite("test.png", frame) # line starts on frame 12 diff --git a/record.py b/record.py new file mode 100644 index 0000000..5765cb5 --- /dev/null +++ b/record.py @@ -0,0 +1,41 @@ +from klipper.gcode import * +import subprocess +import time + +ffmpeg_cmd = [ + "ffmpeg", + "-f", + "v4l2", + "-framerate", + "30", + "-video_size", + "1280x720", + "-input_format", + "mjpeg", + "-i", + "/dev/video0", + ] + +# start at x=45, y=250, end at x=73 (leaving 8mm off the start and end for now) +def main(): + + send_gcode("STATUS_OFF") + send_gcode("LASER_ON") + move_absolute(40, 250, 17.86, 18000) + time.sleep(2) + for i in range(20): + # start recording + # with open('') as f: + with subprocess.Popen(ffmpeg_cmd + [f"sample_data2/line{i}.mp4"]) as ffmpeg: + # move_relative(64, f=600) + time.sleep(0.5) + print(move_relative(34, f=600)) + time.sleep(5) + ffmpeg.terminate() + time.sleep(0.5) + # stop recording + print(move_relative(-34, 4, f=18000)) + time.sleep(1) + +if __name__=="__main__": + main()