Python Forum
Iterating kernel through image for filtering
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Iterating kernel through image for filtering
#1
I have two filters: (1) Median Filter and (2) Adaptive Median Filter

My median filter works. It takes an image, creates a padding the kernel convolves, replacing the center pixel with the median value found in each kernel window.

My adaptive median filter does not work. The difference between this one and the first one is that I want my adaptive median filter to iterate through the image block by block, instead of pixel by pixel, replacing the outliers in each kernel window with the median value. I think my logic is correct in my adaptive median, but I'm having trouble lining everything up in my output, especially with the dimensions of the image requiring the padding.

Also, is there a way to not include the padding when calculating the median near the edges?

import cv2 import numpy as np from matplotlib import pyplot as plt import math import sys from skimage.exposure import rescale_intensity np.set_printoptions(threshold=sys.maxsize) # PART 2: ADAPTIVE MEDIAN FILTER # load image image = cv2.imread('2_noise.png',0) image2 = cv2.imread('2_noise.png',0) # convolve function def medianFilter(image, kernel):	# size of image and kernel (iH, iW) = image.shape[:2] (kH, kW) = kernel.shape[:2] print(iH, iW, kH, kW) # add padding to input image pad = (kW - 1) // 2 image = cv2.copyMakeBorder(image, pad, pad, pad, pad, cv2.BORDER_REPLICATE) # allocate memory for the output image output = np.zeros((iH, iW), dtype="float32") # loop over the input image for y in np.arange(pad, iH + pad): for x in np.arange(pad, iW + pad): # extract the *center* region of the current (x, y)-coordinates dimensions roi = image[y - pad:y + pad + 1, x - pad:x + pad + 1]	# convolution k = np.median(roi*kernel)	# store the convolved value in the output(x,y) output[y - pad, x - pad] = k	# rescale the output image output = rescale_intensity(output, in_range=(0, 255)) output = (output * 255).astype("uint8")	# return the output image return output def iqr(a, outlierConstant): """ a : numpy.ndarray (array from which outliers have to be removed.) outlierConstant : (scale factor around interquartile region.) """ num = a.shape[0] upper_quartile = np.percentile(a, 75) lower_quartile = np.percentile(a, 25) IQR = (upper_quartile - lower_quartile) * outlierConstant quartileSet = (lower_quartile - IQR, upper_quartile + IQR) outlier_indx = [] for i in range(num): if np.any(a[i] >= quartileSet[0]) and np.any(a[i] <= quartileSet[1]): pass else: outlier_indx += [i] return outlier_indx def function(arrayMatrix, threshold=.5): zscore = (arrayMatrix - arrayMatrix.mean())/arrayMatrix.std() return np.where(np.abs(zscore) > threshold) def adaptiveMedian(image, kernel):	# size of image and kernel (iH, iW) = image.shape[:2] (kH, kW) = kernel.shape[:2] print('Image Size: ', iH, iW) print('Kernel Size: ', kH, kW) # add padding to input image pad = (kW - 1) // 2 image = cv2.copyMakeBorder(image, pad, pad, pad, pad, cv2.BORDER_REPLICATE) # allocate memory for the output image output = np.zeros((iH+pad*2, iW+pad*2), dtype="float32") yRange = np.arange(pad, iH + pad) for xxx in yRange[::7]: print(xxx) # loop over the input image for y in yRange[::7]: for x in yRange[::7]: #print(np.arange(pad, iH + pad)) # extract the *center* region of the current (x, y)-coordinates dimensions roi = image[y - pad:y + pad + 1, x - pad:x + pad + 1] #print('roi: ', roi) # finding median median = np.median(roi)	# finding outliers & reshaping outlier = function(roi) out = np.asarray(outlier,order=2) rowss = out.shape[0] colss = out.shape[1] xx = out[0] yy = out[1] data = np.array((xx,yy)).T	# replacing outlier pixels with median value Range = len(data) for xx in range(0,Range): xCoord = data[xx][0] yCoord = data[xx][1] roi[xCoord][yCoord] = median #print('roi/median: ', roi) # convolution k = (roi*kernel) #print('k: ', k) # store refined mask into output image (removing salt & pepper) #print('y: ', y) #print('pad: ', pad) #print('x: ', x) output[y - pad:y + pad + 1, x - pad:x + pad + 1] = k # rescale the output image output = rescale_intensity(output, in_range=(0, 255)) output = (output * 255).astype("uint8") # return the output image return output # construct kernel mask median = np.ones((7, 7), dtype="float") # run the functions adaptiveOutput = adaptiveMedian(image, median) medianOutput = medianFilter(image2, median) # plot both images plt.figure(figsize=(11,6)) plt.subplot(131),plt.imshow(image, cmap = 'gray') plt.title('Original Image w/ noise added'), plt.xticks([]), plt.yticks([]) plt.subplot(132),plt.imshow(medianOutput, cmap = 'gray') plt.title('Median Filter'), plt.xticks([]), plt.yticks([]) plt.subplot(133),plt.imshow(adaptiveOutput, cmap = 'gray') plt.title('Adaptive Median Filter'), plt.xticks([]), plt.yticks([]) plt.show()

Had to change the main for loop:

yRange = np.arange(pad, iH + pad) xRange = np.arange(pad, iW + pad) # loop over the input image for y in yRange[::6]: for x in xRange[::6]:
Also putting the output[...] = k line in the for xx loop, everything seems to work now:
 for xx in range(0,Range): xCoord = data[xx][0] yCoord = data[xx][1] roi[xCoord][yCoord] = median #print('roi/median: ', roi) # convolution k = (roi*kernel) #print('k: ', k) # store refined mask into output image (removing salt & pepper) #print('y: ', y) #print('pad: ', pad) #print('x: ', x) output[y - pad:y + pad + 1, x - pad:x + pad + 1] = k
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Setting up new Python kernel for JupyterLab Desktop on M1 Mac daler6 0 2,537 Jun-20-2022, 03:45 AM
Last Post: daler6
  Jupyter kernel restarts russellm10 0 2,819 Sep-14-2021, 04:24 AM
Last Post: russellm10
  Problem: Restart kernel onPydev console when trying to install a python package poppy2020 1 10,794 Nov-25-2020, 06:13 PM
Last Post: Larz60+
  Kernel needs to restart ErnestTBass 0 3,242 May-06-2020, 08:37 PM
Last Post: ErnestTBass
  Cannot install R kernel or R essentials ErnestTBass 4 6,812 May-01-2020, 12:28 AM
Last Post: Larz60+
  Seam Carving or Bilateral image filtering scott14 1 2,944 Dec-09-2018, 07:22 PM
Last Post: Larz60+
  Jupyter error - 'The kernel appears to have died, it will restart automatically' meganhollie 5 21,885 Jun-12-2018, 10:11 PM
Last Post: Larz60+

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020
This forum uses Lukasz Tkacz MyBB addons.
Forum use Krzysztof "Supryk" Supryczynski addons.