首先先创建一个文件夹,命名为OpenCV。命名为别的名字也可以,但后面的代码你可能要修改。
再新建一个1.1py文件。main.py是创建好文件夹就有的了,不予理会。
再找一张图片命名为1.1.jpg放进文件夹。
一、图像处理
1.1 读取图像
# 读取图像
import cv2
image = cv2.imread("1.1.jpg")
print(image)
imread()函数里传入字符串,字符串是文件名,可设置为绝对路径或来自内容根的路径。
print()函数打印输出图像的矩阵值。
1.2 显示图像
# 读取图像
import cv2
image = cv2.imread("1.1.jpg") # 读取图片
cv2.imshow("lovely", image) # 显示图片,命名为lovely,image是待显示的图片
cv2.waitKey() # 按下任何键盘按键后
cv2.destroyAllWindows() # 关闭所有窗口
waitKey()函数:可以传入参数,如1000 就是 1000ms=1s,8000就是8s。 waitKey(1000)
1.3 保存图像
# 读取图像
import cv2
image = cv2.imread("1.1.jpg") # 读取图片
# 保存图片,命名为lovely,image是待保存的图片
cv2.imwrite("E:\桌面\Algo\OpenCV\lovely.jpg", image)
1.4 色彩空间
GRAY色彩空间指的是灰度图。像素数组中,从0到255代表256个级别,0~255表示不同亮度(色彩的深浅程度),即每个数值表示从黑变白的颜色深浅程度。0表示纯黑色,255表示纯白色,数值由小到大,从黑变白。
# 读取图像
import cv2
image = cv2.imread("1.1.jpg") # 读取图片
cv2.imshow("1.1", image) # 显示图片
gray_image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 将图片由BGR转换为GRAY
cv2.imshow("Gray", gray_image) # 显示图片
cv2.waitKey()
cv2.destroyAllWindows()
cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)函数
第一个参数为待转换的图片,第二个为转换模式。
1.5 HSV色彩空间
BGR色彩空间是Blue、Green、Red。而HSV色彩空间是色调、饱和度、亮度。
色调(H)是指光的颜色。在OpenCV中,色调在[0, 180]内取值,如红 黄 绿 蓝 分别为 0,30,60,120。
饱和度(S)是指色彩的深浅。在OpenCV中,饱和度在区间[0,255]内取值。饱和度为0,就变成了灰度图。
亮度(V)是指光的明暗。在OpenCV中,亮度在区间[0,255]内取值。数值越大,图像越亮。亮度值为0时,图像呈纯黑色。
# 读取图像
import cv2
image = cv2.imread("1.1.jpg") # 读取图片
cv2.imshow("1.1", image) # 显示图片
hsv_image = cv2.cvtColor(image, cv2.COLOR_BGR2HSV) # 将图片由BGR转换为HSV
cv2.imshow("HSV",hsv_image) # 显示图片
cv2.waitKey()
cv2.destroyAllWindows()
cv2.cvtColor(image, cv2.COLOR_BGR2HSV)函数
cv2.cvtColor(image, cv2.COLOR_RGB2HSV)函数 这两个都可以,自行更换。
二、绘图
2.1 绘制线段
cv2.line(img, pt1, pt2, color, thickness) 函数
pt1:线段的起点坐标
pt2:线段的终点坐标
color:绘制线段时的线条颜色
thicness:绘制线段时的线条宽度
# 读取图像
import numpy as np
import cv2
# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((300, 300, 3), np.uint8)
# 在画布上,绘制一个起点坐标为(50, 50), 终点坐标为(250, 50), 蓝色的, 线条宽度为5的线段
canvas = cv2.line(canvas,(50, 50), (250, 50), (255, 0, 0), 5)
canvas = cv2.line(canvas,(50, 150), (250, 150), (0, 255, 0), 10)
canvas = cv2.line(canvas,(50, 250), (250, 250), (0, 0, 255), 15)
canvas = cv2.line(canvas,(150, 50), (150, 250), (0, 255, 255), 20)
cv2.imshow("Lines", canvas)
cv2.waitKey()
cv2.destroyAllWindows()
2.2 绘制矩形
# 读取图像
import numpy as np
import cv2
# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((300, 300, 3), np.uint8)
# 在画布上,绘制一个起点坐标为(50, 50), 终点坐标为(250, 150), 青色的, 线条宽度为20的矩形
canvas = cv2.rectangle(canvas,(50, 50), (250, 150), (255, 255, 0), 20)
cv2.imshow("Rectangle", canvas)
cv2.waitKey()
cv2.destroyAllWindows()
注:
rectangle函数线条宽度参数可写成 -1,就变成画实心的矩形了。
绘制正方形也一样,如画一个(50, 50)、(250, 250)的正方形,改一下起点终点坐标就可以画了。
2.3 绘制圆形
# 读取图像
import numpy as np
import cv2
# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((300, 300, 3), np.uint8)
# 在画布上,绘制一个圆心坐标为(150, 150), 半径为40, 青色的, 线条宽度为20的矩形
canvas = cv2.circle(canvas,(150, 150), 40 , (255, 255, 0), 20)
cv2.imshow("Rectangle", canvas)
cv2.waitKey()
cv2.destroyAllWindows()
circle(canvas,圆心坐标,半径,颜色,线条宽度) 函数
线条宽度设置为 -1,即可画实心圆。
2.4 绘制文字
# 读取图像
import numpy as np
import cv2
# 创建一个大小300*300,具有三个颜色空间RGB的画布,以unin8类型存储
canvas = np.zeros((100, 500, 3), np.uint8)
# 在画布上, 绘制一段文字为(10, 70), 字体样式为FONT_HERSHEY_TRIPLEX,
# 字体大小为2, 绿色的, 线条宽度为5的矩形
canvas = cv2.putText(canvas,"Almost Lover", (10, 70) , cv2.FONT_HERSHEY_TRIPLEX, 2, (0, 255, 0), 5)
cv2.imshow("Text", canvas)
cv2.waitKey()
cv2.destroyAllWindows()
结果:
putText()函数的参数分别为 1要绘制的图像(画布) 2要绘制的文字 3字体样式
4字体大小 5颜色 6线条宽度
其中3字体样式有多种,可自行百度搜索。
三、阈值
阈值化的作用:使图像的轮廓更加鲜明
3.1 阈值处理函数
threshold()函数用于对图像进行阈值处理。
retval, dst = cv2.threshold(image, thresh, maxval, type)
返回值 retval:处理时所采用的阈值 dst:阈值处理后的图像
参数 :
image:图像
thresh:阈值
maxval:阈值处理采用的最大值
type:阈值处理类型
常用的阈值处理类型有:
cv2.THRESH_BINARY 二值化阈值处理
cv2.THRESH_BINARY_INV 反二值化阈值处理
cv2.THRESH_TOZERO 低于阈值零处理
cv2.THRESH_TOZERO_INV 超出阈值零处理
cv2.THRESH_TRUNC 截断阈值处理
cv2.ADAPTIVE_THRESH_MEAN_C 对一个正方形区域内的像素值进行加权平均
cv2.ADAPTIVE_THRESH_GAUSSIAN_C 按高斯函数一个正方形区域内的像素值进行加权
3.2 二值化处理
二值化处理会使图像仅仅保留两种像素值,意味着所有像素的取值只有两种。
公式:
if 像素值 <= 阈值 :像素值 = 0
if 像素值 > 阈值:像素值 = 最大值
代码:
import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.THRESH_BINARY)
cv2.imshow("img", img)
cv2.imshow("d1_THRESH_BINARY", d1)
cv2.waitKey()
cv2.destroyAllWindows()
第三行对应:retval, dst = cv2.threshold(image, thresh, maxval, type) 函数。
反二值化处理就是把cv2.THRESH_BINARY换成cv2.THRESH_BINARY_INV
3.3 零处理
import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.THRESH_TOZERO)
cv2.imshow("img", img)
cv2.imshow("d1_THRESH_TOZERO", d1)
cv2.waitKey()
cv2.destroyAllWindows()
主要变化了阈值处理类型type参数。
超出阈值零处理就是把cv2.THRESH_TOZERO换成cv2.THRESH_TOZERO_INV
3.4 截断处理
使图像中大于阈值的像素值变为阈值,小于或等于阈值的像素保持原值不变。
公式:
if 像素值 <= 阈值 :像素值 = 原值
if 像素值 > 阈值:像素值 = 阈值
import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.THRESH_TRUNC)
cv2.imshow("img", img)
cv2.imshow("d1_THRESH_TRUNC", d1)
cv2.waitKey()
cv2.destroyAllWindows()
主要变化了阈值处理类型type参数。
截断处理 type参数:cv2.THRESH_TRUNC
3.5 自适应处理
import cv2
img = cv2.imread("1.1.jpg", 0)
r1, d1 = cv2.threshold(img, 125, 255, cv2.ADAPTIVE_THRESH_MEAN_C)
r2, d2 = cv2.threshold(img, 125, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C)
cv2.imshow("img", img)
cv2.imshow("d1_ADAPTIVE_THRESH_MEAN_C", d1)
cv2.imshow("d2_ADAPTIVE_THRESH_GAUSSIAN_C", d2)
cv2.waitKey()
cv2.destroyAllWindows()
参数 cv2.ADAPTIVE_THRESH_MEAN_C 对一个正方形区域内的像素值进行加权平均
参数 cv2.ADAPTIVE_THRESH_GAUSSIAN_C 按高斯函数一个正方形区域内的像素值进行加权
四、几何变换
4.1 缩放
dst = cv2.resize(image, dsize, fx, fy, interpolation)
参数:
image:原始图像
dsize:输出图像的大小,格式为(宽,高)
fx:可选参数。水平方向的缩放比例
fy:可选参数。竖直方向的缩放比例
interpolation:可选参数。缩放的插值方式。
注:实际上dsize和fx,fy都可实现缩放效果
import cv2
img = cv2.imread("1.1.jpg", 0)
dst1 = cv2.resize(img, (400,400))
dst2 = cv2.resize(img, (800,800))
dst3 = cv2.resize(img, None, fx = 1/3, fy = 1/2)
dst4 = cv2.resize(img, None, fx = 2, fy = 2)
cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)
cv2.imshow("dst4", dst4)
cv2.waitKey()
cv2.destroyAllWindows()
注意:由于第二个参数dsize不是可选参数,所以当使用后面的可选参数时一定要对其赋None值,否则会报错。
4.2 翻转
dst = cv2.flip(image, flipCode)
image:原始图像
flipCode:翻转类型参数 0(沿X轴翻转) 正数(沿Y轴翻转) 负数(同时沿X轴、Y轴翻转)
import cv2
img = cv2.imread("1.1.jpg")
dst1 = cv2.flip(img, 0)
dst2 = cv2.flip(img, 1)
dst3 = cv2.flip(img, -1)
cv2.imshow("img", img)
cv2.imshow("dst1", dst1)
cv2.imshow("dst2", dst2)
cv2.imshow("dst3", dst3)
cv2.waitKey()
cv2.destroyAllWindows()
4.3 仿射变换
dst = cv2.warpAffine(image, M, dsize, flags, borderMode, borderValue)
image:原始图像
M:一个两行三列的矩阵,根据此矩阵的值变换原图中的像素位置
dsize:输出图像的尺寸大小
flags:可选参数,插值方式。
borderMode:可选参数,边界类型,建议使用默认值
borderValue:可选参数,边界值,默认为0,建议使用默认值
五、图像运算
5.1 掩膜
英文叫mask,用0值表示被遮盖部分,用255值表示暴露的部分
import cv2
import numpy as np
# 创建宽150,高150,3通道,像素类型为无符号8位数字的零值图像
mask = np.zeros((150, 150, 3), np.uint8)
mask[50:100, 20:80, :] = 255; # 第50-100行、20-80列改为纯白255像素
cv2.imshow("mask1", mask) # 显示掩膜
mask[:, :, :] = 255; # 全部改为纯白像素
mask[50:100, 20:80, :] = 0; # 第50-100行、20-80列改为纯黑0像素
cv2.imshow("mask2", mask) # 显示掩膜
cv2.waitKey()
cv2.destroyAllWindows()
5.2 图像的加法运算
dst = cv2.add(image1, image2, mask, dtype)
image1,image2:第一幅图象,第二幅图像
mask:可选参数,掩膜,建议使用默认值
dtype:可选参数,图像深度,建议使用默认值
import cv2
img = cv2.imread("1.1.jpg")
sum1 = img + img
sum2 = cv2.add(img, img)
cv2.imshow("img", img)
cv2.imshow("sum1", sum1)
cv2.imshow("sum2", sum2)
cv2.waitKey()
cv2.destroyAllWindows()
用 ”+“ 运算符的计算结果如果超出255,就会取相加和除以255的余数作为该点像素值,也就是取模运算,这样子超出255的像素值反而变小了。
用add()函数的计算结果如果超出255,就会取255作为该点像素值。
5.3 图形的位运算
按位与运算
import cv2
import numpy as np
img = cv2.imread("1.1.jpg") # 打开原始图像
mask = np.zeros(img.shape, np.uint8) # 生成与img大小相同的掩膜图像
mask[120:180, :, :] = 255 # 生成白色区域掩膜
mask[:, 80:180, :] = 255
bitwise_and = cv2.bitwise_and(img, mask) # 与运算
cv2.imshow("img", img) # 分别打开图像
cv2.imshow("mask", mask)
cv2.imshow("bitwise_and", bitwise_and)
cv2.waitKey()
cv2.destroyAllWindows()
同理,按位或运算将cv2.bitwise_and改成 cv2.bitwise_or 即可。
按位取反运算将将cv2.bitwise_and改成 cv2.bitwise_not 即可。
六、滤波器
滤波器的功能用作图像的平滑处理。
效果:尽可能保留原图像信息,去除图像内噪声、降低细节层次。
dst = cv2.blur(image, ksize, anchor, borderType)
image:原始图像
ksize:滤波核大小,格式为(高度,宽度),一般用等宽高的奇数的滤波核,如(3, 3)
anchor:可选参数,滤波核的锚点,建议使用默认值,可自动计算锚点
borderType:可选参数,边界样式。
6.1 均值滤波器
import cv2
img = cv2.imread("1.1.jpg")
dst1 = cv2.blur(img, (3, 3))
dst2 = cv2.blur(img, (5, 5))
dst3 = cv2.blur(img, (7, 7))
cv2.imshow("img", img)
cv2.imshow("3*3", dst1)
cv2.imshow("5*5", dst2)
cv2.imshow("7*7", dst3)
cv2.waitKey()
cv2.destroyAllWindows()
6.2 中值滤波器
dst = cv2.medianBlur(image, ksize)
image:原始图像
ksize:滤波核的边长,必须是大于1的奇数,该函数会根据此边长自动创建一个正方形的滤波核
import cv2
img = cv2.imread("1.1.jpg")
dst1 = cv2.medianBlur(img, 3)
dst2 = cv2.medianBlur(img, 5)
dst3 = cv2.medianBlur(img, 9)
cv2.imshow("img", img)
cv2.imshow("3", dst1)
cv2.imshow("5", dst2)
cv2.imshow("9", dst3)
cv2.waitKey()
cv2.destroyAllWindows()
注意 cv2.medianBlur(image, ksize)的ksize参数格式 !
6.3 高斯滤波器
dst = cv2.GaussianBlur (image, ksize, sigmaX, sigmaY, borderType)
image:原始图像
ksize:滤波核大小。格式(宽, 高)必须是奇数,如(3, 3)
sigmaX:卷积核水平方向的标准差 sigmaY:卷积核垂直方向的标准差
修改sigmaX和sigmaY都会改变卷积核的权重比例。如果不明白高斯滤波器设计原理,可直接将这两个值设置为0。 方法会自动计算合适的权重比例。
borderType:可选参数,边界样式,建议使用默认值。
import cv2
img = cv2.imread("1.1.jpg")
dst1 = cv2.GaussianBlur(img, (3,3), 0 ,0)
dst2 = cv2.GaussianBlur(img, (9, 9), 0, 0)
dst3 = cv2.GaussianBlur(img, (15, 15), 0, 0)
cv2.imshow("img", img)
cv2.imshow("5*5", dst1)
cv2.imshow("9*9", dst2)
cv2.imshow("15*15", dst3)
cv2.waitKey()
cv2.destroyAllWindows()
6.4 双边滤波器
由于均值滤波、中值滤波、高斯滤波都会使整幅图像变得平滑,而图像中的边界会变得模糊。
双边滤波器可更加有效的保护边界信息的滤波操作。
dst = cv2.bilateralFilter(image,d,sigmaColor,sigmaColor,sigmaSpace,borderType)
iamge:原始图像
d:以当前像素为中心的整个滤波区域的直径。如果是 d < 0 ,则自动根据sigmaSpace参数计算得到。该值与保留的边缘信息数量成正比,与方法运行效率成反比。
simgaSpace:坐标空间sigma的值越大,参与计算的像素数量也就越多
borderType:可选参数,边界样式。
import cv2
img = cv2.imread("1.1.jpg")
dst1 = cv2.GaussianBlur(img, (9, 9), 0, 0)
# 双边滤波器,选用范围直径为15,颜色差为120的
dst2 = cv2.bilateralFilter(img, 9, 120, 100)
cv2.imshow("img", img)
cv2.imshow("GaussianBlur", dst1)
cv2.imshow("bilateralFilter", dst2)
cv2.waitKey()
cv2.destroyAllWindows()
七、腐蚀与膨胀
7.1 腐蚀
腐蚀会使图像沿着自己的边界向内收缩。
dst = cv2.erode(image,kernal,anchor,iterations,borderType,borderValue)
kernal:腐蚀使用的核
anchor:可选参数,核的锚点位置。
iterations:可选参数,腐蚀操作的迭代次数,默认值为1。
borderType:可选参数,边界样式,建议默认。
borderValue:可选参数,边界值,建议默认。
import cv2
import numpy as np
img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8)
dst1 = cv2.erode(img, k)
cv2.imshow("img", img)
cv2.imshow("erode", dst1)
cv2.waitKey()
cv2.destroyAllWindows()
7.2 膨胀
膨胀会使图像沿着自己的边界向外扩张。
dst = cv2.dilate(image, kernal,anchor,iterations,borderType,borderValue)
kernal:膨胀使用的核
anchor:可选参数,核的锚点位置。
iterations:可选参数,膨胀操作的迭代次数,默认值为1。
borderType:可选参数,边界样式,建议默认。
borderValue:可选参数,边界值,建议默认。
import cv2
import numpy as np
img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8) # k是核
dst1 = cv2.dilate(img, k)
cv2.imshow("img", img)
cv2.imshow("dilate", dst1)
cv2.waitKey()
cv2.destroyAllWindows()
7.3 开运算
开运算就是先进行腐蚀操作,再进行膨胀操作。可用来抹除图像外部的无关细节(或噪声)。
import cv2
import numpy as np
img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8)
dst = cv2.erode(img, k) # 先腐蚀操作
dst = cv2.dilate(dst, k) # 后膨胀操作
cv2.imshow("img", img)
cv2.imshow("open", dst)
cv2.waitKey()
cv2.destroyAllWindows()
7.4 闭运算
闭运算就是先进行膨胀操作,再进行腐蚀操作。可用来抹除图像内部的无关细节(或噪声)。
import cv2
import numpy as np
img = cv2.imread("1.1.jpg")
k = np.ones((3, 3), np.uint8)
dst = cv2.dilate(img, k)
dst = cv2.erode(dst, k)
cv2.imshow("img", img)
cv2.imshow("close", dst)
cv2.waitKey()
cv2.destroyAllWindows()
八、图形检测
8.1 图像的轮廓
轮廓是什么?轮廓指的是图像中图形或物体的外边缘线条。
检测: contours, hierarchy = cv2.findContours(image,mode,methode)
mode:轮廓的检索模式。可选模式如下:
cv2.RETR_EXTERNAL 只检测外轮廓
cv2.RETR_LIST 检测所有轮廓,但不建立层次关系
cv2.RETR_CCOMP 检测所有轮廓,并建立两级层次关系
cv2,RETR_TREE 检测所有轮廓,并建立树状结构的层次关系
methode:检测轮廓时使用的方法。可选如下:
cv2.CHAIN_APPROX_NONE 储存轮廓上的所有点
cv2.CHAIN_APPROX_SIMPLE 只保存水平、垂直或对角线轮廓的端点
cv2.CHAIN_APPROX_TC89_L1 Ten-Chinl 近似算法中的一种
cv2.CHAIN_APPROX_TC89_KCOS Ten-Chinl 近似算法中的一种
contours:检测出的所有轮廓,list类型,每一个元素都是某个轮廓的像素坐标数组。
hierarchy:轮廓之间的层次关系。
画轮廓: drawContours(image,contours,contourIdx,color,thickness,lineTypee,hierarchy,maxLevel,offse)
import cv2
img = cv2.imread("1.1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 变为灰度图
t, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 灰度图转换为二值图像
# 检测图像轮廓,记录轮廓的每一个点
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_NONE)
# 绘制轮廓,颜色为红色,线条宽度为5
cv2.drawContours(img, contours, -1, (0, 0, 255), 5)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
8.2 轮廓拟合
矩形包围框
retval = cv2.boundingRect(array)
array:轮廓数组
返回值 retval:元组类型。包括四个整数值,分别是最小矩形包围框左上角顶点的横坐标、左上角顶点的纵坐标、矩形的宽和矩形的高。也可以写成x, y, w, h = cv2.boundingRect(array)
import cv2
img = cv2.imread("1.1.jpg")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 变为灰度图
t, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) # 灰度图转换为二值图像
# 检测图像轮廓,记录轮廓的每一个点
contours, hierarchy = cv2.findContours(binary, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
x, y, w, h = cv2.boundingRect(contours[0]) # 获取第一个轮廓的最小矩形边框,记录坐标和宽高
# 绘制红色矩形
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
cv2.imshow("img", img)
cv2.waitKey()
cv2.destroyAllWindows()
九、视频处理
PC没有摄像头,笔者罢工啦~~~