Let's imagine I have a binary 40*40
matrix.
In this matrix, values can be either ones or zeros.
I need to parse the whole matrix, for any value == 1, apply the following :
If the following condition is met, keep the value = 1, else modify the value back to 0:
Condition: in a square of N*N
(centered on the currently evaluated value), I can count at least M values == 1.
N and M are parameters that can be set for the algorithms, naturally N<20
(in this case) and M<(N*N - 1)
.
The obvious algorithm is to iterate over the whole image and then each time a value == 1. Perform another search around this value. It would make an O^3 complex algorithm. Any idea to make this more efficient?
Let's create a randomly initialized 40*40 matrix of 1s and 0s. 5% (arbitrarily chosen) of the values are 1s, 95% are 0s.
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
def display_array(image):
image_display_ready = image * 255
print(image_display_ready)
plt.imshow(image_display_ready, cmap='gray')
plt.show()
image = np.zeros([40,40])
for _ in range(80): # 5% of the pixels are == 1
i, j = np.random.randint(40, size=2)
image[i, j] = 1
# Image displayed on left below before preprocessing
display_array(image)
def cleaning_algorithm_v1(src_image, FAT, LR, FLAG, verbose=False):
"""
FAT = 4 # False Alarm Threshold (number of surrounding 1s pixel values)
LR = 8 # Lookup Range +/- i/j value
FLAG = 2 # 1s pixels kept as 1s after processing are flag with this value.
"""
rslt_img = np.copy(src_image)
for i in range(rslt_img.shape[0]):
for j in range(rslt_img.shape[1]):
if rslt_img[i, j] >= 1:
surrounding_abnormal_pixels = list()
lower_i = max(i - LR, 0)
upper_i = min(i + LR + 1, rslt_img.shape[0])
lower_j = max(j - LR, 0)
upper_j = min(j + LR + 1, rslt_img.shape[1])
abnormal_pixel_count = 0
for i_k in range(lower_i, upper_i):
for j_k in range(lower_j, upper_j):
if i_k == i and j_k == j:
continue
pixel_value = rslt_img[i_k, j_k]
if pixel_value >= 1:
abnormal_pixel_count += 1
if abnormal_pixel_count >= FAT:
rslt_img[i, j] = FLAG
rslt_img[rslt_img != FLAG] = 0
rslt_img[rslt_img == FLAG] = 1
return rslt_img
# Image displayed on right below after preprocessing
display_array(cleaning_algorithm_v1(image, FAT=10, LR=6, FLAG=2))
Which gives the following:
Optimization Algorithms Optimization refers to a procedure for finding the input parameters or arguments to a function that result in the minimum or maximum output of the function.
Gradient Descent is the most basic but most used optimization algorithm. It's used heavily in linear regression and classification algorithms. Backpropagation in neural networks also uses a gradient descent algorithm.
The genetic algorithm is a method for solving optimization problems.
What about using convolution?
Your kernel would be an NxN window of 1's. In this case the kernel is separable so you can process the convolution as 2 1-D convolutions. You could do something like:
import numpy as np
from scipy.ndimage.filters import convolve1d
from time import time
mat = np.random.random_integers(0, 1, (40, 40))
N = 5
M = 15
window = np.ones((N, ), dtype=np.int)
start = time()
interm = convolve1d(mat, window, axis=0)
result = convolve1d(interm, window, axis=1)
[rows, cols] = np.where(result >= M)
result[:, :] = 0
result[(rows, cols)] = 1
end = time()
print "{} seconds".format(end - start)
0.00155591964722 seconds
Not sure how the complexity compares, but convolution is pretty well optimised in a variety of python deep learning libraries.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With