Skip to content

Commit df94c42

Browse files
Merge branch 'master' into add-clear-least-significant-set-bit
2 parents ab41f02 + 945b5ab commit df94c42

13 files changed

Lines changed: 108 additions & 31 deletions

File tree

computer_vision/README.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
# Computer Vision
22

3-
Computer vision is a field of computer science that works on enabling computers to see, identify and process images in the same way that human does, and provide appropriate output.
3+
Computer vision is an interdisciplinary field focused on enabling computers to gain high-level understanding from images and video—automatically extracting, analyzing, and interpreting visual information to produce outputs such as labels, measurements, 3D structure, or decisions.
44

5-
It is like imparting human intelligence and instincts to a computer.
6-
Image processing and computer vision are a little different from each other. Image processing means applying some algorithms for transforming image from one form to the other like smoothing, contrasting, stretching, etc.
5+
In practice, computer vision methods combine geometry, physics, statistics, and machine learning to connect pixel data to semantic concepts like objects, actions, and scenes.
76

8-
While computer vision comes from modelling image processing using the techniques of machine learning, computer vision applies machine learning to recognize patterns for interpretation of images (much like the process of visual reasoning of human vision).
7+
## Image processing vs. computer vision
98

10-
* <https://en.wikipedia.org/wiki/Computer_vision>
9+
Image processing primarily transforms images (e.g., denoising, contrast enhancement, geometric warping) where the output is another image.
10+
11+
Computer vision uses images/video as input but often outputs information about the scene (e.g., detections, segmentation masks, pose estimates, tracking results, or a decision), which may then drive downstream behavior in a larger system.

computer_vision/cnn_classification.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,6 @@
9494
test_image = np.expand_dims(test_image, axis=0)
9595
result = classifier.predict(test_image)
9696
# training_set.class_indices
97-
if result[0][0] == 0:
98-
prediction = "Normal"
99-
if result[0][0] == 1:
100-
prediction = "Abnormality detected"
97+
# The sigmoid output is a probability in the range [0, 1].
98+
# Use a threshold of 0.5 to convert the probability into a binary prediction.
99+
prediction = "Normal" if result[0][0] < 0.5 else "Abnormality detected"

computer_vision/otsu_threshold.py

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import numpy as np
2+
from PIL import Image
3+
4+
"""
5+
Otsu thresholding algorithm for image processing
6+
https://en.wikipedia.org/wiki/Otsu%27s_method
7+
"""
8+
9+
10+
def otsu_threshold(image: Image) -> Image:
11+
"""
12+
Applies Otsu's thresholding method to a grayscale image.
13+
14+
Parameters:
15+
image (PIL.Image.Image): A grayscale PIL image object.
16+
17+
Returns:
18+
PIL.Image.Image: A binary image after applying Otsu's thresholding.
19+
20+
Example:
21+
>>> from PIL import Image
22+
>>> import numpy as np
23+
>>> image_array = np.array(
24+
... [[0, 0, 0, 0], [255, 255, 255, 255], [0, 0, 0, 0], [255, 255, 255, 255]],
25+
... dtype=np.uint8
26+
... )
27+
>>> image = Image.fromarray(image_array)
28+
>>> binary_image = otsu_threshold(image)
29+
>>> np.array(binary_image)
30+
array([[ 0, 0, 0, 0],
31+
[255, 255, 255, 255],
32+
[ 0, 0, 0, 0],
33+
[255, 255, 255, 255]], dtype=uint8)
34+
"""
35+
# Convert the image to numpy array
36+
pixel_array = np.array(image)
37+
38+
# Compute histogram
39+
hist, _ = np.histogram(pixel_array, bins=256, range=(0, 256))
40+
41+
# Compute between class variance
42+
total_pixels = pixel_array.size
43+
current_max, threshold = 0.0, 0 # Ensure current_max is a float
44+
sum_total, sum_foreground = 0.0, 0.0 # Ensure these are floats
45+
weight_background, weight_foreground = 0.0, 0.0 # Ensure these are floats
46+
47+
for i in range(256):
48+
sum_total += i * hist[i]
49+
50+
for i in range(256):
51+
weight_background += hist[i]
52+
if weight_background == 0:
53+
continue
54+
weight_foreground = total_pixels - weight_background
55+
if weight_foreground == 0:
56+
break
57+
sum_foreground += i * hist[i]
58+
59+
mean_background = sum_foreground / weight_background
60+
mean_foreground = (sum_total - sum_foreground) / weight_foreground
61+
62+
between_class_variance = (
63+
weight_background
64+
* weight_foreground
65+
* (mean_background - mean_foreground) ** 2
66+
)
67+
68+
if between_class_variance > current_max:
69+
current_max = between_class_variance
70+
threshold = i
71+
72+
# Apply threshold to the image
73+
binary_image = pixel_array > threshold
74+
binary_image = binary_image.astype(np.uint8) * 255
75+
76+
# Convert numpy array back to PIL image
77+
return Image.fromarray(binary_image)

data_structures/binary_tree/segment_tree.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ def __init__(self, a) -> None:
1111
if self.N:
1212
self.build(1, 0, self.N - 1)
1313

14-
def left(self, idx):
14+
def left(self, idx) -> int:
1515
"""
1616
Returns the left child index for a given index in a binary tree.
1717
@@ -23,7 +23,7 @@ def left(self, idx):
2323
"""
2424
return idx * 2
2525

26-
def right(self, idx):
26+
def right(self, idx) -> int:
2727
"""
2828
Returns the right child index for a given index in a binary tree.
2929
@@ -44,7 +44,7 @@ def build(self, idx, left, right) -> None:
4444
self.build(self.right(idx), mid + 1, right)
4545
self.st[idx] = max(self.st[self.left(idx)], self.st[self.right(idx)])
4646

47-
def update(self, a, b, val):
47+
def update(self, a, b, val) -> bool:
4848
"""
4949
Update the values in the segment tree in the range [a,b] with the given value.
5050
@@ -71,7 +71,7 @@ def update_recursive(self, idx, left, right, a, b, val) -> bool:
7171
self.st[idx] = max(self.st[self.left(idx)], self.st[self.right(idx)])
7272
return True
7373

74-
def query(self, a, b):
74+
def query(self, a, b) -> float:
7575
"""
7676
Query the maximum value in the range [a,b].
7777
@@ -83,7 +83,7 @@ def query(self, a, b):
8383
"""
8484
return self.query_recursive(1, 0, self.N - 1, a - 1, b - 1)
8585

86-
def query_recursive(self, idx, left, right, a, b):
86+
def query_recursive(self, idx, left, right, a, b) -> float:
8787
"""
8888
query(1, 1, N, a, b) for query max of [a,b]
8989
"""

data_structures/hashing/hash_table.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ def __init__(
2222
self.__aux_list: list = []
2323
self._keys: dict = {}
2424

25-
def keys(self):
25+
def keys(self) -> dict:
2626
"""
2727
The keys function returns a dictionary containing the key value pairs.
2828
key being the index number in hash table and value being the data value.
@@ -48,12 +48,12 @@ def keys(self):
4848
"""
4949
return self._keys
5050

51-
def balanced_factor(self):
51+
def balanced_factor(self) -> float:
5252
return sum(1 for slot in self.values if slot is not None) / (
5353
self.size_table * self.charge_factor
5454
)
5555

56-
def hash_function(self, key):
56+
def hash_function(self, key) -> int:
5757
"""
5858
Generates hash for the given key value
5959

data_structures/hashing/hash_table_with_linked_list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def _set_value(self, key, data) -> None:
1212
self.values[key].appendleft(data)
1313
self._keys[key] = self.values[key]
1414

15-
def balanced_factor(self):
15+
def balanced_factor(self) -> float:
1616
return (
1717
sum(self.charge_factor - len(slot) for slot in self.values)
1818
/ self.size_table

data_structures/heap/binomial_heap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -251,7 +251,7 @@ def peek(self):
251251
"""
252252
return self.min_node.val
253253

254-
def is_empty(self):
254+
def is_empty(self) -> bool:
255255
return self.size == 0
256256

257257
def delete_min(self):

data_structures/heap/max_heap.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ def pop(self) -> int:
6060
return max_value
6161

6262
@property
63-
def get_list(self):
63+
def get_list(self) -> list:
6464
return self.__heap[1:]
6565

6666
def __len__(self) -> int:

data_structures/heap/min_heap.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ def __init__(self, array) -> None:
3939
def __getitem__(self, key):
4040
return self.get_value(key)
4141

42-
def get_parent_idx(self, idx):
42+
def get_parent_idx(self, idx) -> int:
4343
return (idx - 1) // 2
4444

45-
def get_left_child_idx(self, idx):
45+
def get_left_child_idx(self, idx) -> int:
4646
return idx * 2 + 1
4747

48-
def get_right_child_idx(self, idx):
48+
def get_right_child_idx(self, idx) -> int:
4949
return idx * 2 + 2
5050

5151
def get_value(self, key):
5252
return self.heap_dict[key]
5353

54-
def build_heap(self, array):
54+
def build_heap(self, array) -> list:
5555
last_idx = len(array) - 1
5656
start_from = self.get_parent_idx(last_idx)
5757

@@ -120,7 +120,7 @@ def insert(self, node) -> None:
120120
self.heap_dict[node.name] = node.val
121121
self.sift_up(len(self.heap) - 1)
122122

123-
def is_empty(self):
123+
def is_empty(self) -> bool:
124124
return len(self.heap) == 0
125125

126126
def decrease_key(self, node, new_value) -> None:

data_structures/linked_list/doubly_linked_list.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ def delete(self, data) -> str:
196196
current.next.previous = current.previous # 1 <--> 3
197197
return data
198198

199-
def is_empty(self):
199+
def is_empty(self) -> bool:
200200
"""
201201
>>> linked_list = DoublyLinkedList()
202202
>>> linked_list.is_empty()

0 commit comments

Comments
 (0)