四种图像平滑方式
均值滤波, 中值滤波, 高斯滤波, 方值滤波
均值滤波
原理: 将对应元素求和取平均值
命令: img2 = cv2.blur(原始图像,核大小)
img = cv2.blur(origin, (7,7))
方框滤波
原理: 对核中元素求和(求和一般会出现大于255情况,)或者求和取平均值
命令:img = cv2.boxFilter(原始图像,目标图像深度,核大小, normalize属性)
nomalize为0 表示求和, 为1 表示求平均值
img = cv2.boxFilter(img, -1, (2,2), normalize=1)
高斯滤波
原理: 在核中根据权重值的大小来求取像素值的比重,距离中心越大则比重越大, 反之越小
命令: dst = cv2.GaussianBlur(src, ksize, sigmaX)
img = cv2.GaussianBlur(img, (7,7),0)
4. 中值滤波
原理:核中像素值的中值作为图像像素值
命令:dst = cv2.medianBlur(src, ksize) # ksize不是能是元组,就是一个数字
img2 = cv2.medianBlur(img, 7)
图像的阈值化处理
先呈上一张图
这张图中,第一幅图表示原始图像,后面的五张表示五张不同的阈值方式:
第一种阈值:叫二进制阈值化,即将大于阈值的像素值变为255,小于阈值的像素值变为0
第二种阈值:叫反二进制阈值化,即将大于阈值的像素值变为0,小于阈值的像素值变为255
第三种阈值:叫截断阈值化,即将大于阈值的像素值变为阈值,小于阈值的像素值保持不变
第四种阈值:叫反阈值化为0,即将大于阈值的像素值变为0,小于阈值的像素值保持不变
第五种阈值:叫阈值为0,即将小于阈值的像素值变为0,大于阈值的像素值保持不变
命令:retval, dst = cv2.threshold(src, thresh, maxval, type)
retval:表示返回的阈值,跟输入的阈值一致
dst:表示返回的图像
src:输入图像
thresh:阈值
maxval:输出图像中像素最大值,一般为255
type:阈值方式:cv2.THRESH_BINARY,cv2.THRESH_BINARY_INV,cv2.THRESH_TRUNC,cv2.THRESH_TOZERO_INV,cv2.THRESH_TOZERO
r, img2 = cv2.threshold(img,100,255,cv2.THRESH_BINARY)
opencv图像处理基本操作
1、 导入opencv包
import cv2
2、读取图像
img = cv2.imread("图片路径", 读取方式)
读取方式:cv2.IMREAD_UNCHANGED(不改变图像形式),cv2.IMREAD_GRAYSCALE(以灰度形式读取图像),cv2.IMREAD_COLOR(以彩色形式读取图像)
img = cv2.imread('images/cat_color.jpg', cv2.IMREAD_GRAYSCALE)
3、显示图像
cv2.imshow('Lena', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
为了让图像一直显示而不一闪而过,要加上cv2.waitKey(),为了关掉窗口就清空内存,要加上cv2.destroyAllWindows()
4、 保存图像
命令:cv2.imwrite(‘图片路径’, img)
cv2.imwrite('images/cat.tif', img)
5、 读取和修改像素
1)类似于numpy中的数组操作一样,访问或修改单个像素只需指定像素在数组中的位置即可,例如:pixel = [100, 100];访问和修改一定区域内的多个像素只需指定数组范围就行,例如:pixels = [50:100, 50:100]
2)可以使用numpy中提供的item(),访问像素,例如:pixel = img.item(100, 100);使用itemset(),修改像素值,例如:img.itemset((100, 100), 255)
pixel = img[100, 100]
pixels = img[50:100, 50:100]
pixel = img.item(100, 100)
img.itemset((100, 100), 255)
6、 图像属性
1)图像宽度和高度:shape
2)图像像素数量:size
3)图像类型:dtype
m,n,_ = img.shape
# shape返回一个元组,如果图像是灰度图像,返回(宽度, 高度)
# 如果图像是彩色图像,返回(宽度,高度,3)
pixelSize = img.size
# 返回图像像素数量, size = m * n
pixelDtype = img.dtype
# 图像类型一般是uint8
7、 图像通道拆分与合并
1)拆分:cv2.split,一般的操作是将一副彩色图像的b, g, r三个通道分离开来,注意在opencv中,彩色图像的通道是b, g, r,而不是r, g, b,例如:b, g, r = cv2.split(img)
2)合并:cv2.merge,一般的操作是将三个通道合并成一个彩色图像,例如:img = cv2.merge([b, g, r]),合并中可以将彩色图像中的某一通道与两个零通道合并而得到蓝色,绿色,红色图像
b, g, r = cv2.split(img)
zeros = np.zeros((m,n), dtype=np.uint8)
img1 = cv2.merge([b, zeros, zeros])
img2 = cv2.merge([zeros, g, zeros])
img3 = cv2.merge([zeros, zeros, r])
8、 图像加法运算
1)使用img = cv2.add(img1, img2),两副图像相加,很有可能出现像素值超过255的情况,cv2.add会自动将超过255的值变为255
2)使用numpy中的加法img = img1 + img2,这种加法不会像cv2.add中的那样,自动将超过255的像素值变为255,它进行的是一种取模运算,简单来讲就是因为图像类型一般是uint8类型,最大值不能超过255,对于超过255的值,该类型会进行取模运算,就是取除以255的余数;为了避免这种情况出现,我们一般在对图像进行运算之前(不仅仅是加法运算,还有其他的减法,小于0的情况,乘法等等),我们要先将图像的类型转换成int32或者float类型:img = img.astype(np.float),加法结束后再对图像进行归一化处理,将图像像素范围调整到0到1之间(或者0到255之间的整数)
img1 = cv2.add(img, img)
img2 = img + img
img = img.astype(np.int32) # 对原始图像类型进行转换
img3 = img + img
# 归一化处理
def norm(img):
img = img - np.min(img)
img = img / np.max(img)
return img
img3 = norm(img3)
img3 = img3 * 255 # 必须将图像范围改到0到255后再使用np.uint8
img3 = img3.astype(np.uint8) # uint8 只是简单的
9、图像融合
img3 = cv2.addWeighted(img1, weight1, img2, weight2, light), 将两张图像按一定的比例叠加在一起
assert img1.shape == img2.shape
img3 = cv2.addWeighted(img1, 0.8, img2, 0.2, 0)
# 0.8指img1占的比重,0.2指img2占的比重, 0指不改变图像亮度
10、图像类型转换
命令:img2 = cv2.cvtColor(img, 转换格式)
常用转换格式:cv2.COLOR_BGR2GRAY(彩色转灰度), cv2.COLOR_BGR2RGB(BGR转RGB), cv2.COLOR_GRAY2BGR(灰度转彩色)
img2 = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
11、 图像缩放
命令:img2 = cv2.resize(img, (宽度,高度),fx=宽度缩放倍数,fy=高度缩放倍数)
img2 = cv2.resize(img, (200, 200))
img3 = cv2.resize(img, None, fx=1, fy=2)
12、图像翻转
命令:img2 = cv2.flip(img, 翻转方式)
翻转方式:0:x轴翻转;> 0:y轴翻转;< 0:x,y均翻转一次,即对角线翻转
img2 = cv2.flip(img, -1)