Adjusted template extraction for folder parsing

This commit is contained in:
Tom Selier 2023-09-25 20:24:04 +02:00
parent a07f8cc5c6
commit 394d0ef941

View File

@ -3,11 +3,14 @@ Script to extract 10cm x 10cm images from the template
Accounts for (minor) rotation.
command:
python template.py input_directory
python template.py input_folder output_folder
volgorde maakt uit! heb niet die fancy library gebruikt
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
@ -21,7 +24,7 @@ import os
## Parameters ##
# [%] Schaal output in percentages
SCHAAL = 100
SCHAAL = 25
# [mm] 120 op calib a4, 180 op template
@ -79,167 +82,139 @@ def findMin(array, index):
min_val = element[index]
return min_val
input_directory = sys.argv[1]
input_folder = sys.argv[1]
output_folder = sys.argv[2]
if(not os.path.isdir(input_directory)):
print(input_directory)
print("Input directory not found")
if(not os.path.isdir(input_folder)):
print("Input folder 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 folder in os.listdir(input_directory):
if folder.endswith('.py'):
print("Skipping", folder)
continue
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)
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:
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.imwrite(out_filename, crop_img)
if PAUZE or PLAATJES:
cv2.waitKey(0)
if VERBOSE:
print("=============================================")
cv2.destroyAllWindows()