-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathip.py
More file actions
178 lines (151 loc) · 5.77 KB
/
ip.py
File metadata and controls
178 lines (151 loc) · 5.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# 这里定义图像处理函数,以便调用
# Generated on: Jul 1, 2025
# Author: Mao Hongyu
import cv2
import numpy as np
import skimage as sk
def blur(f: str, k: int=9) -> np.uint8:
"""
图像模糊,具体用来模糊或去噪的功能可通过调整k来区分
输入参数:
f: 文件名
k: 卷积核大小,必须是大于1的奇数,默认是9
返回:
8位灰度图像
"""
if k % 2 == 0 or k <= 1:
raise ValueError("Ksize must be odd and above 1!")
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
if img is None:
raise ValueError("Image not Found!")
img = cv2.medianBlur(img, k) # 选用中值滤波,非线性滤波的去噪和模糊效果更好
cv2.imwrite('blur.jpg', img)
return img
def remove_noise(f: str, k: int=5) -> np.uint8:
"""
图像去噪,具体用来模糊或去噪的功能可通过调整k来区分
输入参数:
f: 文件名
k: 卷积核大小,必须是大于1的奇数,默认是5
返回:
8位灰度图像
"""
if k % 2 == 0 or k <= 1:
raise ValueError("Ksize must be odd and above 1!")
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
if img is None:
raise ValueError("Image not Found!")
img = cv2.medianBlur(img, k) # 选用中值滤波,非线性滤波的去噪和模糊效果更好
cv2.imwrite("remove_noise.jpg", img)
return img
def add_noise(f: str, a: float=.02) -> np.uint8:
"""
给图像添加噪声,此处选用椒盐噪声
输入参数:
f: 文件名
a: 椒盐噪声添加比例,取值0到1之间,默认值0.02,可选
返回:
8位灰度图像
"""
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
assert img is not None, "Image not Found!"
img = sk.util.random_noise(img, mode='s&p', amount=a)
img = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX).astype(np.uint8) # 归一化转为8位无符号整数
cv2.imwrite("add_noise.jpg", img)
return img
def sharpen(f: str, k: int=3) -> np.uint8:
"""
边缘检测,选用Laplace算子
输入参数:
f: 文件名
k: 卷积核大小,必须是大于1的奇数,默认是3
返回:
8位灰度图像
"""
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
assert img is not None, "Image not Found!"
img = cv2.Laplacian(img, cv2.CV_64F, k)
img = cv2.normalize(img, None, 0, 255, cv2.NORM_MINMAX) # 将结果标准化到0到255,因为Laplace算子会产生负值或超出255的值
img = cv2.convertScaleAbs(img) # 转为8位无符号整数
cv2.imwrite("sharpen.jpg", img)
return img
def frequency(f: str) -> np.uint8:
"""
显示图像的频域分析结果,使用傅里叶变换
输入参数:
f: 文件名
返回:
8位灰度图像频域
"""
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
assert img is not None, "Image not Found!"
ft = cv2.dft(img.astype(np.float32), flags=cv2.DFT_COMPLEX_OUTPUT)
fts = np.fft.fftshift(ft)
s = cv2.magnitude(fts[:, :, 0], fts[:, :, 1])
s = cv2.normalize(s, None, 0, 255, norm_type=cv2.NORM_MINMAX)
s = s.astype(np.uint8)
s *= 255
cv2.imwrite("frequency.jpg", s)
return s
def binary(f: str) -> np.uint8:
"""
将灰度图像转为二值图像
输入参数:
f: 文件名
返回值:
8位二值图像
"""
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
assert img is not None, "Image not Found!"
cv2.imwrite("binary.jpg", cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1])
return cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)[1]
def reverse(f: str) -> np.uint8:
"""
取负片图像,黑的变白,白的变黑,等效imadjust中old=[0, 1], new[1, 0]的情况
输入参数:
f: 文件名
返回值:
8位灰度图像
"""
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
assert img is not None, "Image not Found!"
cv2.imwrite("reverse.jpg", (255 - img).astype(np.uint8))
return (255 - img).astype(np.uint8)
# 自己定义一个imadjust,OpenCV和skimage中没找到类似的
def imadjust(img: np.uint8, old: list[int] = [0, 1], new: list[int] = [0, 1]) -> np.uint8:
"""
用法和功能跟MATLAB的imadjust函数一样,调整图像的灰度范围,默认值是[0, 1],即图像不变。
参数:
img: 输入图像 (np.ndarray, uint8)
old: 原范围
new: 新范围
返回:
调整后的图像 (np.ndarray, uint8)
"""
img_float = img.astype(np.float32) / 255.0
if old[1] - old[0] != 0:
mapped_img = np.where((img_float >= old[0]) & (img_float <= old[1]),
new[0] + (img_float - old[0]) * (new[1] - new[0]) / (old[1] - old[0]), img_float)
mapped_img = np.clip(mapped_img, 0, 1) # 裁剪到0至1范围内
return (mapped_img * 255).astype(np.uint8)
else:
return img
def cvshow(winname: str, img: np.uint8) -> None:
"""
调试用,OpenCV的图窗显示较为复杂,懒得每次都写,就封装为一个函数
输入参数:
winname: 窗口名称
img: cv2处理好后要显示的图像
"""
cv2.namedWindow(winname, cv2.WINDOW_NORMAL)
cv2.resizeWindow(winname, img.shape[1], img.shape[0])
cv2.imshow(winname, img)
cv2.waitKey(0)
if __name__ == '__main__':
# 在这里不走用户界面,单测试图像处理各函数功能
f = "catl.jpg"
img = cv2.imread(f, cv2.IMREAD_GRAYSCALE)
img = imadjust(img, [0, 1], [1, 0])
# cv2.imwrite("catp.jpg", img)
cvshow("Picture", img)
print(img.dtype)