数字图像处理学习记录
图像基础
图片表示
二值图
只有2种取值
灰度图
unit8
8位灰度图(0~255)
二维矩阵(一个通道)
彩色图
三维矩阵(RGB三个通道)
真彩色
通道的分离和合并
img_bgr = cv.imread(img_path)
# 通道分离
b, g, r = cv.split(img_bgr)
# 通道合并
img_rgb = cv.merge([r, g, b])
彩色图转换成灰度图
# 三通道按权值加权 0.299 0.587 0.114
gray1 = 0.299 * r + 0.587 *g + 0.114 *b
# dtype = uint8
gray2 = np.uint8(gray1)
gray3 = gray1.astype(np.uint8)
gray4 = cv.cvtColor(img_bgr, cv.COLOR_BGR2GRAY)
图像二值化
thresh = 125
gray4[gray4 > thresh] = 255
gray4[gray4 <= thresh] = 0
# gray4 已经被二值化
ignore, img_bin = cv.threshold(gray_uint8_img, th1, th2, cv.THRESH_BINARY)
图像运算
图像相加
混合图像、添加噪声
# dtype = float64
img_add1 = cv.add(img1*0.5, img2*0.5)
# dtype = uint8
img_add2 = cv.addWeighted(img1, alpha, img2, beta, gamma)
图像相减
消除背景、差影法(比较差异,运动跟踪)
img_sub = cv.subtract(img1, img2)
图像相乘
掩膜mask
img = cv.multiply(img1, img2)
图像相除
校正设备、比较差异
img = cv.divide(img1, img2)
图像变换

线性变换
\[s=b+kr
\]
img = cv.convertScaleAbs(img, alpha=1, beta=0)
非线性变换
\[s=a+\frac{ln(r+1)}{blnc}
\]
Gamma变换
\[s=cr^y
\]
y越大图像越亮

img = img / 255
img = np.power(img, y) * 255
图像处理
裁剪
# numpy
img = cv.imread(img_path)
# h * w * c
# y * x *c
img = img[20:100, 100:200, :]
放缩
# OpenCv
# (x, y)=(w, h)=(500,400)
img = cv.resize(img, (500, 400))
平移

仿射变换
# 坐标的映射矩阵M
M = np.array([...], dtype=np.float32)
cv.warpAffine(img, M, dsize)
错切变换

M = np.array([...], dtype=np.float32)
img = cv.warpAffine(img, M, dsize)
镜像变换

# 矩阵
M = np.array([...], dtype=np.float32)
img = cv.warpAffine(img, M, dsize)
# 垂直镜像
cv.flip(img, 0)
# 水平镜像
cv.flip(img, 1)
# 同时进行
cv.flit(img, -1)
旋转变换

# 旋转矩阵
M = np.array([...], dtype=np.float32)
img = cv.warpAffine(img, M, dsize)
# M = cv.getRotationMatrix2D(center, angle, scale)
h, w, c = img.shape
# center = (x, y)
M = cv.getRotationMatrix2D((w//2, h//2), 45)
img = cv.warpAffine(img, M, dsize)
# 顺时针逆时针旋转90°
img_rotate = cv.rotate(img, cv.ROTATE_90_CLOCKWISE)
透视变换
M = cv.getPerspectiveTransform(src, dst)
img = cv.warpPerspective(img, M, dsize)
小总结

像素值没变,像素位置变了。
所以实际上计算了一个坐标变换的矩阵M。
#### 最近邻插值
逆向思维:小图插值变大图 ---> 大图变小图

img1 = cv.resize(img, dsize, interpolation=cv.INTER_NEAREST)
双线性插值
考虑邻近的像素点,按照权值计算。
img1 = cv.resize(img, dsize, interpolation=cv.INTER_LINEAR_EXACT)
图像模糊
卷积
img = cv.filter2D(img, -1, kernel)
均值模糊
cv.blur(img, (5,5))
cv.boxFilter(img, -1, (5,5))
中值滤波
cv.medianBlur(img, 3) # 奇数
高斯模糊

# sigma 方差
# 方差小则copy原图
# 方差大则和均值滤波差不多
cv.GaussianBlur(img, (5,5), sigmaX)
双边滤波
一般模糊会丢失边缘信息,而双边滤波可以保留边缘高频信息,平滑颜色相近的地方。
需要一直更新卷积核的值:
1.距离越远,加权值越小
2.颜色差异越大,加权值越小
缺点:对高频噪声无滤波效果
cv.bilateralFilter(img, -1, sigmaColor=50, sigmaSpace=3)

图像边缘
...

浙公网安备 33010602011771号