Files
2024-10-18 18:28:20 -06:00

161 lines
5.6 KiB
Python

import os
import sys
import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
from scipy.optimize import minimize_scalar
from src import videoCrop
from src.imageTools import radialUndistort, perspectiveUndistort, getFrameFromVideo
class AdvancedDistortionCorrectionTool:
def __init__(self, master):
self.master = master
self.master.title("Advanced Distortion Correction Tool")
self.master.geometry("1200x800")
self.image = None
self.original_image = None
self.displayed_image = None
self.k = 0 # Initialize K value
self.dots = []
self.dragging = None
# Create UI elements
# self.load_button = tk.Button(self.master, text="Load Image", command=self.load_image)
# self.load_button.pack(pady=10)
self.canvas = tk.Canvas(self.master)
self.canvas.pack()
# self.canvas.width
self.canvas.bind("<Button-1>", self.on_click)
self.canvas.bind("<B1-Motion>", self.on_drag)
self.canvas.bind("<ButtonRelease-1>", self.on_release)
self.k_label = tk.Label(self.master, text="K value: 0")
self.k_label.pack(pady=5)
self.k_slider = tk.Scale(self.master, from_=-1.0, to=1.0, resolution=0.01, orient=tk.HORIZONTAL, length=300, command=self.update_k)
self.k_slider.pack(pady=10)
self.zoom_slider = tk.Scale(self.master, from_=0.5, to=5.0, resolution=0.01, orient=tk.HORIZONTAL, label="Zoom", length=300, command=self.update_zoom)
self.zoom_slider.pack(pady=10)
self.perspective_var = tk.BooleanVar()
self.perspective_check = tk.Checkbutton(self.master, text="Apply Perspective Correction", variable=self.perspective_var, command=self.update_persp)
self.perspective_check.pack(pady=10)
self.save_button = tk.Button(self.master, text="Save Image", command=self.save_image, state=tk.DISABLED)
self.save_button.pack(pady=10)
self.display_image_scale = 0.5
self.k_value = 0
self.zoom_value = 1
def update_zoom(self, zoom_value):
self.zoom_value = zoom_value
self.update_image(self.k_value, zoom_value)
def update_k(self, k_value):
self.k_value = k_value
self.update_image(k_value, self.zoom_value)
def update_persp(self):
self.update_image(self.k_value, self.zoom_value)
def load_image(self, image):
print(image)
self.original_image = image
self.save_button.config(state=tk.NORMAL)
height, width = self.original_image.shape[:2]
self.dots = [
[10, 10],
[width-10, 10],
[width-10, height-10],
[10, height-10]
]
self.update_image(self.k_value, self.zoom_value)
def display_image(self):
if self.image is not None:
self.displayed_image = self.image.copy()
if not self.perspective_var.get():
for x, y in self.dots:
cv2.circle(self.displayed_image, (int(x), int(y)), 15, (0, 255, 0), -1)
image = cv2.cvtColor(self.displayed_image, cv2.COLOR_BGR2RGB)
image = Image.fromarray(image)
image.thumbnail((image.width*self.display_image_scale, image.height*self.display_image_scale), Image.LANCZOS)
photo = ImageTk.PhotoImage(image)
self.canvas.config(width=photo.width(), height=photo.height())
self.canvas.create_image(0, 0, anchor=tk.NW, image=photo)
self.canvas.image = photo
def update_image(self, k_value, zoom_value):
if self.original_image is None:
return
self.image = radialUndistort(self.original_image, float(k_value), float(zoom_value))
if self.perspective_var.get():
self.image = perspectiveUndistort(self.image, self.dots)
self.display_image()
self.k_label.config(text=f"K value: {self.k:.2f}")
def count_lines(self, image):
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray, 50, 150, apertureSize=3)
lines = cv2.HoughLines(edges, 1, np.pi/180, 200)
return len(lines) if lines is not None else 0
def on_click(self, event):
x, y = event.x / self.display_image_scale, event.y / self.display_image_scale
for i, (dot_x, dot_y) in enumerate(self.dots):
if abs(x - dot_x) < 50 and abs(y - dot_y) < 50:
self.dragging = i
break
def on_drag(self, event):
if self.dragging is not None:
self.dots[self.dragging] = [event.x / self.display_image_scale, event.y / self.display_image_scale]
self.update_image(self.k_value, self.zoom_value)
def on_release(self, event):
self.dragging = None
def save_image(self):
print(",".join([
str(self.k_value),
str(self.zoom_value),
str(self.dots[0][0]),
str(self.dots[0][1]),
str(self.dots[1][0]),
str(self.dots[1][1]),
str(self.dots[2][0]),
str(self.dots[2][1]),
str(self.dots[3][0]),
str( self.dots[3][1])
]))
if __name__ == "__main__":
if len(sys.argv) < 1:
print("Usage: undistort.py <event code>")
filename = sys.argv[1] + "/" + (os.listdir(sys.argv[1])[0])
root = tk.Tk()
app = AdvancedDistortionCorrectionTool(root)
start, stop = videoCrop.videoCrop(filename)
if start != stop:
print("Found video start and end")
app.load_image(getFrameFromVideo(filename, start))
root.mainloop()