File size: 6,379 Bytes
858a6b3 43c7551 858a6b3 43c7551 d087928 64dc6be 858a6b3 64dc6be 43c7551 64dc6be 43c7551 64dc6be 43c7551 858a6b3 64dc6be 858a6b3 64dc6be 858a6b3 64dc6be 43c7551 64dc6be 43c7551 858a6b3 5794114 858a6b3 d087928 858a6b3 d087928 64dc6be d087928 43c7551 64dc6be 43c7551 d087928 43c7551 2ae1ac2 64dc6be 2ae1ac2 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
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
# Convert the image to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Apply a threshold to convert the grayscale image into a binary image
_, binary = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY)
# Find the contours in the binary image
contours, hierarchy = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Select the contour with the largest area (the object we want to extract the corners from)
contour = max(contours, key=cv2.contourArea)
# Approximate the contour with a polygon
epsilon = 0.01 * cv2.arcLength(contour, True)
approx = cv2.approxPolyDP(contour, epsilon, True)
# Draw the polygon on the original image
cv2.polylines(img, [approx], True, (0, 255, 0), thickness=2)
doc = ezdxf.new("R2010", setup=True)
msp = doc.modelspace()
# Print the coordinates of the corners
for corner in approx:
x, y = corner[0]
coordinates.append([x,y])
#This method of adding line is brute force and needs to be changed, find a way to generalize for polygons
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
# Define the checkerboard pattern size and criteria for corner detection
CHECKERBOARD = (int(board_vert)-1, int(board_horz)-1)
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# Initialize object points and image points arrays
object_points = [] # 3D points in real world space
image_points = [] # 2D points in image plane
# Create the object points for the chessboard corners
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)
# Load the image and convert to grayscale
image = cv2.imread(filename)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Find chessboard corners
ret, corners = cv2.findChessboardCorners(gray, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH
+ cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE)
# If corners found, add object points and image points to arrays
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)
# Calibrate camera using object points and image points
h, w = gray.shape[:2]
try:
ret, mtx, dist, rvecs, tvecs = cv2.calibrateCamera(object_points, image_points, gray.shape[::-1], None, None)
# Save camera matrix and distortion coefficients to file
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):
# Load the image
img = cv2.imread(img)
while(1):
img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)
# Create the NumPy arrays
lower_red = np.array([h1, s1, v1])
upper_red = np.array([h2, s2, v2])
# Convert every element to integer using int() function
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
|