Skip to content

Commit 5cef77a

Browse files
committed
Added histogram equalization in computer vision
1 parent 0040ad4 commit 5cef77a

File tree

19 files changed

+130
-87
lines changed

19 files changed

+130
-87
lines changed

Diff for: ciphers/base64_cipher.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -105,13 +105,13 @@ def base64_decode(encoded_data: str) -> bytes:
105105

106106
# Check if the encoded string contains non base64 characters
107107
if padding:
108-
assert all(char in B64_CHARSET for char in encoded_data[:-padding]), (
109-
"Invalid base64 character(s) found."
110-
)
108+
assert all(
109+
char in B64_CHARSET for char in encoded_data[:-padding]
110+
), "Invalid base64 character(s) found."
111111
else:
112-
assert all(char in B64_CHARSET for char in encoded_data), (
113-
"Invalid base64 character(s) found."
114-
)
112+
assert all(
113+
char in B64_CHARSET for char in encoded_data
114+
), "Invalid base64 character(s) found."
115115

116116
# Check the padding
117117
assert len(encoded_data) % 4 == 0 and padding < 3, "Incorrect padding"

Diff for: computer_vision/histogram_equalization.py

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import cv2
2+
import numpy as np
3+
4+
"""
5+
Histogram Equalization for Image Enhancement
6+
https://en.wikipedia.org/wiki/Histogram_equalization
7+
"""
8+
9+
10+
def hist_equalization(image):
11+
"""
12+
Returns the histogram equalization image
13+
:param image: input image
14+
"""
15+
L, a, b = cv2.split(image)
16+
histogram = cv2.calcHist([L], [0], None, [256], [0, 256])
17+
histogram_sum = np.sum(histogram)
18+
probability_density_function = histogram / histogram_sum
19+
cumulative_distribution_function = np.cumsum(probability_density_function)
20+
lookup_table = np.round(cumulative_distribution_function * 255).astype(np.uint8)
21+
equalized_L = cv2.LUT(L, lookup_table)
22+
new_image = cv2.merge((equalized_L, a, b))
23+
new_image = cv2.cvtColor(new_image, cv2.COLOR_LAB2BGR)
24+
return new_image
25+
26+
27+
if __name__ == "__main__":
28+
image = cv2.imread("path_to_image")
29+
image = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)
30+
new_image = hist_equalization(image)
31+
cv2.imshow("image", new_image)
32+
cv2.waitKey(0)
33+
cv2.destroyAllWindows()

Diff for: data_structures/hashing/number_theory/prime_numbers.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ def is_prime(number: int) -> bool:
3232
"""
3333

3434
# precondition
35-
assert isinstance(number, int) and (number >= 0), (
36-
"'number' must been an int and positive"
37-
)
35+
assert isinstance(number, int) and (
36+
number >= 0
37+
), "'number' must been an int and positive"
3838

3939
if 1 < number < 4:
4040
# 2 and 3 are primes

Diff for: data_structures/heap/min_heap.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ def is_empty(self):
124124
return len(self.heap) == 0
125125

126126
def decrease_key(self, node, new_value):
127-
assert self.heap[self.idx_of_element[node]].val > new_value, (
128-
"newValue must be less that current value"
129-
)
127+
assert (
128+
self.heap[self.idx_of_element[node]].val > new_value
129+
), "newValue must be less that current value"
130130
node.val = new_value
131131
self.heap_dict[node.name] = new_value
132132
self.sift_up(self.idx_of_element[node])

Diff for: data_structures/kd_tree/tests/test_kdtree.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -48,14 +48,14 @@ def test_build_kdtree(num_points, cube_size, num_dimensions, depth, expected_res
4848
assert kdtree is not None, "Expected a KDNode, got None"
4949

5050
# Check if root has correct dimensions
51-
assert len(kdtree.point) == num_dimensions, (
52-
f"Expected point dimension {num_dimensions}, got {len(kdtree.point)}"
53-
)
51+
assert (
52+
len(kdtree.point) == num_dimensions
53+
), f"Expected point dimension {num_dimensions}, got {len(kdtree.point)}"
5454

5555
# Check that the tree is balanced to some extent (simplistic check)
56-
assert isinstance(kdtree, KDNode), (
57-
f"Expected KDNode instance, got {type(kdtree)}"
58-
)
56+
assert isinstance(
57+
kdtree, KDNode
58+
), f"Expected KDNode instance, got {type(kdtree)}"
5959

6060

6161
def test_nearest_neighbour_search():

Diff for: data_structures/suffix_tree/tests/test_suffix_tree.py

+12-12
Original file line numberDiff line numberDiff line change
@@ -22,37 +22,37 @@ def test_search_existing_patterns(self) -> None:
2222
patterns = ["ana", "ban", "na"]
2323
for pattern in patterns:
2424
with self.subTest(pattern=pattern):
25-
assert self.suffix_tree.search(pattern), (
26-
f"Pattern '{pattern}' should be found."
27-
)
25+
assert self.suffix_tree.search(
26+
pattern
27+
), f"Pattern '{pattern}' should be found."
2828

2929
def test_search_non_existing_patterns(self) -> None:
3030
"""Test searching for patterns that do not exist in the suffix tree."""
3131
patterns = ["xyz", "apple", "cat"]
3232
for pattern in patterns:
3333
with self.subTest(pattern=pattern):
34-
assert not self.suffix_tree.search(pattern), (
35-
f"Pattern '{pattern}' should not be found."
36-
)
34+
assert not self.suffix_tree.search(
35+
pattern
36+
), f"Pattern '{pattern}' should not be found."
3737

3838
def test_search_empty_pattern(self) -> None:
3939
"""Test searching for an empty pattern."""
4040
assert self.suffix_tree.search(""), "An empty pattern should be found."
4141

4242
def test_search_full_text(self) -> None:
4343
"""Test searching for the full text."""
44-
assert self.suffix_tree.search(self.text), (
45-
"The full text should be found in the suffix tree."
46-
)
44+
assert self.suffix_tree.search(
45+
self.text
46+
), "The full text should be found in the suffix tree."
4747

4848
def test_search_substrings(self) -> None:
4949
"""Test searching for substrings of the full text."""
5050
substrings = ["ban", "ana", "a", "na"]
5151
for substring in substrings:
5252
with self.subTest(substring=substring):
53-
assert self.suffix_tree.search(substring), (
54-
f"Substring '{substring}' should be found."
55-
)
53+
assert self.suffix_tree.search(
54+
substring
55+
), f"Substring '{substring}' should be found."
5656

5757

5858
if __name__ == "__main__":

Diff for: digital_image_processing/filters/gabor_filter.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ def gabor_filter_kernel(
4848
_y = -sin_theta * px + cos_theta * py
4949

5050
# fill kernel
51-
gabor[y, x] = np.exp(-(_x**2 + gamma**2 * _y**2) / (2 * sigma**2)) * np.cos(
52-
2 * np.pi * _x / lambd + psi
53-
)
51+
gabor[y, x] = np.exp(
52+
-(_x**2 + gamma**2 * _y**2) / (2 * sigma**2)
53+
) * np.cos(2 * np.pi * _x / lambd + psi)
5454

5555
return gabor
5656

Diff for: dynamic_programming/climbing_stairs.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@ def climb_stairs(number_of_steps: int) -> int:
2525
...
2626
AssertionError: number_of_steps needs to be positive integer, your input -7
2727
"""
28-
assert isinstance(number_of_steps, int) and number_of_steps > 0, (
29-
f"number_of_steps needs to be positive integer, your input {number_of_steps}"
30-
)
28+
assert (
29+
isinstance(number_of_steps, int) and number_of_steps > 0
30+
), f"number_of_steps needs to be positive integer, your input {number_of_steps}"
3131
if number_of_steps == 1:
3232
return 1
3333
previous, current = 1, 1

Diff for: dynamic_programming/iterating_through_submasks.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,9 @@ def list_of_submasks(mask: int) -> list[int]:
3737
3838
"""
3939

40-
assert isinstance(mask, int) and mask > 0, (
41-
f"mask needs to be positive integer, your input {mask}"
42-
)
40+
assert (
41+
isinstance(mask, int) and mask > 0
42+
), f"mask needs to be positive integer, your input {mask}"
4343

4444
"""
4545
first submask iterated will be mask itself then operation will be performed

Diff for: greedy_methods/fractional_knapsack.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ def frac_knapsack(vl, wt, w, n):
3939
return (
4040
0
4141
if k == 0
42-
else sum(vl[:k]) + (w - acc[k - 1]) * (vl[k]) / (wt[k])
43-
if k != n
44-
else sum(vl[:k])
42+
else (
43+
sum(vl[:k]) + (w - acc[k - 1]) * (vl[k]) / (wt[k])
44+
if k != n
45+
else sum(vl[:k])
46+
)
4547
)
4648

4749

Diff for: machine_learning/frequent_pattern_growth.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,9 @@ def ascend_tree(leaf_node: TreeNode, prefix_path: list[str]) -> None:
240240
ascend_tree(leaf_node.parent, prefix_path)
241241

242242

243-
def find_prefix_path(base_pat: frozenset, tree_node: TreeNode | None) -> dict: # noqa: ARG001
243+
def find_prefix_path(
244+
base_pat: frozenset, tree_node: TreeNode | None
245+
) -> dict: # noqa: ARG001
244246
"""
245247
Find the conditional pattern base for a given base pattern.
246248

Diff for: maths/numerical_analysis/integration_by_simpson_approx.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -88,18 +88,18 @@ def simpson_integration(function, a: float, b: float, precision: int = 4) -> flo
8888
AssertionError: precision should be positive integer your input : -1
8989
9090
"""
91-
assert callable(function), (
92-
f"the function(object) passed should be callable your input : {function}"
93-
)
91+
assert callable(
92+
function
93+
), f"the function(object) passed should be callable your input : {function}"
9494
assert isinstance(a, (float, int)), f"a should be float or integer your input : {a}"
9595
assert isinstance(function(a), (float, int)), (
9696
"the function should return integer or float return type of your function, "
9797
f"{type(a)}"
9898
)
9999
assert isinstance(b, (float, int)), f"b should be float or integer your input : {b}"
100-
assert isinstance(precision, int) and precision > 0, (
101-
f"precision should be positive integer your input : {precision}"
102-
)
100+
assert (
101+
isinstance(precision, int) and precision > 0
102+
), f"precision should be positive integer your input : {precision}"
103103

104104
# just applying the formula of simpson for approximate integration written in
105105
# mentioned article in first comment of this file and above this function

Diff for: maths/prime_check.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -73,12 +73,12 @@ def test_primes(self):
7373
def test_not_primes(self):
7474
with pytest.raises(ValueError):
7575
is_prime(-19)
76-
assert not is_prime(0), (
77-
"Zero doesn't have any positive factors, primes must have exactly two."
78-
)
79-
assert not is_prime(1), (
80-
"One only has 1 positive factor, primes must have exactly two."
81-
)
76+
assert not is_prime(
77+
0
78+
), "Zero doesn't have any positive factors, primes must have exactly two."
79+
assert not is_prime(
80+
1
81+
), "One only has 1 positive factor, primes must have exactly two."
8282
assert not is_prime(2 * 2)
8383
assert not is_prime(2 * 3)
8484
assert not is_prime(3 * 3)

Diff for: maths/primelib.py

+21-21
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,9 @@ def is_prime(number: int) -> bool:
6666
"""
6767

6868
# precondition
69-
assert isinstance(number, int) and (number >= 0), (
70-
"'number' must been an int and positive"
71-
)
69+
assert isinstance(number, int) and (
70+
number >= 0
71+
), "'number' must been an int and positive"
7272

7373
status = True
7474

@@ -254,9 +254,9 @@ def greatest_prime_factor(number):
254254
"""
255255

256256
# precondition
257-
assert isinstance(number, int) and (number >= 0), (
258-
"'number' must been an int and >= 0"
259-
)
257+
assert isinstance(number, int) and (
258+
number >= 0
259+
), "'number' must been an int and >= 0"
260260

261261
ans = 0
262262

@@ -296,9 +296,9 @@ def smallest_prime_factor(number):
296296
"""
297297

298298
# precondition
299-
assert isinstance(number, int) and (number >= 0), (
300-
"'number' must been an int and >= 0"
301-
)
299+
assert isinstance(number, int) and (
300+
number >= 0
301+
), "'number' must been an int and >= 0"
302302

303303
ans = 0
304304

@@ -399,9 +399,9 @@ def goldbach(number):
399399
"""
400400

401401
# precondition
402-
assert isinstance(number, int) and (number > 2) and is_even(number), (
403-
"'number' must been an int, even and > 2"
404-
)
402+
assert (
403+
isinstance(number, int) and (number > 2) and is_even(number)
404+
), "'number' must been an int, even and > 2"
405405

406406
ans = [] # this list will returned
407407

@@ -525,9 +525,9 @@ def kg_v(number1, number2):
525525
done.append(n)
526526

527527
# precondition
528-
assert isinstance(ans, int) and (ans >= 0), (
529-
"'ans' must been from type int and positive"
530-
)
528+
assert isinstance(ans, int) and (
529+
ans >= 0
530+
), "'ans' must been from type int and positive"
531531

532532
return ans
533533

@@ -574,9 +574,9 @@ def get_prime(n):
574574
ans += 1
575575

576576
# precondition
577-
assert isinstance(ans, int) and is_prime(ans), (
578-
"'ans' must been a prime number and from type int"
579-
)
577+
assert isinstance(ans, int) and is_prime(
578+
ans
579+
), "'ans' must been a prime number and from type int"
580580

581581
return ans
582582

@@ -705,9 +705,9 @@ def is_perfect_number(number):
705705
"""
706706

707707
# precondition
708-
assert isinstance(number, int) and (number > 1), (
709-
"'number' must been an int and >= 1"
710-
)
708+
assert isinstance(number, int) and (
709+
number > 1
710+
), "'number' must been an int and >= 1"
711711

712712
divisors = get_divisors(number)
713713

Diff for: matrix/matrix_class.py

+5-3
Original file line numberDiff line numberDiff line change
@@ -204,9 +204,11 @@ def cofactors(self) -> Matrix:
204204
return Matrix(
205205
[
206206
[
207-
self.minors().rows[row][column]
208-
if (row + column) % 2 == 0
209-
else self.minors().rows[row][column] * -1
207+
(
208+
self.minors().rows[row][column]
209+
if (row + column) % 2 == 0
210+
else self.minors().rows[row][column] * -1
211+
)
210212
for column in range(self.minors().num_columns)
211213
]
212214
for row in range(self.minors().num_rows)

Diff for: neural_network/input_data.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -160,9 +160,9 @@ def __init__(
160160
self._num_examples = 10000
161161
self.one_hot = one_hot
162162
else:
163-
assert images.shape[0] == labels.shape[0], (
164-
f"images.shape: {images.shape} labels.shape: {labels.shape}"
165-
)
163+
assert (
164+
images.shape[0] == labels.shape[0]
165+
), f"images.shape: {images.shape} labels.shape: {labels.shape}"
166166
self._num_examples = images.shape[0]
167167

168168
# Convert shape from [num examples, rows, columns, depth]

Diff for: scripts/validate_solutions.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,6 @@ def test_project_euler(solution_path: pathlib.Path) -> None:
9494
solution_module = convert_path_to_module(solution_path)
9595
answer = str(solution_module.solution())
9696
answer = hashlib.sha256(answer.encode()).hexdigest()
97-
assert answer == expected, (
98-
f"Expected solution to {problem_number} to have hash {expected}, got {answer}"
99-
)
97+
assert (
98+
answer == expected
99+
), f"Expected solution to {problem_number} to have hash {expected}, got {answer}"

Diff for: sorts/bead_sort.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ def bead_sort(sequence: list) -> list:
3131
if any(not isinstance(x, int) or x < 0 for x in sequence):
3232
raise TypeError("Sequence must be list of non-negative integers")
3333
for _ in range(len(sequence)):
34-
for i, (rod_upper, rod_lower) in enumerate(zip(sequence, sequence[1:])): # noqa: RUF007
34+
for i, (rod_upper, rod_lower) in enumerate(
35+
zip(sequence, sequence[1:])
36+
): # noqa: RUF007
3537
if rod_upper > rod_lower:
3638
sequence[i] -= rod_upper - rod_lower
3739
sequence[i + 1] += rod_upper - rod_lower

0 commit comments

Comments
 (0)