Skip to content

Commit

Permalink
Add Digital Image Processing Algorithm: Local Binary Pattern (TheAlgo…
Browse files Browse the repository at this point in the history
…rithms#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 <[email protected]>

* Update digital_image_processing/filters/local_binary_pattern.py

Co-authored-by: Christian Clauss <[email protected]>

* Update digital_image_processing/filters/local_binary_pattern.py

Co-authored-by: Christian Clauss <[email protected]>

* 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 <[email protected]>

* 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 <[email protected]>
  • Loading branch information
3 people authored Aug 24, 2022
1 parent f31fa4e commit b1818af
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 0 deletions.
2 changes: 2 additions & 0 deletions DIRECTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@
* [Fenwick Tree](data_structures/binary_tree/fenwick_tree.py)
* [Lazy Segment Tree](data_structures/binary_tree/lazy_segment_tree.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)
* [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)
Expand Down Expand Up @@ -229,6 +230,7 @@
* [Convolve](digital_image_processing/filters/convolve.py)
* [Gabor Filter](digital_image_processing/filters/gabor_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)
* [Sobel Filter](digital_image_processing/filters/sobel_filter.py)
* Histogram Equalization
Expand Down
81 changes: 81 additions & 0 deletions digital_image_processing/filters/local_binary_pattern.py
Original file line number Diff line number Diff line change
@@ -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()
32 changes: 32 additions & 0 deletions digital_image_processing/test_digital_image_processing.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
PyTest's for Digital Image Processing
"""
import numpy as np
from cv2 import COLOR_BGR2GRAY, cvtColor, imread
from numpy import array, uint8
from PIL import Image
Expand All @@ -12,6 +13,7 @@
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 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 sobel_filter as sob
from digital_image_processing.resize import resize as rs
Expand Down Expand Up @@ -91,3 +93,33 @@ def test_nearest_neighbour(
nn = rs.NearestNeighbour(imread(file_path, 1), 400, 200)
nn.process()
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()

0 comments on commit b1818af

Please sign in to comment.