Added basic operations - binarization, scaling of image values and margin around image.
This commit is contained in:
@ -8,6 +8,7 @@ import cv2 as cv
|
||||
from skimage import filters as skiflt
|
||||
from skimage import restoration as skirest
|
||||
#from scipy import signal as sig
|
||||
from PIL import Image, ImageFilter
|
||||
|
||||
|
||||
# Parent class for all the filters
|
||||
@ -110,6 +111,53 @@ class bilateral(filter):
|
||||
self.img = cv.bilateralFilter(self.img, d, sigmaColor, sigmaSpace)
|
||||
|
||||
|
||||
class scale_values(filter):
|
||||
''' Scale values of the image to use the entire range of data type.
|
||||
This should remove the line height issues.
|
||||
'''
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
# do this once for inverted image and once for original
|
||||
# this is done to get whiter whites and blacker blacks
|
||||
# which helps to get exact line height on stl model
|
||||
tmp = cv.bitwise_not(self.img.astype(np.uint8))
|
||||
coef = 255 / np.max(tmp)
|
||||
tmp = tmp * coef
|
||||
self.img = cv.bitwise_not(tmp.astype(np.uint8))
|
||||
coef = 255 / np.max(tmp)
|
||||
tmp = tmp * coef
|
||||
|
||||
|
||||
class binarize(filter):
|
||||
def init(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
threshold = int(params["threshold"]) if params["threshold"] else 128
|
||||
maxval = int(params["maxval"]) if params["maxval"] else 255
|
||||
type = int(params["type"]) if params["type"] else 0
|
||||
|
||||
#print("with params: threshold: " + str(threshold) +
|
||||
# " maxval: " + str(maxval) + " type: " + str(type))
|
||||
self.img = cv.threshold(self.img, threshold, maxval, type)[1]
|
||||
|
||||
|
||||
class add_margin(filter):
|
||||
def init(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
margin = int(params["margin"]) if params["margin"] else 10
|
||||
color = int(params["color"]) if params["color"] else 255
|
||||
self.fig.set_size_inches(
|
||||
((self.width + 2 * margin) / self.dpi, (self.height + 2 * margin) / self.dpi))
|
||||
self.img = cv.copyMakeBorder(
|
||||
self.img, margin, margin, margin, margin, cv.BORDER_CONSTANT, value=color)
|
||||
self.height, self.width = self.img.shape
|
||||
|
||||
|
||||
class denoise(filter):
|
||||
# TODO possibly not necessary
|
||||
def __init__(self, img):
|
||||
@ -263,6 +311,7 @@ class morph(filter):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
# TODO: this is probably better with binarized image
|
||||
kernel = np.matrix(params["kernel"]) if params["kernel"] else np.ones(
|
||||
(3, 3), np.uint8)
|
||||
iterations = int(params["iterations"]) if params["iterations"] else 1
|
||||
|
17
src/main.py
17
src/main.py
@ -7,7 +7,6 @@
|
||||
import argparse as ap
|
||||
import sys
|
||||
import json
|
||||
import math
|
||||
from os.path import exists
|
||||
|
||||
# Libraries for image processing
|
||||
@ -159,7 +158,8 @@ class app:
|
||||
"ksize", "kernel", "sigmaX", "sigmaY",
|
||||
"sigmaColor", "sigmaSpace", "d", "anchor", "iterations",
|
||||
"op", "strength", "amount", "radius", "weight", "channelAxis",
|
||||
"theta", "sigma", "lambda", "gamma", "psi", "shape", "percent", "threshold"}
|
||||
"theta", "sigma", "lambda", "gamma", "psi", "shape", "percent",
|
||||
"threshold", "maxval", "type", "margin", "color"}
|
||||
|
||||
for key in possible_params:
|
||||
if params.get(key) is None:
|
||||
@ -208,17 +208,14 @@ class app:
|
||||
|
||||
# gets empty figure and ax with dimensions of input image
|
||||
self.height, self.width = self.img.shape
|
||||
fig, ax = self.get_empty_figure()
|
||||
|
||||
# print("Height: " + str(self.height) + " px and width: "
|
||||
# + str(self.width) + " px", file=sys.stderr)
|
||||
self.fig, ax = self.get_empty_figure()
|
||||
|
||||
if self.mirror is True:
|
||||
self.mirror_image()
|
||||
|
||||
# Apply all filters and save image
|
||||
self.apply_filters()
|
||||
self.save_image(fig, ax)
|
||||
self.save_image(self.fig, ax)
|
||||
plt.close()
|
||||
|
||||
def get_empty_figure(self):
|
||||
@ -260,7 +257,7 @@ class app:
|
||||
|
||||
# Colormap must be set to grayscale to avoid color mismatch.
|
||||
ax.imshow(self.img, cmap="gray")
|
||||
fig.savefig(fname=self.output_file, dpi=self.dpi)
|
||||
fig.savefig(fname=self.output_file)
|
||||
|
||||
#------------------------- STL GENERATION -------------------------#
|
||||
|
||||
@ -336,8 +333,7 @@ class app:
|
||||
'''
|
||||
|
||||
# TODO: somehow compress this to fit it onto the model
|
||||
self.id = self.input_file.split(
|
||||
"/")[-1].split(".")[0] + "_" + self.preset_name
|
||||
self.id = self.input_file.split("/")[-1].split(".")[0] + "_" + self.preset_name
|
||||
# TODO: hash is not unique, find a better way
|
||||
# TODO: stl file format has 80 chars for header, use that space to store info
|
||||
# python generates a random value for security reasons, it has to be turned off
|
||||
@ -615,6 +611,7 @@ class app:
|
||||
def save_stl(self):
|
||||
'''Save final mesh to stl file.
|
||||
'''
|
||||
|
||||
# TODO: add a hash function to create ID specific to
|
||||
# input image + preset from config. file or from console + input params
|
||||
# TODO: add the full parameters and filters to a file inside output dir.
|
||||
|
Reference in New Issue
Block a user