From af9444ab26cbb3230c5e20bce2af78d9a4d38c77 Mon Sep 17 00:00:00 2001 From: Xaver Roos Date: Thu, 14 Apr 2022 14:27:55 +0200 Subject: [PATCH] [distance_calculation] checkerboard detection works, calculation not yet --- etrack/calibration_functions.py | 23 ++++---- etrack/distance_calibration.py | 101 +++++++++++++++++--------------- 2 files changed, 68 insertions(+), 56 deletions(-) diff --git a/etrack/calibration_functions.py b/etrack/calibration_functions.py index 842c298..a42da78 100644 --- a/etrack/calibration_functions.py +++ b/etrack/calibration_functions.py @@ -6,16 +6,20 @@ from IPython import embed def crop_frame(frame, marker_positions): # load the four marker positions - bottom_left = marker_positions[0]['bottom left corner'] - bottom_right = marker_positions[0]['bottom right corner'] - top_left = marker_positions[0]['top left corner'] - top_right = marker_positions[0]['top right corner'] + bottom_left_x = marker_positions[0]['bottom left corner'][0] + bottom_left_y = marker_positions[0]['bottom left corner'][1] + bottom_right_x = marker_positions[0]['bottom right corner'][0] + bottom_right_y = marker_positions[0]['bottom right corner'][1] + top_left_x = marker_positions[0]['top left corner'][0] + top_left_y = marker_positions[0]['top left corner'][1] + top_right_x = marker_positions[0]['top right corner'][0] + top_right_y = marker_positions[0]['top right corner'][1] # define boundaries of frame, taken by average of points on same line but slightly different pixel values - left_bound = int(np.mean([bottom_left[0], top_left[0]])) - right_bound = int(np.mean([bottom_right[0], top_right[0]])) - top_bound = int(np.mean([top_left[1], top_right[1]])) - bottom_bound = int(np.mean([bottom_left[1], bottom_right[1]])) + left_bound = int(np.mean([bottom_left_x, top_left_x])) + right_bound = int(np.mean([bottom_right_x, top_right_x])) + top_bound = int(np.mean([top_left_y, top_right_y])) + bottom_bound = int(np.mean([bottom_left_y, bottom_right_y])) # crop the frame by boundary values crop_frame = frame[top_bound:bottom_bound, left_bound:right_bound] @@ -33,7 +37,7 @@ def crop_frame(frame, marker_positions): x_width = np.arange(0, len(diff_width), 1) x_height = np.arange(0, len(diff_height), 1) - return frame_width, frame_height, diff_width, diff_height, x_width, x_height + return crop_frame, frame_width, frame_height, diff_width, diff_height, x_width, x_height def rotation_angle(): pass @@ -63,7 +67,6 @@ def threshold_crossings(data, threshold_factor): if lower_idx < half_window_size: # ..if indice smaller than window size near indice 0 half_window_size = lower_idx lower_window = data[lower_idx[0] - int(half_window_size):lower_idx[0] + int(half_window_size)] # create data window from -window_size to +window_size - min_window = np.min(lower_window) # take minimum of window min_idx = np.where(data == min_window) # find indice where minimum is diff --git a/etrack/distance_calibration.py b/etrack/distance_calibration.py index 6a88535..10e951e 100644 --- a/etrack/distance_calibration.py +++ b/etrack/distance_calibration.py @@ -14,9 +14,8 @@ from calibration_functions import crop_frame, threshold_crossings, checkerboard_ class DistanceCalibration(): - def __init__(self, file_name, frame_number, x_0=154, y_0=1318, cam_dist=1.36, width=1.35, height=0.805, width_pixel=1900, height_pixel=200, checkerboard_width=0.24, checkerboard_height=0.18, - checkerboard_width_pixel=500, checkerboard_height_pixel=350, rectangle_width=0.024, rectangle_height=0.0225, rectangle_width_pixel=100, rectangle_height_pixel=90, - rectangle_count_width=9, rectangle_count_height=7) -> None: + def __init__(self, file_name, frame_number, x_0=154, y_0=1318, cam_dist=1.36, tank_width=1.35, tank_height=0.805, width_pixel=1900, height_pixel=200, + checkerboard_width=0.24, checkerboard_height=0.18, checkerboard_width_pixel=500, checkerboard_height_pixel=350) -> None: super().__init__() # aktualisieren """Calibration of the dimensions of the tank. Conversion of pixel into meter. Width refers to the "x-axis", height to the "y-axis" of the tank. @@ -42,21 +41,16 @@ class DistanceCalibration(): self._width_pix = width_pixel self._height_pix = height_pixel self._cam_dist = cam_dist - self._width = width - self._height = height + self._tank_width = tank_width + self._tank_height = tank_height self._cb_width = checkerboard_width self._cb_height = checkerboard_height self._cb_width_pix = checkerboard_width_pixel self._cb_height_pix = checkerboard_height_pixel - self._rect_width = rectangle_width - self._rect_height = rectangle_height - self._x_factor = self.width / self.width_pix # m/pix - self._y_factor = self.height / self.height_pix # m/pix + self._x_factor = tank_width / width_pixel # m/pix + self._y_factor = tank_height / height_pixel # m/pix - # self.mark_crop_positions - # self.threshold_crossings - # self.checkerboard_position - # self.filter_data + self.distance_calculation @property def x_0(self): @@ -175,7 +169,7 @@ class DistanceCalibration(): # care: y-axis is inverted, top values are low, bottom values are high - frame_width, frame_height, diff_width, diff_height, _, _ = crop_frame(frame, marker_positions) # crop frame to given marker positions + croped_frame, frame_width, frame_height, diff_width, diff_height, _, _ = crop_frame(frame, marker_positions) # crop frame to given marker positions thresh_fact = 7 # factor by which the min/max is divided to calculate the upper and lower thresholds @@ -191,51 +185,65 @@ class DistanceCalibration(): print('lower crossings:', lci_width) print('upper crossings:', uci_width) + # position of checkerboard in width print('width..') width_position, left_width_position, right_width_position = checkerboard_position(lci_width, uci_width) + # position of checkerboard in height print('height..') - height_position, left_height_position, right_height_position = checkerboard_position(lci_height, uci_height) # check if working + height_position, left_height_position, right_height_position = checkerboard_position(lci_height, uci_height) # left height refers to top, right height to bottom + # final corner positions of checkerboard top_left = np.array([left_width_position, left_height_position]) top_right = np.array([right_width_position, left_height_position]) bottom_left = np.array([left_width_position, right_height_position]) bottom_right = np.array([right_width_position, right_height_position]) print(top_left, top_right, bottom_left, bottom_right) - fig, ax = plt.subplots() - ax.imshow(frame) - # ax.autoscale(False) - for p in top_left, top_right, bottom_left, bottom_right: - ax.scatter(p[0], p[1]) - ax.set_xlim(bottom_left_marker[0], bottom_right_marker[0]) - ax.set_ylim(bottom_left_marker[1], top_left_marker[1]) - # plt.show() - # locations of checkerboard position do not yet fit the ones of the frame yet (visually checked) + # fig, ax = plt.subplots() + # ax.imshow(croped_frame) + # for p in top_left, top_right, bottom_left, bottom_right: + # ax.scatter(p[0], p[1]) + # plt.show() # embed() # quit() - # find which indices (=pixels) represent edges of checkerboard by the corresponding sequence of ups and downs - # both for width and height - # assign x and y positions for the checkerboard corners + + return top_left, top_right, bottom_left, bottom_right + + + def distance_calculation(self, top_left, top_right, bottom_left, bottom_right, marker_positions): + + checkerboard_width = 0.24 + checkerboard_height = 0.18 + + checkerboard_width_pixel = top_right[0] - top_left[0] + checkerboard_height_pixel = bottom_right[1] - top_right[1] + + x_factor = checkerboard_width / checkerboard_width_pixel + y_factor = checkerboard_height / checkerboard_height_pixel - # pixel to meter factor for default position with checkerboard in center of tank underneath camera + bottom_left_x = marker_positions[0]['bottom left corner'][0] + bottom_left_y = marker_positions[0]['bottom left corner'][1] + bottom_right_x = marker_positions[0]['bottom right corner'][0] + bottom_right_y = marker_positions[0]['bottom right corner'][1] + top_left_x = marker_positions[0]['top left corner'][0] + top_left_y = marker_positions[0]['top left corner'][1] + top_right_x = marker_positions[0]['top right corner'][0] + top_right_y = marker_positions[0]['top right corner'][1] + + tank_width_pixel = np.mean([bottom_right_x - bottom_left_x, top_right_x - top_left_x]) + tank_height_pixel = np.mean([bottom_left_y - top_left_y, bottom_right_y - top_right_y]) + + tank_width = tank_width_pixel * x_factor + tank_height = tank_height_pixel * y_factor - # plt.plot(diff_width) - plt.plot(diff_width) - # plt.axhline(np.min(diff_height) / thresh_fact) - # plt.axhline(np.max(diff_height) / thresh_fact) - for l in lci_width: - plt.axvline(l, color='yellow') - for u in uci_width: - plt.axvline(u, color='green') - # plt.plot(frame_width, label='height') - # plt.plot(frame_width, label='width') - plt.legend() - plt.show() + print(tank_width, tank_height) + embed() quit() - + pass + if __name__ == "__main__": file_name = "/home/efish/etrack/videos/2022.03.28_3.mp4" @@ -244,10 +252,11 @@ if __name__ == "__main__": # marker_positions = dc.mark_crop_positions() - dc.detect_checkerboard(file_name, frame_number=frame_number, marker_positions=np.load('marker_positions.npy', allow_pickle=True)) - - # print(sys.argv[0]) - # print (sys.argv[1]) - # vid1 = sys.argv[1] + top_left, top_right, bottom_left, bottom_right = dc.detect_checkerboard(file_name, frame_number=frame_number, marker_positions=np.load('marker_positions.npy', allow_pickle=True)) + dc.distance_calculation(top_left, top_right, bottom_left, bottom_right, marker_positions = np.load('marker_positions.npy', allow_pickle=True)) + + # mark_crop_positions why failing plot at end? + # with rectangles of checkerboard? + # embed() \ No newline at end of file