mirror of
https://github.com/furrysalamander/rubedo.git
synced 2025-09-26 23:29:12 +08:00
Working on formatting report data
This commit is contained in:
parent
9f60da8950
commit
24116d713f
@ -8,12 +8,17 @@
|
||||
}
|
||||
},
|
||||
"runArgs": [
|
||||
"--device=/dev/video2"
|
||||
// "--device=/dev/video2"
|
||||
],
|
||||
"customizations": {
|
||||
"extensions": [
|
||||
"ms-python.python",
|
||||
"076923.python-image-preview"
|
||||
]
|
||||
],
|
||||
"vscode": {
|
||||
"extensions": [
|
||||
"ms-python.python"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -45,8 +45,12 @@ def compute_x_value(pixel_values: np.ndarray):
|
||||
|
||||
def generate_height_data_for_frame(frame: np.ndarray):
|
||||
frame = crop_frame(frame)
|
||||
# cv2.imwrite(f"alignment_test/cropped.png", frame)
|
||||
frame = preprocess_frame(frame)
|
||||
# cv2.imwrite(f"alignment_test/processed.png", frame)
|
||||
frame = apply_gaussian_blur(frame)
|
||||
# cv2.imwrite(f"alignment_test/blurred.png", frame)
|
||||
# exit()
|
||||
|
||||
frame_height_data = np.ndarray(frame.shape[0])
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
OUTPUT_GRAPH = False
|
||||
OUTPUT_FRAMES = False
|
||||
OUTPUT_FRAMES = True
|
||||
OUTPUT_HEIGHT_MAPS = False
|
||||
|
||||
CROP_X_OFFSET = 200
|
||||
CROP_Y_OFFSET = 0
|
||||
CROP_FRAME_SIZE_X = 200
|
||||
CROP_X_OFFSET = 220
|
||||
CROP_Y_OFFSET = 11
|
||||
CROP_FRAME_SIZE_X = 45
|
||||
CROP_FRAME_SIZE_Y = 60
|
||||
|
@ -8,7 +8,7 @@ import pickle
|
||||
def main():
|
||||
patterns: list[PatternInfo] = []
|
||||
for x in range(20, 286, 31):
|
||||
for y in range(20, 130, 45):
|
||||
for y in range(80, 190, 45):
|
||||
patterns.append(
|
||||
PatternInfo(
|
||||
0, 0.06,
|
||||
@ -36,9 +36,8 @@ def main():
|
||||
pattern
|
||||
))
|
||||
)
|
||||
break
|
||||
|
||||
with open("testing_adjustments.pkl", "wb") as f:
|
||||
with open("matte_white_ambient_light.pkl", "wb") as f:
|
||||
pickle.dump(pa_scans, f)
|
||||
|
||||
# results = generate_pa_results_for_pattern(calibration_pattern)
|
||||
|
@ -3,55 +3,115 @@ import matplotlib.pyplot as plt
|
||||
from pprint import pprint
|
||||
import numpy as np
|
||||
from pa_result import PaResult
|
||||
|
||||
with open("testing_adjustments.pkl", "rb") as f:
|
||||
data: list[PaResult] = pickle.load(f)
|
||||
|
||||
pa_values = list([x[0] for x in data[:10]])
|
||||
|
||||
data_clean = list([(x, y.score) for x, y in data])
|
||||
pprint(list(sorted(data_clean, key=lambda x: x[1])))
|
||||
x, y = list(zip(*data_clean))
|
||||
p = np.polyfit(x, y, 3)
|
||||
plt.plot(pa_values, np.poly1d(p)(pa_values))
|
||||
plt.scatter(x, y)
|
||||
plt.plot(pa_values, np.poly1d(p)(pa_values))
|
||||
|
||||
|
||||
from visualization import generate_color_map, generate_3d_height_map
|
||||
import statistics
|
||||
from matplotlib.colors import LinearSegmentedColormap
|
||||
from scipy.stats import gaussian_kde
|
||||
from collections import Counter
|
||||
|
||||
|
||||
# Calculate the point density
|
||||
# xy = np.vstack([x,y])
|
||||
# z = gaussian_kde(xy)(xy)
|
||||
def plot_scatter(data_clean: list[tuple[float, float]], dataset: str, ax):
|
||||
x, y = list(zip(*data_clean))
|
||||
p = np.polyfit(x, y, 3)
|
||||
trendline_x = np.linspace(min(x), max(x), 100)
|
||||
|
||||
# fig, ax = plt.subplots()
|
||||
# ax.set_xlabel("PA Value")
|
||||
# ax.set_ylabel("Score")
|
||||
# ax.scatter(x, y, c=z, s=100)
|
||||
# ax.plot(pa_values, np.poly1d(p)(pa_values))
|
||||
# Calculate the R-squared value
|
||||
y_pred = np.poly1d(p)(x)
|
||||
ss_res = np.sum((y - y_pred) ** 2)
|
||||
ss_tot = np.sum((y - np.mean(y)) ** 2)
|
||||
r2 = 1 - (ss_res / ss_tot)
|
||||
|
||||
ax.set_title(dataset)
|
||||
|
||||
# Calculate the point density
|
||||
xy = np.vstack([x, y])
|
||||
z = gaussian_kde(xy)(xy)
|
||||
ax.scatter(x, y, c=z)
|
||||
ax.plot(trendline_x, np.poly1d(p)(trendline_x))
|
||||
ax.set_xlabel("PA Value")
|
||||
ax.set_ylabel("Score")
|
||||
|
||||
# add equation and R-squared annotation
|
||||
equation = f'y = {p[0]:.0f}x^3 + {p[1]:.0f}x^2 + {p[2]:.0f}x + {p[3]:.0f}'
|
||||
r2_text = f'R-squared = {r2:.2f}'
|
||||
ax.annotate(equation + '\n' + r2_text, xy=(0.1, 0.95), xycoords='axes fraction', fontsize=12, ha='left', va='top')
|
||||
|
||||
|
||||
winning_results = []
|
||||
def generate_consistency_chart(data_clean: list[tuple[float, float]], dataset:str, ax):
|
||||
winning_results = []
|
||||
|
||||
for i in range(0, len(data_clean), 10):
|
||||
x = i
|
||||
individual_scan = list(sorted(data_clean[x:x+10], key=lambda x: x[1]))
|
||||
pprint(individual_scan[0])
|
||||
winning_results.append(individual_scan[0][0])
|
||||
# pprint(data_clean[x:x+10])
|
||||
for i in range(0, len(data_clean), 10):
|
||||
x = i
|
||||
individual_scan = list(sorted(data_clean[x:x+10], key=lambda x: x[1]))
|
||||
pprint(individual_scan[0])
|
||||
winning_results.append(individual_scan[0][0])
|
||||
# pprint(data_clean[x:x+10])
|
||||
counter = Counter(winning_results)
|
||||
|
||||
counter = Counter(winning_results)
|
||||
print(counter)
|
||||
fig, ax = plt.subplots()
|
||||
ax.set_ylabel("Winning Frequency")
|
||||
ax.set_xlabel("PA Value")
|
||||
ax.bar(counter.keys(), counter.values(), width=0.06/10)
|
||||
# fig, ax = plt.subplots()
|
||||
ax.set_ylabel("Winning Frequency")
|
||||
ax.set_xlabel("PA Value")
|
||||
ax.bar(counter.keys(), counter.values(), width=0.06/10)
|
||||
|
||||
from visualization import generate_color_map, generate_3d_height_map
|
||||
generate_color_map(data[3][1])
|
||||
generate_3d_height_map(data[3][1])
|
||||
# Calculate the standard deviation of the winning results
|
||||
std_dev = statistics.stdev(winning_results)
|
||||
|
||||
plt.show()
|
||||
# Add the standard deviation as a subtitle for the plot
|
||||
ax.set_title(f"Standard deviation: {std_dev:.5e}", fontsize=10)
|
||||
# fig.suptitle(dataset)
|
||||
# return fig
|
||||
|
||||
|
||||
def main():
|
||||
datasets = [
|
||||
("matte_black_ambient_light.pkl", "Matte Black Print Bed, Black Filament, Ambient Lighting"),
|
||||
("matte_black_dark.pkl", "Matte Black Print Bed, Black Filament, No Ambient Light"),
|
||||
("matte_white_ambient_light.pkl", "Matte Black Print Bed, White Filament, Ambient Lighting"),
|
||||
("matte_white_dark.pkl", "Matte Black Print Bed, White Filament, No Ambient Light"),
|
||||
("pei_black_ambient_light.pkl", "PEI Print Bed, Black Filament, Ambient Light"),
|
||||
("pei_black_dark.pkl", "PEI Print Bed, Black Filament, No Ambient Light"),
|
||||
("pei_white_ambient_light.pkl", "PEI Print Bed, White Filament, Ambient Light"),
|
||||
("pei_white_dark.pkl", "PEI Print Bed, White Filament, No Ambient Light"),
|
||||
("texture_black_ambient_light.pkl", "Textured Print Bed, Black Filament, Ambient Light"),
|
||||
("texture_black_dark.pkl", "Textured Print Bed, Black Filament, No Ambient Light"),
|
||||
("texture_white_ambient_light.pkl", "Textured Print Bed, White Filament, Ambient Light"),
|
||||
("texture_white_dark.pkl", "Textured Print Bed, White Filament, No Ambient Light")
|
||||
]
|
||||
|
||||
|
||||
fig_scatter, axs_scatter = plt.subplots(3, 4)
|
||||
fig_bar, axs_bar = plt.subplots(3, 4)
|
||||
|
||||
|
||||
|
||||
for i, dataset in enumerate(datasets):
|
||||
|
||||
with open(dataset[0], "rb") as f:
|
||||
# List of tuples where tuples are the PaValue and the PaResult
|
||||
data: list[tuple[float, PaResult]] = pickle.load(f)
|
||||
|
||||
data_clean: list[tuple[float, float]] = list([(x, y.score) for x, y in data])
|
||||
|
||||
row = i // 4
|
||||
col = i % 4
|
||||
|
||||
plot_scatter(data_clean, dataset[1], axs_scatter[row, col])
|
||||
generate_consistency_chart(data_clean, dataset[1], axs_bar[row, col])
|
||||
|
||||
# Set the same limits for the x and y axes of all subplots
|
||||
axs_scatter[row, col].set_ylim(0, 350)
|
||||
|
||||
# axs_bar[row, col].set_xlim(xlim)
|
||||
# axs_bar[row, col].set_ylim(ylim)
|
||||
|
||||
# Adjust the spacing between subplots
|
||||
fig_scatter.tight_layout()
|
||||
fig_bar.tight_layout()
|
||||
|
||||
# generate_3d_height_map(data[5][1])
|
||||
# generate_color_map(data[5][1])
|
||||
|
||||
plt.show()
|
||||
|
||||
if __name__=="__main__":
|
||||
main()
|
||||
|
2
main.py
2
main.py
@ -32,7 +32,7 @@ def generate_pa_results_for_pattern(pattern_info: PatternInfo)-> list[PaResult]:
|
||||
|
||||
# Hardcoding a buffer distance of 3mm here for now. Adjust if needed.
|
||||
with tempfile.TemporaryDirectory("pa_videos") as dir:
|
||||
video_files = record_pattern(pattern_info, 3, dir)
|
||||
video_files = record_pattern(pattern_info, 4, dir)
|
||||
|
||||
for video_file in video_files:
|
||||
results.append(
|
||||
|
22
pa_statistics.py
Normal file
22
pa_statistics.py
Normal file
@ -0,0 +1,22 @@
|
||||
from pa_result import PaResult
|
||||
import numpy as np
|
||||
|
||||
class PaStatistics:
|
||||
def __init__(self, lines: list[PaResult], output_directory):
|
||||
self.lines = lines
|
||||
self.output_directory = output_directory
|
||||
self.scores = list([x.score for x in lines])
|
||||
|
||||
def average_deviation(self):
|
||||
return np.average(self.scores)
|
||||
|
||||
def generate_graphs():
|
||||
pass
|
||||
|
||||
def generate_height_maps():
|
||||
pass
|
||||
|
||||
def __str__(self) -> str:
|
||||
return \
|
||||
f"""Average deviation: {self.average_deviation()}
|
||||
"""
|
@ -12,7 +12,7 @@ def crop_frame(frame):
|
||||
|
||||
|
||||
def preprocess_frame(frame):
|
||||
lowerb = np.array([0, 0, 120])
|
||||
lowerb = np.array([0, 0, 50])
|
||||
upperb = np.array([255, 255, 255])
|
||||
red_line = cv2.inRange(frame, lowerb, upperb)
|
||||
|
||||
|
@ -35,7 +35,7 @@ ffmpeg_cmd = [
|
||||
def record_pattern(info: PatternInfo, buffer_distance: float, output_directory: str) -> list:
|
||||
send_gcode("STATUS_OFF") # Turn off LEDs
|
||||
send_gcode("LASER_ON") # Turn on line laser
|
||||
send_gcode("SET_LED LED=chamber_lights WHITE=0.01")
|
||||
send_gcode("SET_LED LED=chamber_lights WHITE=0")
|
||||
time.sleep(0.5)
|
||||
|
||||
lines_start_y = info.lines_start_y()
|
||||
@ -57,7 +57,7 @@ def record_pattern(info: PatternInfo, buffer_distance: float, output_directory:
|
||||
|
||||
with subprocess.Popen(ffmpeg_cmd + [video_file]) as ffmpeg:
|
||||
time.sleep(0.5)
|
||||
print(move_absolute(scan_end_x, f=600))
|
||||
print(move_absolute(scan_end_x, f=400))
|
||||
wait_until_printer_at_location(scan_end_x)
|
||||
|
||||
# stop recording
|
||||
|
@ -6,31 +6,20 @@ from pathlib import Path
|
||||
|
||||
from constants import *
|
||||
|
||||
|
||||
## FIXME:
|
||||
#
|
||||
# This WHOLE file is currently a broken mess. Needs to be cleaned up and fixed.
|
||||
#
|
||||
#
|
||||
#
|
||||
|
||||
def generate_color_map(pa_result: PaResult):
|
||||
fig, ax = plt.subplots()
|
||||
|
||||
y = np.arange(len(pa_result.height_data))
|
||||
x = np.arange(len(pa_result.height_data[0]))
|
||||
x = np.arange(len(pa_result.height_data))
|
||||
y = np.arange(len(pa_result.height_data[0]))
|
||||
(x ,y) = np.meshgrid(x,y)
|
||||
|
||||
# ax.plot_surface(x, y, z_data,cmap=cm.coolwarm,linewidth=0, antialiased=False)
|
||||
ax.pcolormesh(x, y, pa_result.height_data, cmap='RdBu')
|
||||
# ax.scatter(x, y, z)
|
||||
ax.pcolormesh(x, y, np.transpose(pa_result.height_data), cmap='plasma')
|
||||
ax.set_xlabel("X Value (Frame)")
|
||||
ax.set_ylabel("Y Value (Pixel)")
|
||||
|
||||
ax.set_title("Height Map", fontsize=10)
|
||||
return fig
|
||||
|
||||
def generate_cross_section_video():
|
||||
pass
|
||||
|
||||
def generate_cross_sections():
|
||||
pass
|
||||
|
||||
def generate_3d_height_map(pa_result: PaResult):
|
||||
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})
|
||||
@ -38,11 +27,24 @@ def generate_3d_height_map(pa_result: PaResult):
|
||||
y = np.arange(len(pa_result.height_data))
|
||||
x = np.arange(len(pa_result.height_data[0]))
|
||||
(x ,y) = np.meshgrid(x,y)
|
||||
ax.plot_surface(x, y, pa_result.height_data, cmap="RdBu")
|
||||
ax.set_zlim3d(60, 100)
|
||||
ax.plot_surface(x, y, pa_result.height_data, cmap="plasma")
|
||||
ax.set_zlim3d(10, 50)
|
||||
|
||||
ax.set_ylabel("X Value (Frame)")
|
||||
ax.set_xlabel("Y Value (Pixel)")
|
||||
ax.set_zlabel("Height (mm)")
|
||||
|
||||
ax.set_title("3D Height Map", fontsize=10, y=1)
|
||||
|
||||
fig.tight_layout()
|
||||
|
||||
return fig
|
||||
|
||||
def generate_cross_section_video():
|
||||
pass
|
||||
|
||||
def generate_cross_sections():
|
||||
pass
|
||||
|
||||
def graph_frame(pixel_values: np.ndarray, output_file: str):
|
||||
# fig.
|
||||
@ -59,26 +61,6 @@ def graph_frame(pixel_values: np.ndarray, output_file: str):
|
||||
# plt.close()
|
||||
return
|
||||
|
||||
def graph_height_map(z_data: np.ndarray, output_file: str):
|
||||
fig, ax = plt.subplots()
|
||||
|
||||
# points = []
|
||||
# for y, line_data in enumerate(frames):
|
||||
# for x, z in enumerate(line_data):
|
||||
# points.append(
|
||||
# (x, y, z)
|
||||
# )
|
||||
# x, y, z = zip(*points)
|
||||
# x, y, z = np.array(x), np.array(y), np.array(z)
|
||||
y = np.arange(len(z_data))
|
||||
x = np.arange(len(z_data[0]))
|
||||
(x ,y) = np.meshgrid(x,y)
|
||||
|
||||
# ax.plot_surface(x, y, z_data,cmap=cm.coolwarm,linewidth=0, antialiased=False)
|
||||
ax.pcolormesh(x, y, z_data, cmap='RdBu')
|
||||
# ax.scatter(x, y, z)
|
||||
fig.savefig(output_file)
|
||||
|
||||
|
||||
def generate_graphs_for_pa_results(pa_data: PaResult):
|
||||
graph_frame(laser_x_values, f"graphs/{Path(video_file).stem}-{frame_index}.png")
|
||||
|
Loading…
Reference in New Issue
Block a user