Removed unused filters and their parameters from config parser.
This commit is contained in:
@ -77,6 +77,9 @@ def parse_conf(preset_name, filters, params, config_file):
|
||||
Store filters and their parameters.
|
||||
'''
|
||||
|
||||
if not exists(config_file):
|
||||
log.error_exit("Config file not found")
|
||||
|
||||
config = json.load(open(config_file))
|
||||
|
||||
# Find preset in config file
|
||||
@ -96,7 +99,7 @@ def parse_conf(preset_name, filters, params, config_file):
|
||||
log.print_message("Loaded preset:", preset_name,
|
||||
"from file:", config_file)
|
||||
else:
|
||||
log.print_message("Warning: Preset not found in config file")
|
||||
log.error_exit("Preset not found in config file")
|
||||
|
||||
|
||||
def parse_params(params):
|
||||
@ -107,12 +110,13 @@ def parse_params(params):
|
||||
|
||||
# TODO: possibly too bloated, sending all possible params to each filter
|
||||
# TODO: remove unnecessary params
|
||||
possible_params = {"h", "searchWindowSize", "templateWindowSize",
|
||||
"ksize", "kernel", "angle",
|
||||
"sigmaColor", "sigmaSpace", "diameter", "anchor", "iterations",
|
||||
"op", "strength", "amount", "radius", "weight", "channelAxis",
|
||||
"theta", "sigma", "lambd", "gamma", "psi", "shape", "percent",
|
||||
"threshold", "maxval", "type", "margin", "color", "truncate", "patch_size", "patch_distance"}
|
||||
possible_params = {"sigma", "ksize", "kernel",
|
||||
"diameter", "sigmaColor", "sigmaSpace",
|
||||
"patch_size", "patch_distance", "weight",
|
||||
"amount", "radius", "percent",
|
||||
"threshold",
|
||||
"margin", "color"
|
||||
}
|
||||
|
||||
for key in possible_params:
|
||||
if params.get(key) is None:
|
||||
|
243
src/filters.py
243
src/filters.py
@ -8,13 +8,11 @@ import cv2 as cv
|
||||
from skimage import filters as skiflt
|
||||
from skimage import restoration as skirest
|
||||
from skimage import morphology as skimorph
|
||||
from scipy import ndimage
|
||||
from PIL import Image, ImageFilter
|
||||
import bm3d
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
class filter:
|
||||
class img_filter:
|
||||
''' Parent class for all the filters.
|
||||
'''
|
||||
|
||||
@ -28,7 +26,7 @@ class filter:
|
||||
# --------------------- DENOISING FILTERS ---------------------#
|
||||
|
||||
|
||||
class gaussian(filter):
|
||||
class gaussian(img_filter):
|
||||
'''Gaussian blur filter from scikit-image.
|
||||
Easier to use than opencv version.
|
||||
'''
|
||||
@ -45,7 +43,7 @@ class gaussian(filter):
|
||||
self.img, sigma=sigma, preserve_range=True)
|
||||
|
||||
|
||||
class median(filter):
|
||||
class median(img_filter):
|
||||
''' Median blur filter from scikit-image.
|
||||
Using this over opencv version as that one is limited to 5x5 kernel.
|
||||
'''
|
||||
@ -61,7 +59,7 @@ class median(filter):
|
||||
self.img = skiflt.median(self.img, footprint=skimorph.disk(ksize))
|
||||
|
||||
|
||||
class bilateral(filter):
|
||||
class bilateral(img_filter):
|
||||
''' Bilateral filter from opencv.
|
||||
'''
|
||||
|
||||
@ -87,7 +85,7 @@ class bilateral(filter):
|
||||
self.img, diameter, sigmaColor, sigmaSpace)
|
||||
|
||||
|
||||
class bilateral_scikit(filter):
|
||||
class bilateral_scikit(img_filter):
|
||||
''' Skimage denoise_bilateral filter.
|
||||
Averages pixels based on their distance and color similarity.
|
||||
Preserves edges while removing unwanted noise.
|
||||
@ -116,7 +114,7 @@ class bilateral_scikit(filter):
|
||||
self.img = np.uint8(self.img * 255.0) # converting back to uint8
|
||||
|
||||
|
||||
class nlmeans(filter):
|
||||
class nlmeans(img_filter):
|
||||
''' Non-local means filter from scikit-image.
|
||||
'''
|
||||
|
||||
@ -143,7 +141,7 @@ class nlmeans(filter):
|
||||
self.img = np.uint8(self.img * 255.0) # converting back to uint8
|
||||
|
||||
|
||||
class total_variation(filter):
|
||||
class total_variation(img_filter):
|
||||
''' Scikit image denoise_tv_chambolle filter from scikit-image.
|
||||
|
||||
Performs total variation denoising technique based on original Chambolle paper.
|
||||
@ -163,7 +161,7 @@ class total_variation(filter):
|
||||
self.img = np.uint8(self.img * 255.0) # converting back to uint8
|
||||
|
||||
|
||||
class block_match(filter):
|
||||
class block_match(img_filter):
|
||||
'''Block matching filter from bm3d.
|
||||
|
||||
This filter is very slow and should be used only on small images
|
||||
@ -179,7 +177,7 @@ class block_match(filter):
|
||||
stage_arg=bm3d.BM3DStages.ALL_STAGES)
|
||||
|
||||
|
||||
class unsharp_mask_scikit(filter):
|
||||
class unsharp_mask_scikit(img_filter):
|
||||
''' Unsharp mask filter from scikit.
|
||||
|
||||
Apply blurring using gaussian filter, then subtract the blurred image from the original image.
|
||||
@ -204,7 +202,7 @@ class unsharp_mask_scikit(filter):
|
||||
# ------------------- EDGE DETECTION FILTERS -------------------#
|
||||
|
||||
|
||||
class farid(filter):
|
||||
class farid(img_filter):
|
||||
''' Farid filter from filters.
|
||||
Not sure what this might be used for yet.
|
||||
'''
|
||||
@ -212,27 +210,27 @@ class farid(filter):
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
def apply(self, _):
|
||||
|
||||
self.img = skiflt.farid(self.img)
|
||||
|
||||
# ------------------ RIDGE EXTRACTION FILTERS ------------------#
|
||||
|
||||
|
||||
class meijering(filter):
|
||||
class meijering(img_filter):
|
||||
''' Meijering filter from scikit-image filters.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
def apply(self, _):
|
||||
|
||||
self.img = skiflt.meijering(self.img)
|
||||
self.img = np.uint8(self.img * 255.0)
|
||||
|
||||
|
||||
class sato(filter):
|
||||
class sato(img_filter):
|
||||
''' Meijering filter from scikit-image filters.
|
||||
Exctracts black ridges.
|
||||
'''
|
||||
@ -240,13 +238,13 @@ class sato(filter):
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
def apply(self, _):
|
||||
|
||||
self.img = skiflt.sato(self.img)
|
||||
self.img = np.uint8(self.img * 255.0)
|
||||
|
||||
|
||||
class hessian(filter):
|
||||
class hessian(img_filter):
|
||||
''' Hessian filter from scikit-image filters.
|
||||
'''
|
||||
|
||||
@ -263,18 +261,18 @@ class hessian(filter):
|
||||
# ------------------- MISCELLANEOUS FILTERS -------------------#
|
||||
|
||||
|
||||
class invert(filter):
|
||||
class invert(img_filter):
|
||||
''' Invert the image using bitwise_not from opencv.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
def apply(self, _):
|
||||
self.img = cv.bitwise_not(self.img)
|
||||
|
||||
|
||||
class scale_values(filter):
|
||||
class scale_values(img_filter):
|
||||
''' Scale values of the image to use the entire range of data type.
|
||||
This should remove the line height issues.
|
||||
'''
|
||||
@ -294,19 +292,17 @@ class scale_values(filter):
|
||||
tmp = tmp * coef
|
||||
|
||||
|
||||
class binarize(filter):
|
||||
class binarize(img_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
|
||||
|
||||
self.img = cv.threshold(self.img, threshold, maxval, type)[1]
|
||||
self.img = cv.threshold(self.img, threshold, 255, cv.THRESH_BINARY)[1]
|
||||
|
||||
|
||||
class binarize_otsu(filter):
|
||||
class binarize_otsu(img_filter):
|
||||
''' Otsu binarization filter from opencv.
|
||||
'''
|
||||
def init(self, img):
|
||||
@ -316,7 +312,7 @@ class binarize_otsu(filter):
|
||||
self.img = cv.threshold(self.img, 0, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)[1]
|
||||
|
||||
|
||||
class add_margin(filter):
|
||||
class add_margin(img_filter):
|
||||
def init(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
@ -330,95 +326,52 @@ class add_margin(filter):
|
||||
self.img, margin, margin, margin, margin, cv.BORDER_CONSTANT, value=color)
|
||||
self.height, self.width = self.img.shape
|
||||
|
||||
# ---------------------- MORPHOLOGICAL OPS --------------------------#
|
||||
|
||||
class erode(img_filter):
|
||||
''' General morphological operations from OpenCV.
|
||||
|
||||
Can be used with MORPH_OPEN, MORPH_CLOSE, MORPH_DILATE, MORPH_ERODE and more as 'op'.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
|
||||
# get an ellipse kernel
|
||||
kernel = np.matrix(params["kernel"]) if params["kernel"] else cv.getStructuringElement(
|
||||
cv.MORPH_ELLIPSE, (3, 3))
|
||||
|
||||
self.img = cv.morphologyEx(
|
||||
np.uint8(self.img), op=cv.MORPH_ERODE, kernel=kernel)
|
||||
|
||||
class dilate(img_filter):
|
||||
''' General morphological operations from OpenCV.
|
||||
|
||||
Can be used with MORPH_OPEN, MORPH_CLOSE, MORPH_DILATE, MORPH_ERODE and more as 'op'.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
|
||||
# get an ellipse kernel
|
||||
kernel = np.matrix(params["kernel"]) if params["kernel"] else cv.getStructuringElement(
|
||||
cv.MORPH_ELLIPSE, (3, 3))
|
||||
|
||||
self.img = cv.morphologyEx(
|
||||
np.uint8(self.img), op=cv.MORPH_DILATE, kernel=kernel)
|
||||
|
||||
|
||||
# ---------------------- OLD --------------------------#
|
||||
|
||||
|
||||
# TODO: REVISE, REMOVE unused filters
|
||||
|
||||
|
||||
class convolve(filter):
|
||||
''' Convolve with custom kernel using opencv.
|
||||
If no kernel is given, use default 3x3 kernel for averaging.
|
||||
Possibly useful for custom filters.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
kernel = np.array(params["kernel"]) if params["kernel"] else np.ones(
|
||||
(3, 3), np.float32) / 9
|
||||
|
||||
self.img = cv.filter2D(self.img, -1, kernel)
|
||||
|
||||
|
||||
class blur(filter):
|
||||
''' Blur filter from opencv.
|
||||
Performs averaging of the image.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
ksize = int(params["ksize"]) if params["ksize"] else 3
|
||||
|
||||
self.img = cv.blur(self.img, ksize=(ksize, ksize))
|
||||
|
||||
|
||||
class denoise(filter):
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
h = int(params["h"]) if params["h"] else 10
|
||||
tWS = int(params["templateWindowSize"]
|
||||
) if params["templateWindowSize"] else 7
|
||||
sWS = int(params["searchWindowSize"]
|
||||
) if params["searchWindowSize"] else 21
|
||||
|
||||
self.img = np.uint8(self.img)
|
||||
self.img = cv.fastNlMeansDenoising(
|
||||
self.img, h, tWS, sWS)
|
||||
|
||||
|
||||
class sharpen(filter):
|
||||
''' Convolution with a sharpening kernel using opencv.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
kernel = np.matrix(params["kernel"]) if params["kernel"] else np.array(
|
||||
[[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
|
||||
|
||||
self.img = cv.filter2D(self.img, ddepth=-1, kernel=kernel)
|
||||
|
||||
|
||||
class unsharp_mask(filter):
|
||||
''' Unsharp mask filter from opencv.
|
||||
|
||||
First blur the image a little bit, then calculate Laplacian of the image to get the edges.
|
||||
Scale the Laplacian and subtract it from the original image.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
strength = float(params["strength"]) if params["strength"] else 1.0
|
||||
ksize = int(params["ksize"]) if params["ksize"] else 3
|
||||
|
||||
blurred = cv.medianBlur(self.img, ksize)
|
||||
lap = cv.Laplacian(blurred, cv.CV_32F)
|
||||
|
||||
self.img = blurred - strength*lap
|
||||
|
||||
|
||||
class unsharp_mask_pil(filter):
|
||||
class unsharp_mask_pil(img_filter):
|
||||
''' Unsharp mask filter from PIL.
|
||||
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
@ -439,73 +392,3 @@ class unsharp_mask_pil(filter):
|
||||
tmp = Image.fromarray(self.img)
|
||||
tmp = tmp.filter(ImageFilter.UnsharpMask(radius, percent, threshold))
|
||||
self.img = np.asarray(tmp)
|
||||
|
||||
|
||||
class erode(filter):
|
||||
''' General morphological operations from OpenCV.
|
||||
|
||||
Can be used with MORPH_OPEN, MORPH_CLOSE, MORPH_DILATE, MORPH_ERODE and more as 'op'.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
|
||||
# get an ellipse kernel
|
||||
kernel = np.matrix(params["kernel"]) if params["kernel"] else cv.getStructuringElement(
|
||||
cv.MORPH_ELLIPSE, (3, 3))
|
||||
|
||||
self.img = cv.morphologyEx(
|
||||
np.uint8(self.img), op=cv.MORPH_ERODE, kernel=kernel)
|
||||
|
||||
|
||||
class dilate(filter):
|
||||
''' General morphological operations from OpenCV.
|
||||
|
||||
Can be used with MORPH_OPEN, MORPH_CLOSE, MORPH_DILATE, MORPH_ERODE and more as 'op'.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
|
||||
# get an ellipse kernel
|
||||
kernel = np.matrix(params["kernel"]) if params["kernel"] else cv.getStructuringElement(
|
||||
cv.MORPH_ELLIPSE, (3, 3))
|
||||
|
||||
self.img = cv.morphologyEx(
|
||||
np.uint8(self.img), op=cv.MORPH_DILATE, kernel=kernel)
|
||||
|
||||
|
||||
class gabor(filter):
|
||||
''' Gabor filter from OpenCV.
|
||||
|
||||
Performs Gabor filtering on the image.
|
||||
'''
|
||||
|
||||
def __init__(self, img):
|
||||
super().__init__(img)
|
||||
|
||||
def apply(self, params):
|
||||
ksize = int(params["ksize"]) if params["ksize"] else 31
|
||||
sigma = float(params["sigma"]) if params["sigma"] else 10.0
|
||||
theta = params["theta"] if params["theta"] else [
|
||||
0, np.pi/16, np.pi-np.pi/16]
|
||||
lambd = float(params["lambd"]) if params["lambd"] else 10.0
|
||||
gamma = float(params["gamma"]) if params["gamma"] else 0.02
|
||||
psi = float(params["psi"]) if params["psi"] else 0.0
|
||||
|
||||
filters = []
|
||||
|
||||
for i in range(len(theta)):
|
||||
g_kernel = cv.getGaborKernel(ksize=(
|
||||
ksize, ksize), sigma=sigma, theta=theta[i], lambd=lambd, gamma=gamma, psi=psi)
|
||||
g_kernel = g_kernel / 1.5 * g_kernel.sum()
|
||||
filters.append(g_kernel)
|
||||
|
||||
tmp = np.zeros_like(self.img)
|
||||
for i in range(len(filters)):
|
||||
tmp = cv.filter2D(self.img, -1, kernel=filters[i])
|
||||
self.img += np.maximum(self.img, tmp)
|
||||
|
Reference in New Issue
Block a user