mirror of
https://github.com/TheAlgorithms/Python.git
synced 2024-11-27 15:01:08 +00:00
Add Digital Image Processing Algorithm: Local Binary Pattern (#6294)
* add algorithm local binary pattern * fix failed test for local binary pattern * updating DIRECTORY.md * fix detected precommit-error * fix precommit error * final check * Add descriptive name for parameters x and y * Update digital_image_processing/filters/local_binary_pattern.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update digital_image_processing/filters/local_binary_pattern.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update digital_image_processing/filters/local_binary_pattern.py Co-authored-by: Christian Clauss <cclauss@me.com> * Update local_binary_pattern.py * undo changes made on get_neighbors_pixel() * files formatted by black * Update digital_image_processing/filters/local_binary_pattern.py ok thanks Co-authored-by: Christian Clauss <cclauss@me.com> * add test for get_neighbors_pixel() function * reviewed * fix get_neighbors_pixel * Update test_digital_image_processing.py * updating DIRECTORY.md * Create code_quality.yml * Create code_quality.yml * Delete code_quality.yml * Update code_quality.yml * Delete code_quality.yml Co-authored-by: github-actions <${GITHUB_ACTOR}@users.noreply.github.com> Co-authored-by: Christian Clauss <cclauss@me.com>
This commit is contained in:
parent
f31fa4ea7e
commit
b1818af517
|
@ -152,6 +152,7 @@
|
||||||
* [Fenwick Tree](data_structures/binary_tree/fenwick_tree.py)
|
* [Fenwick Tree](data_structures/binary_tree/fenwick_tree.py)
|
||||||
* [Lazy Segment Tree](data_structures/binary_tree/lazy_segment_tree.py)
|
* [Lazy Segment Tree](data_structures/binary_tree/lazy_segment_tree.py)
|
||||||
* [Lowest Common Ancestor](data_structures/binary_tree/lowest_common_ancestor.py)
|
* [Lowest Common Ancestor](data_structures/binary_tree/lowest_common_ancestor.py)
|
||||||
|
* [Maximum Fenwick Tree](data_structures/binary_tree/maximum_fenwick_tree.py)
|
||||||
* [Merge Two Binary Trees](data_structures/binary_tree/merge_two_binary_trees.py)
|
* [Merge Two Binary Trees](data_structures/binary_tree/merge_two_binary_trees.py)
|
||||||
* [Non Recursive Segment Tree](data_structures/binary_tree/non_recursive_segment_tree.py)
|
* [Non Recursive Segment Tree](data_structures/binary_tree/non_recursive_segment_tree.py)
|
||||||
* [Number Of Possible Binary Trees](data_structures/binary_tree/number_of_possible_binary_trees.py)
|
* [Number Of Possible Binary Trees](data_structures/binary_tree/number_of_possible_binary_trees.py)
|
||||||
|
@ -229,6 +230,7 @@
|
||||||
* [Convolve](digital_image_processing/filters/convolve.py)
|
* [Convolve](digital_image_processing/filters/convolve.py)
|
||||||
* [Gabor Filter](digital_image_processing/filters/gabor_filter.py)
|
* [Gabor Filter](digital_image_processing/filters/gabor_filter.py)
|
||||||
* [Gaussian Filter](digital_image_processing/filters/gaussian_filter.py)
|
* [Gaussian Filter](digital_image_processing/filters/gaussian_filter.py)
|
||||||
|
* [Local Binary Pattern](digital_image_processing/filters/local_binary_pattern.py)
|
||||||
* [Median Filter](digital_image_processing/filters/median_filter.py)
|
* [Median Filter](digital_image_processing/filters/median_filter.py)
|
||||||
* [Sobel Filter](digital_image_processing/filters/sobel_filter.py)
|
* [Sobel Filter](digital_image_processing/filters/sobel_filter.py)
|
||||||
* Histogram Equalization
|
* Histogram Equalization
|
||||||
|
|
81
digital_image_processing/filters/local_binary_pattern.py
Normal file
81
digital_image_processing/filters/local_binary_pattern.py
Normal file
|
@ -0,0 +1,81 @@
|
||||||
|
import cv2
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
|
|
||||||
|
def get_neighbors_pixel(
|
||||||
|
image: np.ndarray, x_coordinate: int, y_coordinate: int, center: int
|
||||||
|
) -> int:
|
||||||
|
"""
|
||||||
|
Comparing local neighborhood pixel value with threshold value of centre pixel.
|
||||||
|
Exception is required when neighborhood value of a center pixel value is null.
|
||||||
|
i.e. values present at boundaries.
|
||||||
|
|
||||||
|
:param image: The image we're working with
|
||||||
|
:param x_coordinate: x-coordinate of the pixel
|
||||||
|
:param y_coordinate: The y coordinate of the pixel
|
||||||
|
:param center: center pixel value
|
||||||
|
:return: The value of the pixel is being returned.
|
||||||
|
"""
|
||||||
|
|
||||||
|
try:
|
||||||
|
return int(image[x_coordinate][y_coordinate] >= center)
|
||||||
|
except (IndexError, TypeError):
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def local_binary_value(image: np.ndarray, x_coordinate: int, y_coordinate: int) -> int:
|
||||||
|
"""
|
||||||
|
It takes an image, an x and y coordinate, and returns the
|
||||||
|
decimal value of the local binary patternof the pixel
|
||||||
|
at that coordinate
|
||||||
|
|
||||||
|
:param image: the image to be processed
|
||||||
|
:param x_coordinate: x coordinate of the pixel
|
||||||
|
:param y_coordinate: the y coordinate of the pixel
|
||||||
|
:return: The decimal value of the binary value of the pixels
|
||||||
|
around the center pixel.
|
||||||
|
"""
|
||||||
|
center = image[x_coordinate][y_coordinate]
|
||||||
|
powers = [1, 2, 4, 8, 16, 32, 64, 128]
|
||||||
|
|
||||||
|
# skip get_neighbors_pixel if center is null
|
||||||
|
if center is None:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# Starting from the top right, assigning value to pixels clockwise
|
||||||
|
binary_values = [
|
||||||
|
get_neighbors_pixel(image, x_coordinate - 1, y_coordinate + 1, center),
|
||||||
|
get_neighbors_pixel(image, x_coordinate, y_coordinate + 1, center),
|
||||||
|
get_neighbors_pixel(image, x_coordinate - 1, y_coordinate, center),
|
||||||
|
get_neighbors_pixel(image, x_coordinate + 1, y_coordinate + 1, center),
|
||||||
|
get_neighbors_pixel(image, x_coordinate + 1, y_coordinate, center),
|
||||||
|
get_neighbors_pixel(image, x_coordinate + 1, y_coordinate - 1, center),
|
||||||
|
get_neighbors_pixel(image, x_coordinate, y_coordinate - 1, center),
|
||||||
|
get_neighbors_pixel(image, x_coordinate - 1, y_coordinate - 1, center),
|
||||||
|
]
|
||||||
|
|
||||||
|
# Converting the binary value to decimal.
|
||||||
|
return sum(
|
||||||
|
binary_value * power for binary_value, power in zip(binary_values, powers)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "main":
|
||||||
|
|
||||||
|
# Reading the image and converting it to grayscale.
|
||||||
|
image = cv2.imread(
|
||||||
|
"digital_image_processing/image_data/lena.jpg", cv2.IMREAD_GRAYSCALE
|
||||||
|
)
|
||||||
|
|
||||||
|
# Create a numpy array as the same height and width of read image
|
||||||
|
lbp_image = np.zeros((image.shape[0], image.shape[1]))
|
||||||
|
|
||||||
|
# Iterating through the image and calculating the
|
||||||
|
# local binary pattern value for each pixel.
|
||||||
|
for i in range(0, image.shape[0]):
|
||||||
|
for j in range(0, image.shape[1]):
|
||||||
|
lbp_image[i][j] = local_binary_value(image, i, j)
|
||||||
|
|
||||||
|
cv2.imshow("local binary pattern", lbp_image)
|
||||||
|
cv2.waitKey(0)
|
||||||
|
cv2.destroyAllWindows()
|
|
@ -1,6 +1,7 @@
|
||||||
"""
|
"""
|
||||||
PyTest's for Digital Image Processing
|
PyTest's for Digital Image Processing
|
||||||
"""
|
"""
|
||||||
|
import numpy as np
|
||||||
from cv2 import COLOR_BGR2GRAY, cvtColor, imread
|
from cv2 import COLOR_BGR2GRAY, cvtColor, imread
|
||||||
from numpy import array, uint8
|
from numpy import array, uint8
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
@ -12,6 +13,7 @@ from digital_image_processing.dithering import burkes as bs
|
||||||
from digital_image_processing.edge_detection import canny as canny
|
from digital_image_processing.edge_detection import canny as canny
|
||||||
from digital_image_processing.filters import convolve as conv
|
from digital_image_processing.filters import convolve as conv
|
||||||
from digital_image_processing.filters import gaussian_filter as gg
|
from digital_image_processing.filters import gaussian_filter as gg
|
||||||
|
from digital_image_processing.filters import local_binary_pattern as lbp
|
||||||
from digital_image_processing.filters import median_filter as med
|
from digital_image_processing.filters import median_filter as med
|
||||||
from digital_image_processing.filters import sobel_filter as sob
|
from digital_image_processing.filters import sobel_filter as sob
|
||||||
from digital_image_processing.resize import resize as rs
|
from digital_image_processing.resize import resize as rs
|
||||||
|
@ -91,3 +93,33 @@ def test_nearest_neighbour(
|
||||||
nn = rs.NearestNeighbour(imread(file_path, 1), 400, 200)
|
nn = rs.NearestNeighbour(imread(file_path, 1), 400, 200)
|
||||||
nn.process()
|
nn.process()
|
||||||
assert nn.output.any()
|
assert nn.output.any()
|
||||||
|
|
||||||
|
|
||||||
|
def test_local_binary_pattern():
|
||||||
|
file_path: str = "digital_image_processing/image_data/lena.jpg"
|
||||||
|
|
||||||
|
# Reading the image and converting it to grayscale.
|
||||||
|
image = imread(file_path, 0)
|
||||||
|
|
||||||
|
# Test for get_neighbors_pixel function() return not None
|
||||||
|
x_coordinate = 0
|
||||||
|
y_coordinate = 0
|
||||||
|
center = image[x_coordinate][y_coordinate]
|
||||||
|
|
||||||
|
neighbors_pixels = lbp.get_neighbors_pixel(
|
||||||
|
image, x_coordinate, y_coordinate, center
|
||||||
|
)
|
||||||
|
|
||||||
|
assert neighbors_pixels is not None
|
||||||
|
|
||||||
|
# Test for local_binary_pattern function()
|
||||||
|
# Create a numpy array as the same height and width of read image
|
||||||
|
lbp_image = np.zeros((image.shape[0], image.shape[1]))
|
||||||
|
|
||||||
|
# Iterating through the image and calculating the local binary pattern value
|
||||||
|
# for each pixel.
|
||||||
|
for i in range(0, image.shape[0]):
|
||||||
|
for j in range(0, image.shape[1]):
|
||||||
|
lbp_image[i][j] = lbp.local_binary_value(image, i, j)
|
||||||
|
|
||||||
|
assert lbp_image.any()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user