Unfucked my own fuckup :)
This commit is contained in:
parent
538c7e3341
commit
7ac73274a6
@ -3,14 +3,11 @@ Script to extract 10cm x 10cm images from the template
|
||||
Accounts for (minor) rotation.
|
||||
|
||||
command:
|
||||
python template.py input_folder output_folder
|
||||
|
||||
volgorde maakt uit! heb niet die fancy library gebruikt
|
||||
python template.py input_directory
|
||||
|
||||
known bugs:
|
||||
- plaatjes worden soms de verkeerde kant op gedraaid, ze staan wel recht
|
||||
maar 90 graden gedraaid
|
||||
- plaatjes zijn niet persé exact 10x10 cm als perspectief niet precies goed is
|
||||
- gekke crash bij herextractie van datapunten, zie todo
|
||||
|
||||
Auteurs:
|
||||
Tom Selier
|
||||
@ -24,7 +21,7 @@ import os
|
||||
## Parameters ##
|
||||
|
||||
# [%] Schaal output in percentages
|
||||
SCHAAL = 25
|
||||
SCHAAL = 100
|
||||
|
||||
|
||||
# [mm] 120 op calib a4, 180 op template
|
||||
@ -38,13 +35,13 @@ OFFSET = 20
|
||||
|
||||
|
||||
# Toon plaatjes (forceert pauze)
|
||||
PLAATJES = True
|
||||
PLAATJES = False
|
||||
|
||||
# Wacht na elke plaatje op toets
|
||||
PAUZE = False
|
||||
|
||||
# Sla plaatjes op
|
||||
SAVE = False
|
||||
SAVE = True
|
||||
|
||||
# extra info
|
||||
VERBOSE = True
|
||||
@ -82,139 +79,167 @@ def findMin(array, index):
|
||||
min_val = element[index]
|
||||
return min_val
|
||||
|
||||
input_folder = sys.argv[1]
|
||||
output_folder = sys.argv[2]
|
||||
input_directory = sys.argv[1]
|
||||
|
||||
if(not os.path.isdir(input_folder)):
|
||||
print("Input folder not found")
|
||||
if(not os.path.isdir(input_directory)):
|
||||
print(input_directory)
|
||||
print("Input directory not found")
|
||||
exit()
|
||||
|
||||
if(not os.path.isdir(output_folder)):
|
||||
print("Output folder not found")
|
||||
exit()
|
||||
|
||||
|
||||
### ARUCO PARAMETERS ###
|
||||
detector_params = cv2.aruco.DetectorParameters()
|
||||
detector_params.adaptiveThreshWinSizeMax = 150 # Takes longer, but better chance of finding markers
|
||||
dictionary = cv2.aruco.getPredefinedDictionary(cv2.aruco.DICT_ARUCO_ORIGINAL)
|
||||
detector = cv2.aruco.ArucoDetector(dictionary, detector_params)
|
||||
|
||||
### IMAGE CONVERSIE ###
|
||||
for file in os.listdir(input_folder):
|
||||
## Laad plaatjes in kleur ##
|
||||
filename = input_folder + '/' + file
|
||||
out_filename = output_folder + '/' + file
|
||||
img = cv2.imread(filename, 1)
|
||||
for folder in os.listdir(input_directory):
|
||||
if folder.endswith('.py'):
|
||||
print("Skipping", folder)
|
||||
continue
|
||||
|
||||
if VERBOSE:
|
||||
print(file)
|
||||
if folder.endswith('.jpg'):
|
||||
continue
|
||||
|
||||
## Herschaal de fotos ##
|
||||
(h, w) = img.shape[:2]
|
||||
x_scale = int(w/100*SCHAAL)
|
||||
y_scale = int(h/100*SCHAAL)
|
||||
small_img = cv2.resize(img, (x_scale, y_scale))
|
||||
(h_small, w_small) = small_img.shape[:2]
|
||||
if VERBOSE:
|
||||
print("Van %dx%dpx naar %dx%dpx geschaald"%(h,w,h_small,w_small))
|
||||
|
||||
## Detecteer aruco markers ##
|
||||
(corners, ids, rejected) = detector.detectMarkers(small_img)
|
||||
new_image = cv2.aruco.drawDetectedMarkers(
|
||||
small_img,
|
||||
corners,
|
||||
ids)
|
||||
assert len(ids) == 4, "Not enough markers found in " + str(file)
|
||||
if VERBOSE:
|
||||
print("%d markers gedetecteerd" %len(ids))
|
||||
|
||||
## Zoek de 'binnenste' hoekjes ##
|
||||
i = 0
|
||||
x = np.zeros(4, dtype=np.int32)
|
||||
y = np.zeros(4, dtype=np.int32)
|
||||
for corner in corners:
|
||||
x[i] = corner[0][getCorner(ids[i])][0]
|
||||
y[i] = corner[0][getCorner(ids[i])][1]
|
||||
cv2.circle(
|
||||
new_image,
|
||||
(x[i], y[i]),
|
||||
radius=3,
|
||||
color=(0, 254, 254),
|
||||
thickness=-1)
|
||||
i += 1
|
||||
if VERBOSE:
|
||||
print("Gedecteerde hoekjes (recht): ")
|
||||
print("\t x: ", end='')
|
||||
print(x)
|
||||
print("\t y: ", end='')
|
||||
print(y)
|
||||
|
||||
## Draai de plaatjes recht ##
|
||||
x0 = x[np.where(ids == 0)[0][0]]
|
||||
x1 = x[np.where(ids == 1)[0][0]]
|
||||
x_dif = x0-x1
|
||||
|
||||
y0 = y[np.where(ids == 0)[0][0]]
|
||||
y1 = y[np.where(ids == 1)[0][0]]
|
||||
y_dif = y0 - y1
|
||||
|
||||
angle_rad = np.arctan(y_dif/x_dif)
|
||||
angle_deg = angle_rad * 180.0 / np.pi
|
||||
if(VERBOSE):
|
||||
print("%d graden gedraaid"%angle_deg)
|
||||
|
||||
(cX, cY) = (w_small // 2, h_small // 2)
|
||||
matrix = cv2.getRotationMatrix2D((cX, cY), angle_deg, 1.0)
|
||||
warp_img = cv2.warpAffine(new_image, matrix, (w_small, h_small))
|
||||
|
||||
## Herdetecteer de binnenste hoekjes op de gedraaide plaatjes ##
|
||||
mask = cv2.inRange(warp_img, (0, 253, 253), (0, 255, 255))
|
||||
warped_corners = []
|
||||
for i in range(4):
|
||||
coordinate = cv2.minMaxLoc(mask)[3]
|
||||
warped_corners.append(coordinate)
|
||||
cv2.circle(mask, warped_corners[i], 10, (0, 0, 0), -1)
|
||||
|
||||
if VERBOSE:
|
||||
print("Gedecteerde hoekjes (gedraaid): ")
|
||||
print("\t", warped_corners)
|
||||
|
||||
## Teken rode balken voor controle ##
|
||||
# feature voor ooit, nogal lastig
|
||||
|
||||
## Calibratie van afstand met betrekking tot pixels ##
|
||||
xs = [corner[0] for corner in warped_corners]
|
||||
ys = [corner[1] for corner in warped_corners]
|
||||
x_max = np.amax(xs)
|
||||
x_min = np.amin(xs)
|
||||
x_diff = x_max - x_min
|
||||
calib_scale = x_diff / CALIB_AFSTAND
|
||||
if VERBOSE:
|
||||
print("Berekende schaal: %d pixels/mm"%calib_scale)
|
||||
|
||||
## Crop de plaatjes ##
|
||||
top_left_x = findMin(warped_corners, 0)
|
||||
top_left_y = findMin(warped_corners, 1)
|
||||
bot_right_x = findMax(warped_corners, 0)
|
||||
bot_right_y = findMax(warped_corners, 1)
|
||||
|
||||
offset = int((OFFSET+CORRECTIE)*calib_scale)
|
||||
crop_img = warp_img[
|
||||
top_left_y+offset:bot_right_y-offset,
|
||||
top_left_x+offset:bot_right_x-offset]
|
||||
|
||||
## Check voor rode balken ##
|
||||
# zie boven
|
||||
|
||||
## Output ##
|
||||
if PLAATJES:
|
||||
cv2.imshow('window', warp_img)
|
||||
cv2.imshow('cropped', crop_img)
|
||||
if SAVE:
|
||||
cv2.imwrite(out_filename, crop_img)
|
||||
if PAUZE or PLAATJES:
|
||||
cv2.waitKey(0)
|
||||
if VERBOSE:
|
||||
print("=============================================")
|
||||
path = os.path.join(input_directory, folder)
|
||||
if (path).endswith("_out"):
|
||||
continue
|
||||
out_folder = path + "_out"
|
||||
if (os.path.exists(out_folder) == False):
|
||||
if VERBOSE:
|
||||
print("Created folder: " + out_folder)
|
||||
os.mkdir(out_folder)
|
||||
|
||||
for file in os.listdir(os.path.join(input_directory, folder)):
|
||||
## Laad plaatjes in kleur ##
|
||||
filename = input_directory + '/' + folder + '/' + file
|
||||
img = cv2.imread(filename, 1)
|
||||
|
||||
assert img is not None, "Image path is wrong " + filename
|
||||
if VERBOSE:
|
||||
print(file)
|
||||
|
||||
## Herschaal de fotos ##
|
||||
(h, w) = img.shape[:2]
|
||||
x_scale = int(w/100*SCHAAL)
|
||||
y_scale = int(h/100*SCHAAL)
|
||||
if SCHAAL != 100:
|
||||
small_img = cv2.resize(img, (x_scale, y_scale))
|
||||
else:
|
||||
small_img = img
|
||||
(h_small, w_small) = small_img.shape[:2]
|
||||
if VERBOSE:
|
||||
print("Van %dx%dpx naar %dx%dpx geschaald"%(h,w,h_small,w_small))
|
||||
|
||||
## Detecteer aruco markers ##
|
||||
(corners, ids, rejected) = detector.detectMarkers(small_img)
|
||||
new_image = cv2.aruco.drawDetectedMarkers(
|
||||
small_img,
|
||||
corners,
|
||||
ids)
|
||||
|
||||
if ids is None:
|
||||
print("Skipping: ", filename)
|
||||
print("=============================================")
|
||||
continue
|
||||
if len(ids) != 4:
|
||||
print("Skipping: ", filename)
|
||||
print("=============================================")
|
||||
continue
|
||||
|
||||
if VERBOSE:
|
||||
print("%d markers gedetecteerd" %len(ids))
|
||||
|
||||
## Zoek de 'binnenste' hoekjes ##
|
||||
i = 0
|
||||
x = np.zeros(4, dtype=np.int32)
|
||||
y = np.zeros(4, dtype=np.int32)
|
||||
for corner in corners:
|
||||
x[i] = corner[0][getCorner(ids[i])][0]
|
||||
y[i] = corner[0][getCorner(ids[i])][1]
|
||||
cv2.circle(
|
||||
new_image,
|
||||
(x[i], y[i]),
|
||||
radius=5,
|
||||
color=(0, 254, 254),
|
||||
thickness=-1)
|
||||
i += 1
|
||||
if VERBOSE:
|
||||
print("Gedecteerde hoekjes (recht): ")
|
||||
print("\t x: ", end='')
|
||||
print(x)
|
||||
print("\t y: ", end='')
|
||||
print(y)
|
||||
|
||||
## Draai de plaatjes recht ##
|
||||
x0 = x[np.where(ids == 0)[0][0]]
|
||||
x1 = x[np.where(ids == 1)[0][0]] # TODO: Fix whatevers happening here
|
||||
x_dif = x0-x1
|
||||
|
||||
y0 = y[np.where(ids == 0)[0][0]]
|
||||
y1 = y[np.where(ids == 1)[0][0]]
|
||||
y_dif = y0 - y1
|
||||
|
||||
angle_rad = np.arctan(y_dif/x_dif)
|
||||
angle_deg = angle_rad * 180.0 / np.pi
|
||||
if(VERBOSE):
|
||||
print("%d graden gedraaid"%angle_deg)
|
||||
|
||||
(cX, cY) = (w_small // 2, h_small // 2)
|
||||
matrix = cv2.getRotationMatrix2D((cX, cY), angle_deg, 1.0)
|
||||
warp_img = cv2.warpAffine(new_image, matrix, (w_small, h_small))
|
||||
|
||||
## Herdetecteer de binnenste hoekjes op de gedraaide plaatjes ##
|
||||
mask = cv2.inRange(warp_img, (0, 253, 253), (0, 255, 255))
|
||||
warped_corners = []
|
||||
for i in range(4):
|
||||
coordinate = cv2.minMaxLoc(mask)[3]
|
||||
warped_corners.append(coordinate)
|
||||
cv2.circle(mask, warped_corners[i], 10, (0, 0, 0), -1)
|
||||
|
||||
if VERBOSE:
|
||||
print("Gedecteerde hoekjes (gedraaid): ")
|
||||
print("\t", warped_corners)
|
||||
|
||||
## Teken rode balken voor controle ##
|
||||
# feature voor ooit, nogal lastig
|
||||
|
||||
## Calibratie van afstand met betrekking tot pixels ##
|
||||
xs = [corner[0] for corner in warped_corners]
|
||||
ys = [corner[1] for corner in warped_corners]
|
||||
x_max = np.amax(xs)
|
||||
x_min = np.amin(xs)
|
||||
x_diff = x_max - x_min
|
||||
calib_scale = x_diff / CALIB_AFSTAND
|
||||
if VERBOSE:
|
||||
print("Berekende schaal: %d pixels/mm"%calib_scale)
|
||||
|
||||
## Crop de plaatjes ##
|
||||
top_left_x = findMin(warped_corners, 0)
|
||||
top_left_y = findMin(warped_corners, 1)
|
||||
bot_right_x = findMax(warped_corners, 0)
|
||||
bot_right_y = findMax(warped_corners, 1)
|
||||
|
||||
offset = int((OFFSET+CORRECTIE)*calib_scale)
|
||||
crop_img = warp_img[
|
||||
top_left_y+offset:bot_right_y-offset,
|
||||
top_left_x+offset:bot_right_x-offset]
|
||||
|
||||
## Check voor rode balken ##
|
||||
# zie boven
|
||||
|
||||
## Output ##
|
||||
if PLAATJES:
|
||||
cv2.imshow('window', warp_img)
|
||||
cv2.imshow('cropped', crop_img)
|
||||
if SAVE:
|
||||
out_path = out_folder + "/" + file
|
||||
print("Saving to:", out_path)
|
||||
cv2.imwrite(out_path, crop_img)
|
||||
if PAUZE or PLAATJES:
|
||||
cv2.waitKey(0)
|
||||
if VERBOSE:
|
||||
print("=============================================")
|
||||
|
||||
cv2.destroyAllWindows()
|
9
src/helpers/statistics.py
Normal file
9
src/helpers/statistics.py
Normal file
@ -0,0 +1,9 @@
|
||||
import numpy as np
|
||||
|
||||
def imgStats(img):
|
||||
mean = np.zeros(3)
|
||||
std = np.zeros(3)
|
||||
for i in range(img.shape[2]):
|
||||
mean[i] = np.mean(img[:, :, i])
|
||||
std[i] = np.std(img[:, :, i])
|
||||
return mean, std
|
10
src/suite.py
10
src/suite.py
@ -9,6 +9,7 @@ import cv2
|
||||
import time
|
||||
import matplotlib.pyplot as plt
|
||||
import json
|
||||
from helpers.statistics import imgStats
|
||||
|
||||
## UI config load
|
||||
PROJECT_PATH = pathlib.Path(__file__).parent
|
||||
@ -193,6 +194,13 @@ class MainApp:
|
||||
self.axs[column, row].xaxis.set_major_formatter(lambda x, pos: str(x*canny_step))
|
||||
self.axs[column, row].yaxis.set_major_formatter(lambda x, pos: str(x*canny_step))
|
||||
|
||||
def writeStats(self, img, labels, column, row):
|
||||
mean, std = imgStats(img)
|
||||
self.axs[column, row].title.set_text(
|
||||
"mean: %c:%d %c:%d %c:%d \n std: %c:%d %c:%d %c:%d"
|
||||
%(labels[0], mean[0], labels[1], mean[1], labels[2], mean[2],
|
||||
labels[0], std[0], labels[1], std[1], labels[2], std[2]))
|
||||
|
||||
def update(self, event=None):
|
||||
path = self.img_path.get()
|
||||
|
||||
@ -250,6 +258,7 @@ class MainApp:
|
||||
# Canny edge
|
||||
img_canny = cv2.Canny(image=img_blur,threshold1=ct1,threshold2=ct2)
|
||||
self.add_output(img_canny, "Canny Edge")
|
||||
self.writeStats(img, ('B', 'G', 'R'), 0, 0)
|
||||
|
||||
# BGR
|
||||
self.add_output(img[:, :, 0], "BGR B")
|
||||
@ -268,6 +277,7 @@ class MainApp:
|
||||
|
||||
if img_hsv is not None:
|
||||
self.drawHist(img_hsv, ('H', 'S', 'V'), 0, 1)
|
||||
self.writeStats(img_hsv, ('H', 'S', 'V'), 0, 1)
|
||||
|
||||
# Canny Heatmap
|
||||
self.drawCannyHM(img, 1, 1)
|
||||
|
Loading…
Reference in New Issue
Block a user