处理基础
- opencv基本的读取图像,显示图像,保存图像
- 读取图像 imread()
- 显示图像 imshow()
- 保存图像 imwrite()
import cv2
# 读取图像
i = cv2.imread("./test.jpg")
# 显示图像
cv2.imshow("Demo",i)
cv2.waitKey(0)
cv2.destroyAllWindows()
# 保存图像 保存成功返回True
cv2.imwrite("./test2.jpg",i)
True
- 像素处理
- item可以直接访问像素点,itemset可以修改像素点的值
import cv2
# 读取图像
i = cv2.imread("./test.jpg")
# 像素处理
'''
i[:,100:200,0] = 255
或者
# item可以直接访问像素点,itemset可以修改像素点的值
# i.itemset((100:300,100:300,0),255)
# print(i.item(100,100,2))
# i.itemset((100,100,2),255)
# print(i.item(100,100,2))
'''
i[:,100:200,0] = 255
cv2.imshow("Demo",i)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 图像属性
- 图像形状 shape
- 彩色图像 返回行数、列数、通道数
- 灰色图像 返回行数、列数
- 像素数目 size
- 彩色图像 行数 * 列数 * 通道数
- 灰色图像 行数 * 列数
- 图像类型 dtype
- 图像形状 shape
import cv2
# 读取图像
i = cv2.imread("./test.jpg")
# 图像形状
print(i.shape)
# 像素数目
print(i.size)
# 图像类型
print(i.dtype)
(277, 300, 3)
249300
uint8
- 图像ROI 即:图像感兴趣区域
import cv2
img = cv2.imread("./test.jpg",cv2.IMREAD_GRAYSCALE)
print(img.shape)
cry = img[10:200,150:300]
cv2.imshow("origin", i)
cv2.imshow("cry", cry)
cv2.waitKey(0)
cv2.destroyAllWindows()
(277, 300)
- 通道的拆分(split)、合并(merge)
import cv2
img = cv2.imread("./test.jpg")
# 第一种方式拆分
r = img[:,:,2]
g = img[:,:,1]
b = img[:,:,0]
# 第二种方式拆分
b, g, r = cv2.split(img)
# 或者
r = cv2.split(img)[2]
g = cv2.split(img)[1]
b = cv2.split(img)[0]
rows,cols,none = img.shape
# 合并 merge方法 [务必注意通道合并顺序,OpenCV是bgr顺序]
new_photo = cv2.merge([b, g, r])
cv2.imshow("new_photo", new_photo)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像运算
- 图像加法 注意:参与运算的图像的大小和类型必须一致
- 使用cv2.add 方法 结果 = cv2.add(图像1,图像2) 也称之为饱和运算
- 像素值 <= 255 图像1 + 图像2
- 像素值 >255 结果取255
- 使用numpy方法直接相加 结果 = 图像1 + 图像2
- 像素值 <= 255 图像1 + 图像2
- 像素值 >255 结果对255取模(就是取余数)
- 使用cv2.add 方法 结果 = cv2.add(图像1,图像2) 也称之为饱和运算
import cv2
img1 = cv2.imread("./test.jpg", cv2.IMREAD_GRAYSCALE)
img2 = img1
# 使用numpy方法
img3 = img1 + img2
# 使用cv2.add方法
img4 = cv2.add(img1, img2)
cv2.imshow("img3", img3)
cv2.imshow("img4", img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 图像融合 注意:参与运算的图像的大小和类型必须一致
- 结果图像 = 图像1 * 系数1 + 图像2 * 系数2 + 亮度调节量
- addWeighted
- cv2.addWeighted(src1,k1,scr2,k2,gamma)
参数gamma不可以省略
- cv2.addWeighted(src1,k1,scr2,k2,gamma)
import cv2
img1 = cv2.imread("./test.jpg")
img2 = cv2.imread("./test2.png")
img1_split = img1[:77,:]
img2_split = img2[:77,:300]
# 使用cv2.addWeighted方法
img4 = cv2.addWeighted(img1_split,0.3, img2_split, 0.7, 0)
cv2.imshow("img4", img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
类型转换
使用cv2.cvtColor()函数实现类型转化
- result = cv2.cvtColor(src, code[, dstCn])
- src 表示原图像
- code 表示色彩转换码
- dstCn 表示目标的通道数
import cv2
img1 = cv2.imread("./test.jpg", cv2.IMREAD_UNCHANGED)
img2 = cv2.cvtColor(img1,cv2.COLOR_BGR2RGB)
cv2.imshow("img2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
几何变换
- 图像的缩放 result = cv2.resize(src, dsize,[,fx[,fy[,interpolation]]])
- 注意:使用fx或者fy时,dsize位置要设置为None
- src 表示图像
- dsize 表示图像输出大小
- 指定比例,内部参数(列(与fx相关),行(与fy相关))
- fx 表示水平方向的缩放比例
- fy 表示垂直方向的缩放比例
- interpolation 代表插值方式
import cv2
img1 = cv2.imread("./test.jpg", cv2.IMREAD_UNCHANGED)
# 使用resize方式
# img2 = cv2.resize(img1, (300, 200))
# 使用fx, fy
img2 = cv2.resize(img1, None, fx=0.5, fy=0.7)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 图像的翻转 result = cv2.flip(src, filpCode)
- filpCode的值取值含义
- 0 绕x轴翻转
- 正数 绕y轴翻转
- 负数 绕x,y轴翻转
- filpCode的值取值含义
import cv2
img1 = cv2.imread("./test.jpg", cv2.IMREAD_UNCHANGED)
# 0 绕x轴翻转
img2 = cv2.flip(img1, 0)
# 正数 绕y轴翻转
img3 = cv2.flip(img1, 1)
# 负数 绕x,y轴翻转
img4 = cv2.flip(img1, -1)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.imshow("img3", img3)
cv2.imshow("img4", img4)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像平滑处理
- 均值滤波 result = cv2.blur(src, 核大小)
- 对临近像素点求和平均
- 核大小为元组(以宽度和高度为元组)
import cv2
img1 = cv2.imread("./test.jpg", cv2.IMREAD_UNCHANGED)
# 均值滤波
img2 = cv2.blur(img1, (3, 3))
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 高斯滤波 result = GaussianBlur(src, ksize, sigmaX)
- 对临近像素点加权平均
- ksize 指定核大小 必须为奇数
- sigmaX X方向方差,控制权重 一般设置为0
import cv2
img1 = cv2.imread("./test.jpg", cv2.IMREAD_UNCHANGED)
# 高斯滤波
img2 = cv2.GaussianBlur(img1, (5, 5), 0)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 中值滤波 result = cv2.medianBlur(src, ksize)
- 将临近的像素点按照大小排序,选取排在中间位置的像素点
- ksize 指定核大小 一个数字就好 必须为奇数
import cv2
img1 = cv2.imread("./test.jpg", cv2.IMREAD_UNCHANGED)
# 中值滤波
img2 = cv2.medianBlur(img1, 9)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
形态学转换
主要针对二值图像
图像腐蚀和膨胀可以看做是相反的操作,组合起来一般可以去噪
- 图像腐蚀 result = cv2.erode(src,kernel,iterations)
- kernel 卷积核
- 可以使用numpy生成 kernel = np.ones((5,5),np.uint8)
- iterations 迭代次数
- 表示腐蚀次数
- kernel 卷积核
import cv2
import numpy as np
img1 = cv2.imread("./test.jpg", cv2.IMREAD_GRAYSCALE)
# 图像腐蚀
img2 = cv2.erode(img1, np.ones((5, 5),np.uint8), iterations=3)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
- 图像膨胀 result = cv2.dilate(src,kernel,iterations)
- kernel 卷积核
- 可以使用numpy生成 kernel = np.ones((5,5),np.uint8)
- iterations 迭代次数
- 表示腐蚀次数
- kernel 卷积核
import cv2
import numpy as np
img_origin = cv2.imread("./test.jpg", cv2.IMREAD_GRAYSCALE)
img1 = cv2.imread("./fs.jpg",)
# 图像膨胀
img2 = cv2.dilate(img1, np.ones((5, 5),np.uint8), iterations=3)
cv2.imshow("img_origin", img_origin)
cv2.imshow("img1", img1)
cv2.imshow("img2", img2)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像梯度
- Sobel算子及其函数使用 cv2.Sobel(src, ddepth, dx, dy,[ksize])
- ddepth 可以使用-1 但是不建议使用-1 原因是在获取某些边界时,负值边界无法获取到,一般使用cv2.CV_64F,并配合cv2.converScaleAbs()将负值转化,然后使用addWeighted来合并
- dx,dy建议分开使用设置,然后相加,使得获取的边界更加清晰
import cv2
img = cv2.imread("./cat.jpg",cv2.IMREAD_GRAYSCALE)
# dx,dy分开设置,然后dx+dy获取边界效果最好
ix = cv2.Sobel(img,cv2.CV_64F,1,0)
iy = cv2.Sobel(img,cv2.CV_64F,0,1)
# dx,dy不分开计算时的结果
ii = cv2.Sobel(img,cv2.CV_64F,1,1)
# 深度使用cv2.CV_64F时,需要使用cv2.convertScaleAbs()方法将负值转化回正值
ix = cv2.convertScaleAbs(ix)
iy = cv2.convertScaleAbs(iy)
# 将负值转化为正值
ii = cv2.convertScaleAbs(ii)
# 将获取的横向边界和纵向边界融合
i = cv2.addWeighted(ix,0.5,iy,0.5,0)
cv2.imshow("dx=1,dy=1", i)
cv2.imshow("dx=dy=1", ii)
cv2.waitKey(0)
cv2.destroyAllWindows()