|
|
@ -1,17 +1,18 @@
|
|
|
|
"""! @file filters.py
|
|
|
|
"""! @file filters.py
|
|
|
|
@brief Filter library for the application
|
|
|
|
@brief Filter library for the application
|
|
|
|
@author xlanro00
|
|
|
|
@author xlanro00
|
|
|
|
"""
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
import numpy as np
|
|
|
|
import numpy as np
|
|
|
|
#import matplotlib.pyplot as plt
|
|
|
|
#import matplotlib.pyplot as plt
|
|
|
|
import cv2 as cv
|
|
|
|
import cv2 as cv
|
|
|
|
|
|
|
|
from skimage import filters as skiflt
|
|
|
|
|
|
|
|
from skimage import restoration as skirest
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Parent class for all the filters
|
|
|
|
# Parent class for all the filters
|
|
|
|
class filter:
|
|
|
|
class filter:
|
|
|
|
'''
|
|
|
|
''' Parent class for all the filters.
|
|
|
|
Parent class for all the filters
|
|
|
|
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
@ -19,8 +20,9 @@ class filter:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class convolve(filter):
|
|
|
|
class convolve(filter):
|
|
|
|
''' Convolve using custom kernel,
|
|
|
|
''' Convolve with custom kernel using opencv.
|
|
|
|
if no kernel is given, use default 3x3 kernel for averaging
|
|
|
|
If no kernel is given, use default 3x3 kernel for averaging.
|
|
|
|
|
|
|
|
Possibly useful for custom filters.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
@ -31,15 +33,20 @@ class convolve(filter):
|
|
|
|
kernel = np.array(params["kernel"]) if params["kernel"] else np.ones(
|
|
|
|
kernel = np.array(params["kernel"]) if params["kernel"] else np.ones(
|
|
|
|
(ksize, ksize), np.float32) / np.sqrt(ksize)
|
|
|
|
(ksize, ksize), np.float32) / np.sqrt(ksize)
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " ksize: " + str(ksize) + " kernel: \n" + str(kernel))
|
|
|
|
print("with params: ksize: " +
|
|
|
|
|
|
|
|
str(ksize) + " kernel: \n" + str(kernel))
|
|
|
|
self.img = cv.filter2D(self.img, -1, kernel)
|
|
|
|
self.img = cv.filter2D(self.img, -1, kernel)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class blur(filter):
|
|
|
|
class blur(filter):
|
|
|
|
|
|
|
|
''' Blur filter from OpenCV.
|
|
|
|
|
|
|
|
Performs averaging of the image.
|
|
|
|
|
|
|
|
'''
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
|
super().__init__(img)
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
|
def apply(self, params):
|
|
|
|
def apply(self, params):
|
|
|
|
|
|
|
|
# TODO remove try-except
|
|
|
|
if(params["anchor"]):
|
|
|
|
if(params["anchor"]):
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
anchor = tuple(map(int, params["anchor"].split(',')))
|
|
|
|
anchor = tuple(map(int, params["anchor"].split(',')))
|
|
|
@ -49,11 +56,14 @@ class blur(filter):
|
|
|
|
anchor = (-1, -1)
|
|
|
|
anchor = (-1, -1)
|
|
|
|
ksize = int(params["ksize"]) if params["ksize"] else 3
|
|
|
|
ksize = int(params["ksize"]) if params["ksize"] else 3
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " ksize: " + str(ksize) + " anchor: " + str(anchor))
|
|
|
|
print("with params: ksize: " +
|
|
|
|
|
|
|
|
str(ksize) + " anchor: " + str(anchor))
|
|
|
|
self.img = cv.blur(self.img, ksize=(ksize, ksize), anchor=anchor)
|
|
|
|
self.img = cv.blur(self.img, ksize=(ksize, ksize), anchor=anchor)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class gaussian(filter):
|
|
|
|
class gaussian(filter):
|
|
|
|
|
|
|
|
''' Gaussian blur filter from OpenCV.
|
|
|
|
|
|
|
|
'''
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
|
super().__init__(img)
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
@ -62,22 +72,27 @@ class gaussian(filter):
|
|
|
|
sigmaX = float(params["sigmaX"]) if params["sigmaX"] else 0
|
|
|
|
sigmaX = float(params["sigmaX"]) if params["sigmaX"] else 0
|
|
|
|
sigmaY = float(params["sigmaY"]) if params["sigmaY"] else 0
|
|
|
|
sigmaY = float(params["sigmaY"]) if params["sigmaY"] else 0
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " ksize: " + str(ksize) + " sigmaX: " + str(sigmaX) + " sigmaY: " + str(sigmaY))
|
|
|
|
print("with params: ksize: " + str(ksize) +
|
|
|
|
|
|
|
|
" sigmaX: " + str(sigmaX) + " sigmaY: " + str(sigmaY))
|
|
|
|
self.img = cv.GaussianBlur(self.img, (ksize, ksize), sigmaX, sigmaY)
|
|
|
|
self.img = cv.GaussianBlur(self.img, (ksize, ksize), sigmaX, sigmaY)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class median(filter):
|
|
|
|
class median(filter):
|
|
|
|
|
|
|
|
''' Median blur filter from OpenCV.
|
|
|
|
|
|
|
|
'''
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
|
super().__init__(img)
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
|
def apply(self, params):
|
|
|
|
def apply(self, params):
|
|
|
|
ksize = int(params["ksize"]) if params["ksize"] else 3
|
|
|
|
ksize = int(params["ksize"]) if params["ksize"] else 3
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " ksize: " + str(ksize))
|
|
|
|
print("with params: ksize: " + str(ksize))
|
|
|
|
self.img = cv.medianBlur(np.uint8(self.img), ksize)
|
|
|
|
self.img = cv.medianBlur(np.float32(self.img), ksize)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class bilateral(filter):
|
|
|
|
class bilateral(filter):
|
|
|
|
|
|
|
|
''' Bilateral filter from OpenCV.
|
|
|
|
|
|
|
|
'''
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
|
super().__init__(img)
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
@ -87,27 +102,87 @@ class bilateral(filter):
|
|
|
|
sigmaColor = int(params["sigmaColor"]) if params["sigmaColor"] else 75
|
|
|
|
sigmaColor = int(params["sigmaColor"]) if params["sigmaColor"] else 75
|
|
|
|
sigmaSpace = int(params["sigmaSpace"]) if params["sigmaSpace"] else 75
|
|
|
|
sigmaSpace = int(params["sigmaSpace"]) if params["sigmaSpace"] else 75
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " d: " + str(d) + " sigmaColor: " + str(sigmaColor) + " sigmaSpace: " + str(sigmaSpace))
|
|
|
|
print("with params: d: " + str(d) + " sigmaColor: " +
|
|
|
|
|
|
|
|
str(sigmaColor) + " sigmaSpace: " + str(sigmaSpace))
|
|
|
|
self.img = cv.bilateralFilter(self.img, d, sigmaColor, sigmaSpace)
|
|
|
|
self.img = cv.bilateralFilter(self.img, d, sigmaColor, sigmaSpace)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class denoise(filter):
|
|
|
|
class denoise(filter):
|
|
|
|
|
|
|
|
# TODO possibly not necessary
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
|
super().__init__(img)
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
|
def apply(self, params):
|
|
|
|
def apply(self, params):
|
|
|
|
h = int(params["h"]) if params["h"] else 20
|
|
|
|
h = int(params["h"]) if params["h"] else 10
|
|
|
|
tWS = int(params["templateWindowSize"]
|
|
|
|
tWS = int(params["templateWindowSize"]
|
|
|
|
) if params["templateWindowSize"] else 7
|
|
|
|
) if params["templateWindowSize"] else 7
|
|
|
|
sWS = int(params["searchWindowSize"]
|
|
|
|
sWS = int(params["searchWindowSize"]
|
|
|
|
) if params["searchWindowSize"] else 21
|
|
|
|
) if params["searchWindowSize"] else 21
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " h: " + str(h) + " tWS: " + str(tWS) + " sWS: " + str(sWS))
|
|
|
|
print("with params: h: " + str(h) +
|
|
|
|
|
|
|
|
" tWS: " + str(tWS) + " sWS: " + str(sWS))
|
|
|
|
self.img = np.uint8(self.img)
|
|
|
|
self.img = np.uint8(self.img)
|
|
|
|
self.img = cv.fastNlMeansDenoising(self.img, h, tWS, sWS)
|
|
|
|
self.img = cv.fastNlMeansDenoising(
|
|
|
|
|
|
|
|
self.img, h, tWS, sWS)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class denoise_bilateral(filter):
|
|
|
|
|
|
|
|
''' Scikit image denoise_bilateral filter.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Performs bilateral denoising technique on the image.
|
|
|
|
|
|
|
|
Averages pixels based on their distance and color similarity.
|
|
|
|
|
|
|
|
Preserves edges while removing unwanted noise.
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, img):
|
|
|
|
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def apply(self, params):
|
|
|
|
|
|
|
|
sigmaColor = float(params["sigmaColor"]
|
|
|
|
|
|
|
|
) if params["sigmaColor"] else 0.1
|
|
|
|
|
|
|
|
sigmaSpace = float(params["sigmaSpace"]
|
|
|
|
|
|
|
|
) if params["sigmaSpace"] else 15.0
|
|
|
|
|
|
|
|
channelAxis = int(params["channelAxis"]
|
|
|
|
|
|
|
|
) if params["channelAxis"] else None
|
|
|
|
|
|
|
|
iterations = int(params["iterations"]) if params["iterations"] else 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("with params: sigma_color: " + str(sigmaColor) +
|
|
|
|
|
|
|
|
" sigma_spatial: " + str(sigmaSpace) + " channel_axis: " +
|
|
|
|
|
|
|
|
str(channelAxis) + " iterations: " + str(iterations))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for i in range(iterations):
|
|
|
|
|
|
|
|
self.img = skirest.denoise_bilateral(
|
|
|
|
|
|
|
|
self.img, sigma_color=sigmaColor,
|
|
|
|
|
|
|
|
sigma_spatial=sigmaSpace, channel_axis=channelAxis)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class denoise_tv_chambolle(filter):
|
|
|
|
|
|
|
|
''' Scikit image denoise_tv_chambolle filter from scikit-image.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Performs total variation denoising technique on the image.
|
|
|
|
|
|
|
|
This filter removes fine detail, but preserves edges.
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, img):
|
|
|
|
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def apply(self, params):
|
|
|
|
|
|
|
|
weight = float(params["weight"]) if params["weight"] else 0.1
|
|
|
|
|
|
|
|
channelAxis = int(params["channelAxis"]
|
|
|
|
|
|
|
|
) if params["channelAxis"] else None
|
|
|
|
|
|
|
|
iterations = int(params["iterations"]) if params["iterations"] else 1
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("with params: weight: " + str(weight) +
|
|
|
|
|
|
|
|
" channel_axis: " + str(channelAxis) + " iterations: " + str(iterations))
|
|
|
|
|
|
|
|
for i in range(iterations):
|
|
|
|
|
|
|
|
self.img = skirest.denoise_tv_chambolle(
|
|
|
|
|
|
|
|
self.img, weight=weight, channel_axis=channelAxis)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class sharpen(filter):
|
|
|
|
class sharpen(filter):
|
|
|
|
|
|
|
|
''' Convolution with a sharpening kernel using opencv.
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
# TODO possibly unnecessary, because unsharp masking is working better
|
|
|
|
def __init__(self, img):
|
|
|
|
def __init__(self, img):
|
|
|
|
super().__init__(img)
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
@ -115,12 +190,12 @@ class sharpen(filter):
|
|
|
|
kernel = np.matrix(params["kernel"]) if params["kernel"] else np.array(
|
|
|
|
kernel = np.matrix(params["kernel"]) if params["kernel"] else np.array(
|
|
|
|
[[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
|
|
|
|
[[0, -1, 0], [-1, 5, -1], [0, -1, 0]])
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " kernel: \n" + str(kernel))
|
|
|
|
print("with params: kernel: \n" + str(kernel))
|
|
|
|
self.img = cv.filter2D(self.img, ddepth=-1, kernel=kernel)
|
|
|
|
self.img = cv.filter2D(self.img, ddepth=-1, kernel=kernel)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class unsharp_mask(filter):
|
|
|
|
class unsharp_mask(filter):
|
|
|
|
''' 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.
|
|
|
|
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.
|
|
|
|
Scale the Laplacian and subtract it from the original image.
|
|
|
@ -132,13 +207,43 @@ class unsharp_mask(filter):
|
|
|
|
def apply(self, params):
|
|
|
|
def apply(self, params):
|
|
|
|
strength = float(params["strength"]) if params["strength"] else 1.0
|
|
|
|
strength = float(params["strength"]) if params["strength"] else 1.0
|
|
|
|
ksize = int(params["ksize"]) if params["ksize"] else 3
|
|
|
|
ksize = int(params["ksize"]) if params["ksize"] else 3
|
|
|
|
blurred = cv.medianBlur(np.uint8(self.img), ksize)
|
|
|
|
|
|
|
|
|
|
|
|
blurred = cv.medianBlur(self.img, ksize)
|
|
|
|
lap = cv.Laplacian(blurred, cv.CV_32F)
|
|
|
|
lap = cv.Laplacian(blurred, cv.CV_32F)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
print("with params: strength: " +
|
|
|
|
|
|
|
|
str(strength) + " ksize: " + str(ksize))
|
|
|
|
self.img = blurred - strength*lap
|
|
|
|
self.img = blurred - strength*lap
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class unsharp_mask_scikit(filter):
|
|
|
|
|
|
|
|
''' Unsharp mask filter from scikit.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Apply blurring using gaussian filter, then subtract the blurred image from the original image.
|
|
|
|
|
|
|
|
Radius parameter is the sigma parameter of the gaussian filter.
|
|
|
|
|
|
|
|
Amount parameter regulates the strength of the unsharp mask.
|
|
|
|
|
|
|
|
Better results than using opencv module.
|
|
|
|
|
|
|
|
'''
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def __init__(self, img):
|
|
|
|
|
|
|
|
super().__init__(img)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def apply(self, params):
|
|
|
|
|
|
|
|
radius = int(params["radius"]) if params["radius"] else 3
|
|
|
|
|
|
|
|
amount = float(params["amount"]) if params["amount"] else 1
|
|
|
|
|
|
|
|
channelAxis = int(params["channelAxis"]
|
|
|
|
|
|
|
|
) if params["channelAxis"] else None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#self.img = cv.cvtColor(self.img, cv.COLOR_GRAY2RGB)
|
|
|
|
|
|
|
|
print("with params: radius: " +
|
|
|
|
|
|
|
|
str(radius) + " amount: " + str(amount))
|
|
|
|
|
|
|
|
self.img = skiflt.unsharp_mask(
|
|
|
|
|
|
|
|
self.img, radius=radius, amount=amount, channel_axis=channelAxis)
|
|
|
|
|
|
|
|
#self.img = cv.cvtColor(self.img, cv.COLOR_RGB2GRAY)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class morph(filter):
|
|
|
|
class morph(filter):
|
|
|
|
''' General morphological operations.
|
|
|
|
''' General morphological operations from OpenCV.
|
|
|
|
|
|
|
|
|
|
|
|
Can be used with MORPH_OPEN, MORPH_CLOSE, MORPH_DILATE, MORPH_ERODE and more as 'op'.
|
|
|
|
Can be used with MORPH_OPEN, MORPH_CLOSE, MORPH_DILATE, MORPH_ERODE and more as 'op'.
|
|
|
|
'''
|
|
|
|
'''
|
|
|
@ -152,6 +257,7 @@ class morph(filter):
|
|
|
|
iterations = int(params["iterations"]) if params["iterations"] else 1
|
|
|
|
iterations = int(params["iterations"]) if params["iterations"] else 1
|
|
|
|
op = getattr(cv, params["op"]) if params["op"] else cv.MORPH_OPEN
|
|
|
|
op = getattr(cv, params["op"]) if params["op"] else cv.MORPH_OPEN
|
|
|
|
if(params["anchor"]):
|
|
|
|
if(params["anchor"]):
|
|
|
|
|
|
|
|
# TODO remove try-except
|
|
|
|
try:
|
|
|
|
try:
|
|
|
|
anchor = tuple(map(int, params["anchor"].split(',')))
|
|
|
|
anchor = tuple(map(int, params["anchor"].split(',')))
|
|
|
|
except AttributeError:
|
|
|
|
except AttributeError:
|
|
|
@ -159,6 +265,8 @@ class morph(filter):
|
|
|
|
else:
|
|
|
|
else:
|
|
|
|
anchor = (-1, -1)
|
|
|
|
anchor = (-1, -1)
|
|
|
|
|
|
|
|
|
|
|
|
#print("with params: " + " kernel: \n" + str(kernel) + " anchor: " + str(anchor) + " iterations: " + str(iterations) + " op: " + str(op))
|
|
|
|
print("with params: kernel: \n" + str(kernel) + " anchor: " +
|
|
|
|
|
|
|
|
str(anchor) + " iterations: " + str(iterations) + " op: " + str(op))
|
|
|
|
self.img = cv.morphologyEx(
|
|
|
|
self.img = cv.morphologyEx(
|
|
|
|
self.img, op=op, kernel=kernel, anchor=anchor, iterations=iterations)
|
|
|
|
np.uint8(self.img), op=op, kernel=kernel,
|
|
|
|
|
|
|
|
anchor=anchor, iterations=iterations)
|
|
|
|