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.params = {}
self.filters = [] self.filters = []
# Parse configuration from json file # Parse configuration from json file
if self.args.config: if self.args.config:
self.config_file = self.args.config[0] self.config_file = self.args.config[0]
@ -57,6 +58,7 @@ class apply_filters:
self.input_file = self.args.input_file self.input_file = self.args.input_file
self.output_file = self.args.output_file self.output_file = self.args.output_file
self.dpi = self.args.dpi self.dpi = self.args.dpi
self.mirror = True if self.args.mirror else False
self.run() self.run()
def run(self): def run(self):
@ -67,22 +69,22 @@ class apply_filters:
self.width = self.img.shape[1] self.width = self.img.shape[1]
self.height = self.img.shape[0] self.height = self.img.shape[0]
self.print_size(self.img.shape) self.print_size(self.img.shape)
print(self.dpi)
fig = plt.figure(figsize=(self.width, self.height), fig = plt.figure(figsize=(self.width/100, self.height/100),
frameon=False, dpi=self.dpi / 100) # dpi is in cm frameon=False, dpi=self.dpi)
ax = plt.Axes(fig, [0., 0., 1., 1.]) ax = plt.Axes(fig, [0., 0., 1., 1.])
ax.set_axis_off() ax.set_axis_off()
fig.add_axes(ax) fig.add_axes(ax)
if self.args.mirror: if self.mirror is True:
self.mirror_image() self.mirror_image()
# Apply all filters and save image # Apply all filters and save image
self.apply_filter() self.apply_filter()
self.save_image(fig, ax) self.save_image(fig, ax)
plt.close() plt.close()
if self.args.stl: if self.args.stl_file:
self.make_lithophane() self.make_lithophane()
def parse_params(self, params): def parse_params(self, params):
@ -125,7 +127,8 @@ class apply_filters:
parser = ap.ArgumentParser(prog='main.py', parser = ap.ArgumentParser(prog='main.py',
description='Program for processing a 2D image into 3D fingerprint.', 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 # positional arguments
parser.add_argument("input_file", type=str, parser.add_argument("input_file", type=str,
@ -138,9 +141,8 @@ class apply_filters:
parser.add_argument('-m', "--mirror", help="mirror input image", parser.add_argument('-m', "--mirror", help="mirror input image",
type=bool, action=ap.BooleanOptionalAction) type=bool, action=ap.BooleanOptionalAction)
# another boolean switch argument # another boolean switch argument, this time with value, name of the new file
parser.add_argument('-s', '--stl', help="make stl model from processed image", parser.add_argument('-s', '--stl_file', type=str, nargs='?', help="make stl model from processed image", required=False)
type=bool, action=ap.BooleanOptionalAction)
# file with configuration containing presets, new preset name # file with configuration containing presets, new preset name
# pair argument - give both or none # pair argument - give both or none
@ -160,12 +162,6 @@ class apply_filters:
print("Applying " + filter_name + " filter ", end='') print("Applying " + filter_name + " filter ", end='')
return getattr(flt, filter_name) 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): def mirror_image(self):
''' Mirror image when mirroring is needed, ''' Mirror image when mirroring is needed,
should be used only if we want a positive model should be used only if we want a positive model
@ -178,7 +174,7 @@ class apply_filters:
def apply_filter(self): def apply_filter(self):
''' Apply filters to image. ''' 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: if len(self.filters) == 0:
@ -201,9 +197,9 @@ class apply_filters:
Colormap set to grayscale to avoid color mismatch. 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") ax.imshow(self.img, cmap="gray")
fig.savefig(fname=self.output_file) fig.savefig(fname=self.output_file, dpi='figure')
def make_lithophane(self): def make_lithophane(self):
'''After processing image, make a lithophane from it. '''After processing image, make a lithophane from it.
@ -214,28 +210,33 @@ class apply_filters:
print("Converting to stl format", file=sys.stderr) print("Converting to stl format", file=sys.stderr)
self.make_mesh() self.make_mesh()
plt.show() plt.show()
self.save_model() print(f"Saving lithophane to ", self.args.stl_file, file=sys.stderr)
self.save_mesh()
def make_meshgrid(self): def make_meshgrid(self):
''' Create numpy meshgrid. ''' Create numpy meshgrid.
Modify image values to get more usable depth values. Modify image values to get more usable depth values.
Add zero padding to image to make sides of the plate. 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 # Modify image to make it more suitable depth
# values1 = (1 + (1 - self.img/255)/6) * 255/10 # this works rescaled = (1 + (1 - self.img/255)/6) * 255 / 10 # for positive forms ?
# values2 = (1 - (1 - self.img/255)/6) * 255/10 # if self.mirror is True:
# TODO: i dont know how to make white surrounding be extruded rescaled = (2 - (1 - self.img/255)/6) * 255 / 10 # for negative forms
values1better = 28.05 - 0.01*self.img # TODO: i dont know how to make white surrounding be extruded
#values2better = 22.95 - 0.01*self.img
# (np.around(values2[::300],3))
# Add zero padding to image # Add zero padding to image
# TODO this better be done in the next function to keep dimensions intact # TODO this better be done in the next function to keep dimensions intact
self.height = self.img.shape[0] + 2 self.height = self.img.shape[0] + 2
self.width = self.img.shape[1] + 2 self.width = self.img.shape[1] + 2
self.img = np.zeros([self.height, self.width]) 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 # Create meshgrid for 3D model
verticesX = np.around(np.linspace(0, self.width / 10, self.width), 3) verticesX = np.around(np.linspace(0, self.width / 10, self.width), 3)
@ -245,7 +246,19 @@ class apply_filters:
def make_mesh(self): def make_mesh(self):
''' Create mesh from image. ''' Create mesh from image.
Create vertices from meshgrid, add depth values 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 # Convert meshgrid and image matrix to array of 3D points
@ -292,17 +305,17 @@ class apply_filters:
vertices = np.array(vertices) vertices = np.array(vertices)
# Create the mesh # 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 i, face in enumerate(faces):
for j in range(3): 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): def save_mesh(self):
''' Save final model to stl file. ''' Save final mesh to stl file.
''' '''
print("Saving lithophane to stl file", file=sys.stderr) self.stl_mesh.save(self.args.stl_file)
self.model.save('res/test.stl')
image = apply_filters() image = apply_filters()

Loading…
Cancel
Save