Added stl filename, fixed type conversion for image.

master
Rostislav Lán 2 years ago
parent 48349d9958
commit 68b9deaae3

@ -27,6 +27,7 @@ class apply_filters:
self.params = {}
self.filters = []
# Parse configuration from json file
if self.args.config:
self.config_file = self.args.config[0]
@ -57,6 +58,7 @@ class apply_filters:
self.input_file = self.args.input_file
self.output_file = self.args.output_file
self.dpi = self.args.dpi
self.mirror = True if self.args.mirror else False
self.run()
def run(self):
@ -67,22 +69,22 @@ class apply_filters:
self.width = self.img.shape[1]
self.height = self.img.shape[0]
self.print_size(self.img.shape)
fig = plt.figure(figsize=(self.width, self.height),
frameon=False, dpi=self.dpi / 100) # dpi is in cm
print(self.dpi)
fig = plt.figure(figsize=(self.width/100, self.height/100),
frameon=False, dpi=self.dpi)
ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off()
fig.add_axes(ax)
if self.args.mirror:
if self.mirror is True:
self.mirror_image()
# Apply all filters and save image
self.apply_filter()
self.save_image(fig, ax)
plt.close()
if self.args.stl:
if self.args.stl_file:
self.make_lithophane()
def parse_params(self, params):
@ -125,7 +127,8 @@ class apply_filters:
parser = ap.ArgumentParser(prog='main.py',
description='Program for processing a 2D image into 3D fingerprint.',
usage='%(prog)s [-h] [-m | --mirror | --no-mirror] input_file output_file dpi ([-c config_file preset | --config config_file preset] | [filters ...])')
usage='%(prog)s [-h] [-m | --mirror | --no-mirror] input_file output_file dpi \
([-c config_file preset | --config config_file preset] | [filters ...]) [-s stl_file | --stl_file stl_file]')
# positional arguments
parser.add_argument("input_file", type=str,
@ -138,9 +141,8 @@ class apply_filters:
parser.add_argument('-m', "--mirror", help="mirror input image",
type=bool, action=ap.BooleanOptionalAction)
# another boolean switch argument
parser.add_argument('-s', '--stl', help="make stl model from processed image",
type=bool, action=ap.BooleanOptionalAction)
# another boolean switch argument, this time with value, name of the new file
parser.add_argument('-s', '--stl_file', type=str, nargs='?', help="make stl model from processed image", required=False)
# file with configuration containing presets, new preset name
# pair argument - give both or none
@ -160,12 +162,6 @@ class apply_filters:
print("Applying " + filter_name + " filter ", end='')
return getattr(flt, filter_name)
def resize_image(self):
print("Resize image", file=sys.stderr)
self.img = self.img.resize(
(np.array(self.width, self.height)).astype(int))
def mirror_image(self):
''' Mirror image when mirroring is needed,
should be used only if we want a positive model
@ -178,7 +174,7 @@ class apply_filters:
def apply_filter(self):
''' Apply filters to image.
Applies the filters one by one, if no filters were given, just save original image output.
Apply the filters one by one, if none were given, just save original image output.
'''
if len(self.filters) == 0:
@ -188,9 +184,9 @@ class apply_filters:
# Apply all filters
for i, filter_name in enumerate(self.filters):
filter = self.filter_factory(filter_name)
# print(self.img.dtype)
#print(self.img.dtype)
filter.apply(self, self.params[i+1])
# print(self.img.dtype)
#print(self.img.dtype)
def print_size(self, size):
print("Height: " + str(size[0]), file=sys.stderr)
@ -201,9 +197,9 @@ class apply_filters:
Colormap set to grayscale to avoid color mismatch.
'''
print("Saving image", file=sys.stderr)
print("Saving image to ", self.output_file, file=sys.stderr)
ax.imshow(self.img, cmap="gray")
fig.savefig(fname=self.output_file)
fig.savefig(fname=self.output_file, dpi='figure')
def make_lithophane(self):
'''After processing image, make a lithophane from it.
@ -214,28 +210,33 @@ class apply_filters:
print("Converting to stl format", file=sys.stderr)
self.make_mesh()
plt.show()
self.save_model()
print(f"Saving lithophane to ", self.args.stl_file, file=sys.stderr)
self.save_mesh()
def make_meshgrid(self):
''' Create numpy meshgrid.
Modify image values to get more usable depth values.
Add zero padding to image to make sides of the plate.
'''
if self.img.dtype == np.float32 or self.img.dtype == np.float64:
print("Converting to uint8", file=sys.stderr)
self.img = self.img * 255
self.img = self.img.astype(np.uint8)
# Modify image to make it more suitable depth
# values1 = (1 + (1 - self.img/255)/6) * 255/10 # this works
# values2 = (1 - (1 - self.img/255)/6) * 255/10 #
# TODO: i dont know how to make white surrounding be extruded
rescaled = (1 + (1 - self.img/255)/6) * 255 / 10 # for positive forms ?
if self.mirror is True:
rescaled = (2 - (1 - self.img/255)/6) * 255 / 10 # for negative forms
values1better = 28.05 - 0.01*self.img
#values2better = 22.95 - 0.01*self.img
# (np.around(values2[::300],3))
# TODO: i dont know how to make white surrounding be extruded
# Add zero padding to image
# TODO this better be done in the next function to keep dimensions intact
self.height = self.img.shape[0] + 2
self.width = self.img.shape[1] + 2
self.img = np.zeros([self.height, self.width])
self.img[1:-1:1, 1:-1:1] = values1better
self.img[1:-1:1, 1:-1:1] = rescaled
# Create meshgrid for 3D model
verticesX = np.around(np.linspace(0, self.width / 10, self.width), 3)
@ -245,7 +246,19 @@ class apply_filters:
def make_mesh(self):
''' Create mesh from image.
Create vertices from meshgrid, add depth values from image.
Create faces from vertices.
Create faces from vertices. Add veectors to the model.
From wikipedia.org/wiki/STL_(file_format):
ascii stl format consists of repeating struictures:
facet normal ni nj nk # normal vector
outer loop
vertex v1x v1y v1z # vertex 1
vertex v2x v2y v2z # vertex 2
vertex v3x v3y v3z # vertex 3
endloop
endfacet
'''
# Convert meshgrid and image matrix to array of 3D points
@ -292,17 +305,17 @@ class apply_filters:
vertices = np.array(vertices)
# Create the mesh
self.model = mesh.Mesh(np.zeros(len(faces), dtype=mesh.Mesh.dtype))
self.stl_mesh = mesh.Mesh(np.zeros(len(faces), dtype=mesh.Mesh.dtype))
for i, face in enumerate(faces):
for j in range(3):
self.model.vectors[i][j] = vertices[face[j], :]
self.stl_mesh.vectors[i][j] = vertices[face[j], :]
self.stl_mesh.vectors[i][j] /= 2.54 # convert to inches
def save_model(self):
''' Save final model to stl file.
def save_mesh(self):
''' Save final mesh to stl file.
'''
print("Saving lithophane to stl file", file=sys.stderr)
self.model.save('res/test.stl')
self.stl_mesh.save(self.args.stl_file)
image = apply_filters()

Loading…
Cancel
Save