Skip to content

Commit

Permalink
Working on formatting report data
Browse files Browse the repository at this point in the history
  • Loading branch information
furrysalamander committed Apr 18, 2023
1 parent 9f60da8 commit 24116d7
Show file tree
Hide file tree
Showing 10 changed files with 163 additions and 91 deletions.
9 changes: 7 additions & 2 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
]
}
}
}
4 changes: 4 additions & 0 deletions analysis.py
Original file line number Diff line number Diff line change
Expand Up @@ -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])

Expand Down
8 changes: 4 additions & 4 deletions constants.py
Original file line number Diff line number Diff line change
@@ -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
5 changes: 2 additions & 3 deletions generate_bulk_scans.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
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,
Expand Down Expand Up @@ -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)
Expand Down
136 changes: 98 additions & 38 deletions generate_report_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,55 +3,115 @@
from pprint import pprint
import numpy as np
from pa_result import PaResult
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

with open("testing_adjustments.pkl", "rb") as f:
data: list[PaResult] = pickle.load(f)

pa_values = list([x[0] for x in data[:10]])
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)

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))
# 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)

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)
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')

# Calculate the point density
# xy = np.vstack([x,y])
# z = gaussian_kde(xy)(xy)

# 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))
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])
counter = Counter(winning_results)

winning_results = []
# fig, ax = plt.subplots()
ax.set_ylabel("Winning Frequency")
ax.set_xlabel("PA Value")
ax.bar(counter.keys(), counter.values(), width=0.06/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])
# Calculate the standard deviation of the winning results
std_dev = statistics.stdev(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)
# 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

from visualization import generate_color_map, generate_3d_height_map
generate_color_map(data[3][1])
generate_3d_height_map(data[3][1])

plt.show()
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 changes: 1 addition & 1 deletion main.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
22 changes: 22 additions & 0 deletions pa_statistics.py
Original file line number Diff line number Diff line change
@@ -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()}
"""
2 changes: 1 addition & 1 deletion processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
4 changes: 2 additions & 2 deletions record.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
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()
Expand All @@ -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
Expand Down
62 changes: 22 additions & 40 deletions visualization.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,43 +6,45 @@

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)
return fig
ax.pcolormesh(x, y, np.transpose(pa_result.height_data), cmap='plasma')
ax.set_xlabel("X Value (Frame)")
ax.set_ylabel("Y Value (Pixel)")

def generate_cross_section_video():
pass
ax.set_title("Height Map", fontsize=10)
return fig

def generate_cross_sections():
pass

def generate_3d_height_map(pa_result: PaResult):
fig, ax = plt.subplots(subplot_kw={"projection": "3d"})

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.
Expand All @@ -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")
Expand Down

0 comments on commit 24116d7

Please sign in to comment.