滤波和卷积
图像阈值处理
原始图像
其中 红色线为阈值
二进制阈值化
小于阈值的——0
大于阈值的——255
反二进制阈值化
小于阈值的——255
大于阈值的——0
截断阈值化
小于阈值的——本身
大于阈值的——取阈值
反阈值化为0
小于阈值的——本身
大于等于阈值的——0
阈值化为0
小于阈值的——0
大于等于阈值的——本身
实现:threshold
retval, dst = cv2.threshold(src, thresh, maxval, type)
retval
:阈值dst
:处理结果src
:源图像threshold
:阈值maxval
:最大值,例如:1、255type
:类型cv2.THRESH_BINARY
- 二进制阈值化
- 不一定是0和1,也可以是其他两个值
cv2.THRESH_BINARY_INV
- 反二进制阈值化
cv2.THRESH_TRUNC
- 截断阈值化
cv2.THRESH_TOZERO_INV
- 反阈值化为0
cv2.THRESH_TOZERO
- 阈值化为0
图像平滑处理
均值滤波
- 任意一点的像素,都是周围N*N个像素值的均值
- 函数
blur
处理结果 = cv2.blur(原始图像, 核心大小)
- 核大小:以(宽度,高度)形式表示的元组
- 例:
r = cv2.blur(o, (5,5))
方框滤波
- 函数
boxFilter
处理结果 = cv2.boxFilter(原始图像, 目标图像深度, 核大小, normalize属性)
- 目标图像深度:int类型的目标图像深度。通常使用“-1”表示与原始图像一致
- 核大小:以(宽度,高度)形式表示的元组
- normalize属性:是否对目标图像进行归一化处理
- 例:
r=cv2.boxFilter(o, -1, (5,5), normalize=1)
- 注意:不进行归一化,可能会溢出,(全白)
高斯滤波
- 让临近的像素具有更高的重要度。对周围像素计算加权平均值,较近的像素具有较大的权重值
- 函数
GaussianBlur
函数dst = cv2.GaussianBlur(src, ksize, sigmaX)
src
:原始图形ksiez
:核大小(N,N)(必须是奇数)sigmaX
:X方向方差,控制权重
- 例:
r=cv2.GaussianBlur(o, (3,3), 0)
中值滤波
- 让临近的像素按照大小排列,取排序像素集中位于中间位置的值作为中值滤波后的像素值
- 函数
medianBlur
dst = cv2.medianBlur(src, ksize)
src
:源文件ksize
:核大小(必须是比1大的奇数,如3、5、7等)
- 例:
r = cv2.medianBlur(o, 3)
图像梯度
sobel算子
- 水平方向梯度
- 垂直方向边界
- 两个方向的梯度计算
- 函数:
dst = cv2.Sobel(src, ddepth, dx, dy, [ksize])
dst
:计算结果src
:原始图像ddepth
:处理结果图像深度- 通常情况下,可以将该参数的值设置为-1,让处理结果与原始图像保持一致
- 实际操作中,计算梯度值可能会出现负数。通常处理的图像是
np.uint8
类型,如果结果也是该类型,所有负数会自动横断为0,发生信息丢失。所以,通常计算时,使用更高的数据类型cv2.CV_64F
,取绝对值后,再转换为np.uint8(cv2.CV_8U)
类型 dst = cv2.convertScaleAbs(src[, alpha[, beta]])
- 作用:将原始图像
src
转换为256色位图 - 例:
目标图像 = cv2.convertScaleAbs(原始图像)
- 作用:将原始图像
dx
:x轴方向dy
:y轴方向- 计算x方向梯度:【
dx=1, dy=0
】 - 计算y方向梯度:【
dx=0, dy=1
】 - 两个方向梯度:推荐方式2
- 函数
dst = cv2.addWeighted(src1, alpha, src2, beta, gamma)
- 功能:计算两幅图像的权重和
dst
:计算结果src1
:源图像1alpha
:源图像1的系数src2
:源图像2beta
:源图像2的系数gamma
:修正值- 关系
- 例:
dst = cv2.addWeighted(src1, 0.5, src2, 0.5, 0)
- 函数
- 计算x方向梯度:【
ksize
:核大小
- 操作
import cv2
import numpy as np
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
sobelx = cv2.Sobel(o, cv2.CV_64F, 1, 0)
sobely = cv2.Sobel(o, cv2.CV_64F, 0, 1)
sobelx = cv2.convertScaleAbs(sobelx) # 转回uint8
sobely = cv2.convertScaleAbs(sobely) # 转回uint8
sobelxy = cv2.addWeighted(sobelx, 0.5, sobely, 0.5, 0)
sobelxy11 = cv2.Sobel(o, cv2.CV_64F, 1, 1)
cv2.imshow("ori", o)
cv2.imshow("xy", sobelxy)
cv2.imshow("xy11", sobelxy11)
cv2.waitKey()
cv2.destroyAllWindows()
- 效果
scharr算子
- 使用3*3的sobel算子时,可能不太请准。scharr算子,效果更好(系数不一样)
- 函数
dst = Scharr(src, ddpeth, dx, dy)
dst
:计算结果src
:原始图像ddepth
:处理结果图像深度(具体如sobel算子一样)
dx
:x轴方向dy
:y轴方向
- 等价于
dst = Sobel(src, ddpeth, dx, dy, -1)
- 操作
import cv2
import numpy as np
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
scharrx = cv2.Scharr(o, cv2.CV_64F, 1, 0)
scharry = cv2.Scharr(o, cv2.CV_64F, 0, 1)
scharrx = cv2.convertScaleAbs(scharrx) # 转回uint8
scharry = cv2.convertScaleAbs(scharry) # 转回uint8
scharrxy = cv2.addWeighted(scharrx, 0.5, scharry, 0.5, 0)
cv2.imshow("ori", o)
cv2.imshow("x", scharrx)
cv2.imshow("y", scharry)
cv2.imshow("xy", scharrxy)
cv2.waitKey()
cv2.destroyAllWindows()
- 效果
laplacian算子
- 拉普拉斯算子类似二阶sobel导数。实际上,在OpenCV中,通过调用sobel算子来计算拉普拉斯算子。使用公式如下:
- 使用的卷积核为:P5new = (P2+P4+P6+P8)-4*P5
- 例:
- 三个算子对比
- 函数
dst = cv2.Laplacian(src, ddepth)
dst
:结果图像src
:原始图像ddepth
:图像深度(跟sobel算子一样,需要转换)
- 操作
import cv2
import numpy as np
o = cv2.imread("D:\\data\\Code\\PycharmProjects\\helloworld\\lena.jpg", cv2.IMREAD_GRAYSCALE)
laplacian = cv2.Laplacian(o, cv2.CV_64F)
laplacian = cv2.convertScaleAbs(laplacian) # 转回uint8
cv2.imshow("ori", o)
cv2.imshow("x", laplacian)
cv2.waitKey()
cv2.destroyAllWindows()
- 效果