Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add files via upload #1

Merged
merged 4 commits into from
Mar 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 68 additions & 0 deletions 095_what_is_convolution.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#!/usr/bin/env python
__author__ = "Sreenivas Bhattiprolu"
__license__ = "Feel free to copy, I appreciate if you acknowledge Python for Microscopists"

# https://youtu.be/1GUgD2SBl9A

"""
Spyder Editor

scipy.signal.convolve2d - https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.convolve2d.html
scipy.ndimage.filters.convolve
cv2.filter2D - https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d

"""
import cv2
import numpy as np
from scipy.signal import convolve2d
from scipy.ndimage.filters import convolve
from skimage import io, img_as_float


img_gaussian_noise = img_as_float(io.imread('images/BSE_25sigma_noisy.jpg', as_gray=True))
img_salt_pepper_noise = img_as_float(io.imread('images/BSE_salt_pepper.jpg', as_gray=True))

img = img_salt_pepper_noise

#convolving the image with a normalized box filter.
#It simply takes the average of all the pixels under kernel area
#and replaces the central element with this average.
#Can also use cv2.blur() to directly apply the convolution rather than defining
#kernel and applying it as a filter (or convolution) separately.
kernel = np.ones((5,5),np.float32)/25 #Averaging filter with 5x5 kernel
#Normalize by dividing with 25 so all numbers add to 1
gaussian_kernel = np.array([[1/16, 1/8, 1/16], #3x3 kernel
[1/8, 1/4, 1/8],
[1/16, 1/8, 1/16]])

laplacian = np.array([[0.,1,0], [1,-4,1], [0,1,0]])
gabor = cv2.getGaborKernel((5, 5), 1.4, 45, 5, 1)

"""
Results from all approaches would be the same..
Remember that if the padding (border) is not done then the output image
and values would be different

"""

conv_using_cv2 = cv2.filter2D(img, -1, kernel, borderType=cv2.BORDER_CONSTANT)
# when ddepth=-1, the output image will have the same depth as the source
#example, if input is float64 then output will also be float64
# BORDER_CONSTANT - Pad the image with a constant value (i.e. black or 0)
#BORDER_REPLICATE: The row or column at the very edge of the original is replicated to the extra border.

conv_using_scipy = convolve2d(img, kernel, mode='same')
#mode ="same" - pads image so the output is same as input

conv_using_scipy2 = convolve(img, kernel, mode='constant', cval=0.0)
#mode=constant adds a constant value at the borders.


cv2.imshow("Original", img)
cv2.imshow("cv2 filter", conv_using_cv2)
cv2.imshow("Using scipy", conv_using_scipy)
cv2.imshow("Using scipy2", conv_using_scipy2)

cv2.waitKey(0)
cv2.destroyAllWindows()

50 changes: 50 additions & 0 deletions 096_What is Gaussian denoising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python
__author__ = "Sreenivas Bhattiprolu"
__license__ = "Feel free to copy, I appreciate if you acknowledge Python for Microscopists"

# https://youtu.be/xCHbcVUCYBI

"""

cv2.filter2D - https://docs.opencv.org/2.4/modules/imgproc/doc/filtering.html?highlight=filter2d#filter2d
cv2.GaussianBlur - https://www.tutorialkart.com/opencv/python/opencv-python-gaussian-image-smoothing/
skimage.filters.gaussian - https://scikit-image.org/docs/dev/api/skimage.filters.html#skimage.filters.gaussian
"""
import cv2
import numpy as np
from skimage import io, img_as_float
from skimage.filters import gaussian

img_gaussian_noise = img_as_float(io.imread('images/BSE_25sigma_noisy.jpg', as_gray=True))
img_salt_pepper_noise = img_as_float(io.imread('images/BSE_salt_pepper.jpg', as_gray=True))

img = img_gaussian_noise

gaussian_kernel = np.array([[1/16, 1/8, 1/16], #3x3 kernel
[1/8, 1/4, 1/8],
[1/16, 1/8, 1/16]])



conv_using_cv2 = cv2.filter2D(img, -1, gaussian_kernel, borderType=cv2.BORDER_CONSTANT)
# when ddepth=-1, the output image will have the same depth as the source
#example, if input is float64 then output will also be float64
# BORDER_CONSTANT - Pad the image with a constant value (i.e. black or 0)
#BORDER_REPLICATE: The row or column at the very edge of the original is replicated to the extra border.

gaussian_using_cv2 = cv2.GaussianBlur(img, (3,3), 0, borderType=cv2.BORDER_CONSTANT)

gaussian_using_skimage = gaussian(img, sigma=1, mode='constant', cval=0.0)
#sigma defines the std dev of the gaussian kernel. SLightly different than
#how we define in cv2


cv2.imshow("Original", img)
cv2.imshow("cv2 filter", conv_using_cv2)
cv2.imshow("Using cv2 gaussian", gaussian_using_cv2)
cv2.imshow("Using skimage", gaussian_using_skimage)
#cv2.imshow("Using scipy2", conv_using_scipy2)

cv2.waitKey(0)
cv2.destroyAllWindows()

42 changes: 42 additions & 0 deletions 097_What is Median denoising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
#!/usr/bin/env python
__author__ = "Sreenivas Bhattiprolu"
__license__ = "Feel free to copy, I appreciate if you acknowledge Python for Microscopists"

# https://youtu.be/StX_1iEO3ck

"""
Spyder Editor

cv2.medianBlur - https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_filtering/py_filtering.html
skimage.filters.median - https://scikit-image.org/docs/dev/api/skimage.filters.html#skimage.filters.median

See how median is much better at cleaning salt and pepper noise compared to Gaussian
"""
import cv2
import numpy as np
from scipy.ndimage.filters import convolve
from skimage import io
from skimage.filters import median

#img = io.imread('images/einstein.jpg', as_gray=True)

#Needs 8 bit, not float.
img_gaussian_noise = cv2.imread('images/BSE_25sigma_noisy.jpg', 0)
img_salt_pepper_noise = cv2.imread('images/BSE_salt_pepper.jpg', 0)

img = img_salt_pepper_noise


median_using_cv2 = cv2.medianBlur(img, 3)

from skimage.morphology import disk
median_using_skimage = median(img, disk(3), mode='constant', cval=0.0)


cv2.imshow("Original", img)
cv2.imshow("cv2 median", median_using_cv2)
cv2.imshow("Using skimage median", median_using_skimage)

cv2.waitKey(0)
cv2.destroyAllWindows()

53 changes: 53 additions & 0 deletions 098_What is Bilateral denoising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#!/usr/bin/env python
__author__ = "Sreenivas Bhattiprolu"
__license__ = "Feel free to copy, I appreciate if you acknowledge Python for Microscopists"

# https://youtu.be/yenye2s90BA

"""
Spyder Editor

cv2.cv2.bilateralFilter - https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_filtering/py_filtering.html
skimage bilateral - https://scikit-image.org/docs/dev/auto_examples/filters/plot_denoise.html

https://people.csail.mit.edu/sparis/bf_course/course_notes.pdf

Bilateral is slow and not very efficient at salt and pepper
"""
import cv2
import numpy as np
from scipy.ndimage.filters import convolve
from skimage import io
from skimage.filters import median


img_gaussian_noise = cv2.imread('images/BSE_25sigma_noisy.jpg', 0)
img_salt_pepper_noise = cv2.imread('images/BSE_salt_pepper.jpg', 0)

img = img_salt_pepper_noise

bilateral_using_cv2 = cv2.bilateralFilter(img, 5, 20, 100, borderType=cv2.BORDER_CONSTANT)

#d - diameter of each pixel neighborhood used during filtering
# sigmaCOlor - Sigma of grey/color space.
#sigmaSpace - Large value means farther pixels influence each other (as long as the colors are close enough)


from skimage.restoration import denoise_bilateral
bilateral_using_skimage = denoise_bilateral(img, sigma_color=0.05, sigma_spatial=15,
multichannel=False)

#sigma_color = float - Sigma for grey or color value.
#For large sigma_color values the filter becomes closer to gaussian blur.
#sigma_spatial: float. Standard ev. for range distance. Increasing this smooths larger features.




cv2.imshow("Original", img)
cv2.imshow("cv2 bilateral", bilateral_using_cv2)
cv2.imshow("Using skimage bilateral", bilateral_using_skimage)

cv2.waitKey(0)
cv2.destroyAllWindows()

52 changes: 52 additions & 0 deletions 099_WHat is NLM.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#!/usr/bin/env python
__author__ = "Sreenivas Bhattiprolu"
__license__ = "Feel free to copy, I appreciate if you acknowledge Python for Microscopists"

# https://youtu.be/Va4Rwoy1v88

"""

https://scikit-image.org/docs/dev/auto_examples/filters/plot_nonlocal_means.html

Works well for random gaussian noise but not as good for salt and pepper
https://www.iro.umontreal.ca/~mignotte/IFT6150/Articles/Buades-NonLocal.pdf

The non-local means algorithm replaces the value of a pixel by an average
of a selection of other pixels values: small patches centered on the other
pixels are compared to the patch centered on the pixel of interest, and the
average is performed only for pixels that have patches close to the current patch.
"""
import cv2
import numpy as np
from skimage import io, img_as_float
from skimage.restoration import denoise_nl_means, estimate_sigma

img_gaussian_noise = img_as_float(io.imread('images/BSE_25sigma_noisy.jpg', as_gray=True))
img_salt_pepper_noise = img_as_float(io.imread('images/BSE_salt_pepper.jpg', as_gray=True))

img = img_gaussian_noise

sigma_est = np.mean(estimate_sigma(img, multichannel=True))
#sigma_est = 0.1

denoise_img = denoise_nl_means(img, h=1.15 * sigma_est, fast_mode=True,
patch_size=5, patch_distance=3, multichannel=False)

"""
When the fast_mode argument is False, a spatial Gaussian weighting is applied
to the patches when computing patch distances. When fast_mode is True a
faster algorithm employing uniform spatial weighting on the patches is applied.

Larger h allows more smoothing between disimilar patches.

"""

#denoise_img_as_8byte = img_as_ubyte(denoise_img)



cv2.imshow("Original", img)
cv2.imshow("NLM Filtered", denoise_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

43 changes: 43 additions & 0 deletions 100_What is Total Variation denoising.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python
__author__ = "Sreenivas Bhattiprolu"
__license__ = "Feel free to copy, I appreciate if you acknowledge Python for Microscopists"

# https://youtu.be/G39dVoiivZk

"""

Works well for random gaussian noise but not as good for salt and pepper

https://hal.archives-ouvertes.fr/hal-00437581/document
"""
import cv2
import numpy as np
from skimage import io, img_as_float
from skimage.restoration import denoise_tv_chambolle
from matplotlib import pyplot as plt

img = img_as_float(io.imread('images/BSE_25sigma_noisy.jpg', as_gray=True))


plt.hist(img.flat, bins=100, range=(0,1)) #.flat returns the flattened numpy array (1D)


denoise_img = denoise_tv_chambolle(img, weight=0.1, eps=0.0002, n_iter_max=200, multichannel=False)

"""
denoise_tv_chambolle(image, weight=0.1, eps=0.0002, n_iter_max=200, multichannel=False)
weight: The greater weight, the more denoising (at the expense of fidelity to input).
eps: Relative difference of the value of the cost function that determines the stop criterion.
n_iter_max: Max number of iterations used for optimization

"""


plt.hist(denoise_img.flat, bins=100, range=(0,1)) #.flat returns the flattened numpy array (1D)


cv2.imshow("Original", img)
cv2.imshow("TV Filtered", denoise_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

34 changes: 34 additions & 0 deletions 101-What is BM3D.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/usr/bin/env python
__author__ = "Sreenivas Bhattiprolu"
__license__ = "Feel free to copy, I appreciate if you acknowledge Python for Microscopists"

# https://youtu.be/aJrG8IH81SY

"""

http://www.cs.tut.fi/~foi/papers/ICIP2019_Ymir.pdf

"""

import matplotlib.pyplot as plt
from skimage import io, img_as_float
from skimage.metrics import peak_signal_noise_ratio
import bm3d
import cv2

noisy_img = img_as_float(io.imread("images/BSE_25sigma_noisy.jpg", as_gray=True))

BM3D_denoised_image = bm3d.bm3d(noisy_img, sigma_psd=0.2, stage_arg=bm3d.BM3DStages.HARD_THRESHOLDING)

"""
bm3d library is not well documented yet, but looking into source code....
sigma_psd - noise standard deviation
stage_arg: Determines whether to perform hard-thresholding or Wiener filtering.
stage_arg = BM3DStages.HARD_THRESHOLDING or BM3DStages.ALL_STAGES (slow but powerful)
All stages performs both hard thresholding and Wiener filtering.
"""

cv2.imshow("Original", noisy_img)
cv2.imshow("Denoised", BM3D_denoised_image)
cv2.waitKey(0)
cv2.destroyAllWindows()
Loading