Skip to content

Commit cd37879

Browse files
authored
Merge pull request #3 from ErickOF/feature-datagen_salt_and_pepper_noise
The datagen tool add salt and pepper noise to grayscale image
2 parents 643888e + aa3c810 commit cd37879

File tree

4 files changed

+138
-49
lines changed

4 files changed

+138
-49
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,4 +221,5 @@ pyrightconfig.json
221221

222222
# Ignore generate images from datagen tool
223223
tools/datagen/src/imgs/*_grayscale_image*
224+
tools/datagen/src/imgs/*_noisy_image*
224225
tools/datagen/src/imgs/*_sobel_*

tools/datagen/README.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,25 @@ There are two versions of the script, a JupyterNotebook and a normal Python
2222
script. For both of them, in the main function, the variables `img_name` and
2323
`img_ext` must be updated. The `img_name` is only the name of the image that
2424
is saved in `tools/datagen/src/imgs` and the `img_ext` is the extension of the
25-
image. For instance:
25+
image. The `salt_probability` is used to set the probability of getting a salt
26+
pixel in the image, while `pepper_probability` is used for the pepper pixels.
27+
These two variables can be set to 0.0 to generate an image without noise. For
28+
instance:
2629

2730
```python
31+
salt_probability: float = 0.1
32+
salt_probability: float = 0.1
2833
img_name: str = 'car'
2934
img_ext: str = 'jpg
3035
```
3136

3237
will load `tools/datagen/src/imgs/car.jpg` image and generate:
3338

3439
* tools/datagen/src/imgs/car\_grayscale\_image.jpg
35-
* tools/datagen/src/imgs/car\_sobel\_combined\_result.jpg
40+
* tools/datagen/src/imgs/car\_noisy\_image.jpg
3641
* tools/datagen/src/imgs/car\_sobel\_x\_result.jpg
3742
* tools/datagen/src/imgs/car\_sobel\_y\_result.jpg
43+
* tools/datagen/src/imgs/car\_sobel\_combined\_result.jpg
3844

3945
These generated images are ignored and must not be committed to the repository.
4046

tools/datagen/datagen.ipynb

Lines changed: 68 additions & 30 deletions
Large diffs are not rendered by default.

tools/datagen/datagen.py

Lines changed: 61 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,56 @@
22
"""
33
Script to generate the data required for SystemC testbench.
44
"""
5-
from typing import Tuple
5+
from typing import List, Tuple
66

77
import cv2
88
import numpy as np
99
import matplotlib.pyplot as plt
1010

1111

12-
def apply_sobel_filter(image_path: str
12+
def apply_sobel_filter(
13+
image_path: str,
14+
salt_prob: float = 0.0,
15+
pepper_prob: float = 0.0,
1316
)-> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]:
1417
"""Applies the Sobel filter in X and Y to a input image and returns each
1518
step.
1619
1720
Args:
1821
image_path (str): Path to the input image
22+
salt_prob (float): Probability of changing a pixel to salt. Value from
23+
0.0 to 1.0. Defaults to 0.0.
24+
pepper_prob (float): Probability of changing a pixel to pepper. Value
25+
from 0.0 to 1.0. Defaults to 0.0.
1926
2027
Returns:
21-
Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: A tuple
22-
containing the gray image, the sobel in x, the sobel in y, and the
23-
sobel combining x and y.
28+
Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray, np.ndarray]: A
29+
tuple containing the grayscale image, the grayscale image with salt
30+
and pepper noise, the sobel in x, the sobel in y, and the sobel
31+
combining x and y.
2432
"""
2533
# Read the image
2634
image: np.ndarray = cv2.imread(image_path)
2735

2836
# BGR to grayscale
2937
gray_img: np.ndarray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
3038

39+
# Noisy image
40+
noisy_img: np.ndarray = np.copy(gray_img)
41+
42+
salt_num: int = int(np.ceil(salt_prob * noisy_img.size))
43+
pepper_num: int = int(np.ceil(pepper_prob * noisy_img.size))
44+
45+
salt_coords: List[np.ndarray] = [
46+
np.random.randint(0, i, salt_num) for i in image.shape
47+
]
48+
pepper_coords: List[np.ndarray] = [
49+
np.random.randint(0, i, pepper_num) for i in image.shape
50+
]
51+
52+
noisy_img[salt_coords[0], salt_coords[1]] = 255
53+
noisy_img[pepper_coords[0], pepper_coords[1]] = 0
54+
3155
# Apply Sobel in x direction
3256
sobel_x_img: np.ndarray = cv2.Sobel(gray_img, cv2.CV_64F, 1, 0, ksize=3)
3357
sobel_x_uint8: np.ndarray = np.uint8(np.absolute(sobel_x_img))
@@ -40,49 +64,69 @@ def apply_sobel_filter(image_path: str
4064
sobel_combined_img: np.ndarray = cv2.magnitude(sobel_x_img, sobel_y_img)
4165

4266
# Convert to 8-bit image
43-
sobel_combined_uint8: np.ndarray = np.uint8(np.absolute(sobel_combined_img))
67+
sobel_combined_uint8: np.ndarray = np.uint8(
68+
np.absolute(sobel_combined_img)
69+
)
4470

4571
# Display the results
4672
plt.figure(figsize=(10, 8))
4773

48-
plt.subplot(2, 2, 1)
74+
plt.subplot(2, 3, 1)
4975
plt.title('Original Image')
5076
plt.imshow(cv2.cvtColor(image, cv2.COLOR_BGR2RGB))
5177
plt.axis('off')
5278

53-
plt.subplot(2, 2, 2)
79+
plt.subplot(2, 3, 2)
5480
plt.title('Grayscale Image')
5581
plt.imshow(gray_img, cmap='gray')
5682
plt.axis('off')
5783

58-
plt.subplot(2, 2, 3)
84+
plt.subplot(2, 3, 3)
85+
plt.title('Noisy Image')
86+
plt.imshow(noisy_img, cmap='gray')
87+
plt.axis('off')
88+
89+
plt.subplot(2, 3, 4)
5990
plt.title('Sobel X')
6091
plt.imshow(np.uint8(np.absolute(sobel_x_img)), cmap='gray')
6192
plt.axis('off')
6293

63-
plt.subplot(2, 2, 4)
94+
plt.subplot(2, 3, 5)
6495
plt.title('Sobel Y')
6596
plt.imshow(np.uint8(np.absolute(sobel_y_img)), cmap='gray')
6697
plt.axis('off')
6798

68-
plt.figure(figsize=(5, 5))
99+
plt.subplot(2, 3, 6)
69100
plt.title('Sobel Combined')
70101
plt.imshow(sobel_combined_uint8, cmap='gray')
71102
plt.axis('off')
72103

73104
plt.show()
74105

75-
return (gray_img, sobel_x_uint8, sobel_y_uint8, sobel_combined_uint8)
106+
return (gray_img, noisy_img, sobel_x_uint8, sobel_y_uint8,
107+
sobel_combined_uint8)
76108

77109

78110
if __name__ == '__main__':
111+
salt_probability: float = 0.1
112+
pepper_probability: float = 0.1
79113
img_name: str = 'car'
80114
img_ext: str = 'jpg'
81115
img_path: str = f'src/imgs/{img_name}.{img_ext}'
82-
gray, sobel_x, sobel_y, sobel_combined = apply_sobel_filter(img_path)
116+
gray, noisy, sobel_x, sobel_y, sobel_combined = \
117+
apply_sobel_filter(img_path, salt_probability, pepper_probability)
83118

84119
cv2.imwrite(f'src/imgs/{img_name}_grayscale_image.{img_ext}', gray)
85-
cv2.imwrite(f'src/imgs/{img_name}_sobel_x_result.{img_ext}', np.uint8(np.absolute(sobel_x)))
86-
cv2.imwrite(f'src/imgs/{img_name}_sobel_y_result.{img_ext}', np.uint8(np.absolute(sobel_y)))
87-
cv2.imwrite(f'src/imgs/{img_name}_sobel_combined_result.{img_ext}', sobel_combined)
88-
120+
cv2.imwrite(f'src/imgs/{img_name}_noisy_image.{img_ext}', noisy)
121+
cv2.imwrite(
122+
f'src/imgs/{img_name}_sobel_x_result.{img_ext}',
123+
np.uint8(np.absolute(sobel_x))
124+
)
125+
cv2.imwrite(
126+
f'src/imgs/{img_name}_sobel_y_result.{img_ext}',
127+
np.uint8(np.absolute(sobel_y))
128+
)
129+
cv2.imwrite(
130+
f'src/imgs/{img_name}_sobel_combined_result.{img_ext}',
131+
sobel_combined
132+
)

0 commit comments

Comments
 (0)