|
import cv2 |
|
import numpy as np |
|
import ezdxf |
|
import gradio as gr |
|
from pathlib import Path |
|
|
|
coordis = [] |
|
|
|
def save_matrix(mtx, dist, path): |
|
"""Save camera matrix and distortion coefficients to file.""" |
|
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_WRITE) |
|
cv_file.write('K', mtx) |
|
cv_file.write('D', dist) |
|
cv_file.release() |
|
|
|
def load_matrix(path): |
|
"""Load camera matrix and distortion coefficients from file.""" |
|
cv_file = cv2.FileStorage(path, cv2.FILE_STORAGE_READ) |
|
camera_matrix = cv_file.getNode('K').mat() |
|
dist_matrix = cv_file.getNode('D').mat() |
|
cv_file.release() |
|
return [camera_matrix, dist_matrix] |
|
|
|
def correct_image(image, yaml): |
|
image = cv2.imread(image) |
|
mtx, dist = load_matrix(yaml.name) |
|
dst = cv2.undistort(image, mtx, dist, None, None) |
|
return dst |
|
|
|
|
|
def color_tab(file_path, yaml): |
|
|
|
coordinates = [] |
|
img = cv2.imread(file_path) |
|
|
|
mtx, dist = load_matrix(yaml.name) |
|
|
|
img = cv2.undistort(img, mtx, dist, None, None) |
|
|
|
height, width, _ = img.shape |
|
|
|
|
|
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) |
|
|
|
|
|
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY) |
|
|
|
|
|
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) |
|
|
|
|
|
contour = max(contours, key=cv2.contourArea) |
|
|
|
|
|
epsilon = 0.01 * cv2.arcLength(contour, True) |
|
approx = cv2.approxPolyDP(contour, epsilon, True) |
|
|
|
|
|
cv2.polylines(img, [approx], True, (0, 255, 0), thickness=2) |
|
|
|
|
|
doc = ezdxf.new("R2010", setup=True) |
|
msp = doc.modelspace() |
|
|
|
|
|
for corner in approx: |
|
x, y = corner[0] |
|
coordinates.append([x,y]) |
|
|
|
|
|
msp.add_line((coordinates[0][0], -coordinates[0][1]), (coordinates[1][0], -coordinates[1][1])) |
|
msp.add_line((coordinates[1][0], -coordinates[1][1]), (coordinates[2][0], -coordinates[2][1])) |
|
msp.add_line((coordinates[2][0], -coordinates[2][1]), (coordinates[3][0], -coordinates[3][1])) |
|
msp.add_line((coordinates[3][0], -coordinates[3][1]), (coordinates[0][0], -coordinates[0][1])) |
|
msp.add_line((0,0), (0, -height)) |
|
msp.add_line((0, -height), (width, -height)) |
|
msp.add_line((width, -height), (width, 0)) |
|
msp.add_line((width, 0), (0,0)) |
|
|
|
doc.saveas("output.dxf") |
|
return "output.dxf", img |
|
|
|
def corner_tab(img, evt: gr.SelectData): |
|
|
|
height, width, _ = img.shape |
|
|
|
row, col = evt.index |
|
coordis.append([row, col]) |
|
|
|
if len(coordis) == 4 : |
|
coordinates = np.array(coordis) |
|
dwg = ezdxf.new("R2010") |
|
msp = dwg.modelspace() |
|
dwg.layers.new(name="greeny green lines", dxfattribs={"color": 3}) |
|
|
|
msp.add_line((coordinates[0][0], -coordinates[0][1]), (coordinates[1][0], -coordinates[1][1])) |
|
msp.add_line((coordinates[1][0], -coordinates[1][1]), (coordinates[2][0], -coordinates[2][1])) |
|
msp.add_line((coordinates[2][0], -coordinates[2][1]), (coordinates[3][0], -coordinates[3][1])) |
|
msp.add_line((coordinates[3][0], -coordinates[3][1]), (coordinates[0][0], -coordinates[0][1])) |
|
|
|
msp.add_line((0,0), (0, -height)) |
|
msp.add_line((0, -height), (width, -height)) |
|
msp.add_line((width, -height), (width, 0)) |
|
msp.add_line((width, 0), (0,0)) |
|
|
|
|
|
dwg.saveas("output.dxf") |
|
coordis.clear() |
|
|
|
return "output.dxf" |
|
|
|
|
|
def generate_matrix(filename, board_vert, board_horz): |
|
"""Main function to calibrate camera and undistort image.""" |
|
|
|
filename_stem = Path(filename).stem |
|
|
|
|
|
CHECKERBOARD = (int(board_vert)-1, int(board_horz)-1) |
|
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001) |
|
|
|
|
|
object_points = [] |
|
image_points = [] |
|
|
|
|
|
objectp3d = np.zeros((1, CHECKERBOARD[0] * CHECKERBOARD[1], 3), np.float32) |
|
objectp3d[0, :, :2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2) |
|
|
|
|
|
image = cv2.imread(filename) |
|
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) |
|
|
|
|
|
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH |
|
+ cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE) |
|
|
|
|
|
if ret: |
|
object_points.append(objectp3d) |
|
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1), criteria) |
|
image_points.append(corners2) |
|
image = cv2.drawChessboardCorners(image, CHECKERBOARD, corners2, ret) |
|
|
|
|
|
h, w = gray.shape[:2] |
|
try: |
|
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None) |
|
|
|
save_matrix(mtx, dist, f"{filename_stem}.yml") |
|
return f"{filename_stem}.yml" |
|
except: |
|
print("Please check the Chessboard Dimensions") |
|
|
|
|
|
def slider(img, h1, s1, v1, h2, s2, v2): |
|
|
|
img = cv2.imread(img) |
|
|
|
while(1): |
|
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR) |
|
|
|
|
|
lower_red = np.array([h1, s1, v1]) |
|
upper_red = np.array([h2, s2, v2]) |
|
|
|
|
|
lower_red = np.array([int(x) for x in lower_red]) |
|
upper_red = np.array([int(x) for x in upper_red]) |
|
|
|
|
|
mask = cv2.inRange(img, lower_red, upper_red) |
|
res = cv2.bitwise_and(img,img, mask= mask) |
|
|
|
return res |
|
|
|
|