|
|
@ -1,6 +1,7 @@
|
|
|
|
"""! @file main.py
|
|
|
|
"""Main file of the project, contains filtering and stl generation functions
|
|
|
|
@brief Main file for the application
|
|
|
|
|
|
|
|
@author xlanro00
|
|
|
|
.. moduleauthor:: xlanro00
|
|
|
|
|
|
|
|
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
# Import basic libraries
|
|
|
|
# Import basic libraries
|
|
|
@ -121,6 +122,8 @@ class fingerprint_app:
|
|
|
|
self.args = parser.parse_args()
|
|
|
|
self.args = parser.parse_args()
|
|
|
|
|
|
|
|
|
|
|
|
def parse_stl(self):
|
|
|
|
def parse_stl(self):
|
|
|
|
|
|
|
|
'''Parse arguments for stl generation.
|
|
|
|
|
|
|
|
'''
|
|
|
|
# Get stl filename
|
|
|
|
# Get stl filename
|
|
|
|
self.stl_path = self.output_file.rsplit('/', 1)[0] + '/'
|
|
|
|
self.stl_path = self.output_file.rsplit('/', 1)[0] + '/'
|
|
|
|
self.mode = self.args.stl[0]
|
|
|
|
self.mode = self.args.stl[0]
|
|
|
@ -221,7 +224,8 @@ class fingerprint_app:
|
|
|
|
return fig, ax
|
|
|
|
return fig, ax
|
|
|
|
|
|
|
|
|
|
|
|
def mirror_image(self):
|
|
|
|
def mirror_image(self):
|
|
|
|
'''Mirror image using opencv, should be used if we want a positive model.
|
|
|
|
'''Mirror image using opencv.
|
|
|
|
|
|
|
|
Should be used to cancel implicit mirroring.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
log.print_message("Mirroring image")
|
|
|
|
log.print_message("Mirroring image")
|
|
|
@ -251,6 +255,9 @@ class fingerprint_app:
|
|
|
|
|
|
|
|
|
|
|
|
def save_image(self, fig, ax):
|
|
|
|
def save_image(self, fig, ax):
|
|
|
|
'''Save processed image to the output file.
|
|
|
|
'''Save processed image to the output file.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param fig: figure used to render image.
|
|
|
|
|
|
|
|
:param ax: Ax used to render image.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
log.print_message("Saving image to", self.output_file)
|
|
|
|
log.print_message("Saving image to", self.output_file)
|
|
|
@ -262,7 +269,7 @@ class fingerprint_app:
|
|
|
|
# ------------------------- STL GENERATION -------------------------#
|
|
|
|
# ------------------------- STL GENERATION -------------------------#
|
|
|
|
|
|
|
|
|
|
|
|
def run_stl(self):
|
|
|
|
def run_stl(self):
|
|
|
|
'''Make heightmap, create mesh and save as stl file.
|
|
|
|
'''Choose correct generation code based on mode.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
self.prepare_heightmap()
|
|
|
|
self.prepare_heightmap()
|
|
|
@ -286,8 +293,8 @@ class fingerprint_app:
|
|
|
|
|
|
|
|
|
|
|
|
def prepare_heightmap(self):
|
|
|
|
def prepare_heightmap(self):
|
|
|
|
'''Scale image values to get values from 0 to 255.
|
|
|
|
'''Scale image values to get values from 0 to 255.
|
|
|
|
Then compute base and papilar lines height.
|
|
|
|
|
|
|
|
Check validity of dimension parameters.
|
|
|
|
Check validity of dimension parameters.
|
|
|
|
|
|
|
|
Then compute base and papilar lines height.
|
|
|
|
Prepare meshgrid, array which later serves to store point coordinates.
|
|
|
|
Prepare meshgrid, array which later serves to store point coordinates.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
@ -344,7 +351,7 @@ class fingerprint_app:
|
|
|
|
|
|
|
|
|
|
|
|
def get_ID(self):
|
|
|
|
def get_ID(self):
|
|
|
|
'''Get a unique ID for the model, which is used in filename and on the model backside.
|
|
|
|
'''Get a unique ID for the model, which is used in filename and on the model backside.
|
|
|
|
Also create parameter string for stl header, which is used to create ID using hash function SHA512.
|
|
|
|
Also create parameter string for stl header, which is used to create ID using hash function MD5.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
# these are the same for all types of models
|
|
|
|
# these are the same for all types of models
|
|
|
@ -412,7 +419,10 @@ class fingerprint_app:
|
|
|
|
self.param_string.encode('utf-8')).hexdigest())[:10]
|
|
|
|
self.param_string.encode('utf-8')).hexdigest())[:10]
|
|
|
|
|
|
|
|
|
|
|
|
def append_faces(self, faces, c):
|
|
|
|
def append_faces(self, faces, c):
|
|
|
|
''' Function to add faces to the list of faces.
|
|
|
|
'''Add faces to the list of faces.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param faces: Array with faces.
|
|
|
|
|
|
|
|
:param c: Indices of currently added faces.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
faces.append([c, c + 1, c + 2])
|
|
|
|
faces.append([c, c + 1, c + 2])
|
|
|
@ -422,6 +432,9 @@ class fingerprint_app:
|
|
|
|
def engrave_text(self, bottom_vert_arr, top_vert_arr):
|
|
|
|
def engrave_text(self, bottom_vert_arr, top_vert_arr):
|
|
|
|
'''Engrave text on the back of the model.
|
|
|
|
'''Engrave text on the back of the model.
|
|
|
|
Create an empty image, fill it with color and draw text on it.
|
|
|
|
Create an empty image, fill it with color and draw text on it.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param bottom_vert_arr: Bottom vertex array.
|
|
|
|
|
|
|
|
:param top_vert_arr: Top vertex array
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
fig, ax = self.get_empty_figure()
|
|
|
|
fig, ax = self.get_empty_figure()
|
|
|
@ -448,14 +461,11 @@ class fingerprint_app:
|
|
|
|
fig.canvas.draw()
|
|
|
|
fig.canvas.draw()
|
|
|
|
data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
|
|
|
|
data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)
|
|
|
|
data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))
|
|
|
|
data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))
|
|
|
|
|
|
|
|
plt.close()
|
|
|
|
|
|
|
|
|
|
|
|
# scale inscription layer to suitable height
|
|
|
|
# scale inscription layer to suitable height
|
|
|
|
data = (data/255)/10
|
|
|
|
data = (data/255)/10
|
|
|
|
|
|
|
|
|
|
|
|
plt.close()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO: this is very badly written, fix it
|
|
|
|
|
|
|
|
# TODO: this sometimes generates invalid mesh, fix it
|
|
|
|
|
|
|
|
# add the bottom array
|
|
|
|
# add the bottom array
|
|
|
|
OFFSET = 0.01
|
|
|
|
OFFSET = 0.01
|
|
|
|
|
|
|
|
|
|
|
@ -464,6 +474,8 @@ class fingerprint_app:
|
|
|
|
for j in range(self.width):
|
|
|
|
for j in range(self.width):
|
|
|
|
bottom_vert_arr[i][j][2] = data[i][j][0]
|
|
|
|
bottom_vert_arr[i][j][2] = data[i][j][0]
|
|
|
|
elif self.mode == "c":
|
|
|
|
elif self.mode == "c":
|
|
|
|
|
|
|
|
# TODO: this is very badly written, fix it, why is teh offset needed at all?
|
|
|
|
|
|
|
|
# TODO: this sometimes generates invalid mesh, fix it
|
|
|
|
for j in range(self.width):
|
|
|
|
for j in range(self.width):
|
|
|
|
bottom_vert_arr[i][j][2] += data[i][j][0]
|
|
|
|
bottom_vert_arr[i][j][2] += data[i][j][0]
|
|
|
|
if (bottom_vert_arr[i][j][2] < (top_vert_arr[i][0][2])-OFFSET):
|
|
|
|
if (bottom_vert_arr[i][j][2] < (top_vert_arr[i][0][2])-OFFSET):
|
|
|
@ -474,7 +486,10 @@ class fingerprint_app:
|
|
|
|
return bottom_vert_arr
|
|
|
|
return bottom_vert_arr
|
|
|
|
|
|
|
|
|
|
|
|
def create_stl_mesh(self, faces, vertices):
|
|
|
|
def create_stl_mesh(self, faces, vertices):
|
|
|
|
'''Create mesh from faces and vertices.
|
|
|
|
'''Create mesh from faces and vertices arrays.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
:param faces: Vector of face indices
|
|
|
|
|
|
|
|
:param vertices: Vector of vertices
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
# Convert lists to numpy arrays
|
|
|
|
# Convert lists to numpy arrays
|
|
|
@ -500,8 +515,10 @@ class fingerprint_app:
|
|
|
|
|
|
|
|
|
|
|
|
def create_faces(self, top_vert_arr, bottom_vert_arr):
|
|
|
|
def create_faces(self, top_vert_arr, bottom_vert_arr):
|
|
|
|
'''Create faces for the model.
|
|
|
|
'''Create faces for the model.
|
|
|
|
|
|
|
|
Iterate over all vertices, append to vector and create faces from indices.
|
|
|
|
|
|
|
|
|
|
|
|
Iterate over all vertices, append to vector and create faces from indices
|
|
|
|
:param bottom_vert_arr: Bottom vertex array.
|
|
|
|
|
|
|
|
:param top_vert_arr: Top vertex array
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
count = 0
|
|
|
|
count = 0
|
|
|
@ -563,9 +580,7 @@ class fingerprint_app:
|
|
|
|
return faces, vertices
|
|
|
|
return faces, vertices
|
|
|
|
|
|
|
|
|
|
|
|
def make_stl_planar(self):
|
|
|
|
def make_stl_planar(self):
|
|
|
|
'''
|
|
|
|
'''Create vertices from meshgrid, add z coordinates from processed image heightmap.
|
|
|
|
Create vertices from meshgrid, add depth values from image.
|
|
|
|
|
|
|
|
Create faces from vertices. Add vectors and faces to the model.
|
|
|
|
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
# Add the image matrix to the 2D meshgrid and create 1D array of 3D points
|
|
|
|
# Add the image matrix to the 2D meshgrid and create 1D array of 3D points
|
|
|
@ -589,10 +604,8 @@ class fingerprint_app:
|
|
|
|
self.create_stl_mesh(faces, vertices)
|
|
|
|
self.create_stl_mesh(faces, vertices)
|
|
|
|
|
|
|
|
|
|
|
|
def make_stl_curved(self):
|
|
|
|
def make_stl_curved(self):
|
|
|
|
'''Compute curved surface.
|
|
|
|
'''Compute curved surface offset.
|
|
|
|
Create mesh from meshgrid.
|
|
|
|
Create vertices from meshgrid, add z coordinates from processed image heightmap.
|
|
|
|
Create vertices from meshgrid, add depth values from image.
|
|
|
|
|
|
|
|
Create faces from vertices. Add vectors and faces to the model.
|
|
|
|
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
# Calculate the curved surface values
|
|
|
|
# Calculate the curved surface values
|
|
|
|