OpenCV
安装OpenCV-python
pip install opencv-python
安装可以使用国内镜像
opencv基础操作
- 图像读取
# cv2.imread(path, [读取方式])
img1 = cv2.imread('./media/1.jpg')
img2 = cv2.imread('./media/2.png')
print(img)
- 显示图像
cv2.imshow('img1',img1)
cv2.imshow('img2',img2)
cv2.waitKey(0) # 等待时间 使得窗口一直显示
- 保存图像
# 保存图片
# img1 = cv2.imread('./media/2.png')
# cv2.imshow('img1', img1)
# img2 = cv2.resize(img,dsize=None,fx=0.2,fy=0.2) # 把图片的长和宽缩小为原来的0.2
# cv2.imshow('img2', img2)
# cv2.waitKey(0)
# cv2.imwrite('./media/nut.png', img2) # 保存图片
绘制几何图形
- 绘制直线
cv2.line(img,start,end,color,thickness) 图像 起始点 终点 颜色 线条宽度
# 绘制直线
# img = cv2.imread('./media/1.jpg')
# cv2.imshow('1', img)
# cv2.line(img,(200,200),(250,250),(255,0,0),9) # 图片 第一个点的坐标 第二个点的坐标 直线颜色 直线粗细
# cv2.imshow('2',img)
# cv2.waitKey(0)
- 绘制圆形
cv.circle(img,centerpoint, r, color, thickness) 图像 圆心点 半径 颜色 线条 -1填充
# 绘制圆形
# img = cv2.imread('./media/1.jpg')
# cv2.imshow('1', img)
# cv2.circle(img,(200,200),50,(255,0,0),2) # 图片 圆心 半径
# cv2.imshow('2',img)
# cv2.waitKey(0)
- 绘制矩形
cv.rectangle(img,leftupper,rightdown,color,thickness) 左上角 右下角
# 绘制矩形
# img = cv2.imread('./media/1.jpg')
# cv2.imshow('1', img)
# cv2.rectangle(img,(200,200),(250,250),(255,0,0),2) # 图片 左上角坐标 右下角坐标
# cv2.imshow('2',img)
# cv2.waitKey(0)
- 文字
cv.putText(img,text,station, font, Fontscale ,color,thickness,cv2.LINE_AA)
# 添加文字
# img = cv2.imread('./media/1.jpg')
# # cv2.imshow('1', img)
# cv2.putText(img,'defeedback',(250,250),cv2.FONT_HERSHEY_SCRIPT_SIMPLEX,2,(255,0,0),3,cv2.LINE_AA)
# # 图片 文本内容 位置 字体 字号 颜色 粗细 字体的描边
# cv2.imshow('2',img)
# cv2.waitKey(0)
坐标相关
'''
line()
circle()
rectangle
putText
getPerspectiveTransform 矫正 warpPerspective
getRotationMatrix2D 旋转 warpAffine
'''
import cv2
nut = cv2.imread('./media/nut.png') # 宽 204 高 254
# print(nut.shape) # (254, 204, 3) h,w,c 高宽通道 行数 列数
# cv2.line(nut,(0,127),(102,127),(255,0,255),2) # line中的点的坐标是(x,y) x是列 y是行 左上角是原点 第四象限
# cv2.rectangle(nut,(0,0),(102,127),(0,255,255),2) # 同line
# cv2.putText(nut,'defeedback',(102,127),cv2.FONT_HERSHEY_COMPLEX,0.5,(0,255,255),2,cv2.LINE_AA) # 坐标是文本的左下角 同上
cv2.imshow('nut',nut)
cv2.waitKey(0)
- 获取并修改图像中的像素点
# 获取并修改图像的像素点 索引赋值
# img = cv2.imread('./media/1.jpg')
# # print(img[200:500][50:500])
# img[100:200] = [0,0,255] # 100到200行
# cv2.imshow('2',img)
# cv2.waitKey(0)
- 捕获摄像头或视频
# 捕获视频或摄像头
cap = cv2.VideoCapture('./media/Naruto.mp4') # 填地址 0则为默认摄像头
flage = True
while flage:
flage,img = cap.read()
if not flage:
print('视频播放完成')
break
cv2.imshow('video',img)
input = cv2.waitKey(30)
if input == ord('q'):
break
cap.release() # 释放资源
cv2.destroyAllWindows() # 关闭窗口
- 随机颜色
# 随机颜色
img=np.random.randint(0,256,(512,512,3),dtype=np.uint8)
cv2.imshow("img",img)
cv2.waitKey(0)
计算机眼中的图像
计算机采用0 /1 的编码,计算机中的图像都是8位,每个像素点的范围是0~255,0是黑,255是白
- 二值图像
二值图只有0和1,0是黑,1是白。
二值图通常用于文字、线条的扫描识别和掩膜图像的存储
- 灰度图
灰度图是只有一个通道的图像,每个像素点是0~255,表现出来就是有黑到灰到白的图像 256级灰度
- 彩色图
彩色图是有RGB三通道的图像,每个像素点有三个值,分别是三个通道的颜色分量
灰度
彩色图是有三个通道的图像,而灰度图是单通道图像。彩色图变灰度图是把三个通达合并的过程。合并方法主要有三种,最大值法,平均值,加权平均值。
- 最大值
三个通道中选出一个最大的,作为单通道的像素值
# 最大值灰度
# img = cv2.imread('./media/1.jpg')
# img_gret = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)
# # print(img)
# cv2.imshow('1',img)
# for i in range(img.shape[0]):
# for j in range(img.shape[1]):
# img_gret[i,j] = max(img[i][j][0], img[i][j][1], img[i][j][2])
# cv2.imshow('grey',img_gret)
# cv2.waitKey(0)
- 平均值
三个通道的相加,除以三
# 平均值灰度
# img = cv2.imread('./media/1.jpg')
# img_gret = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)
# # print(img)
# cv2.imshow('1',img)
# for i in range(img.shape[0]):
# for j in range(img.shape[1]):
# img_gret[i,j] = (int(img[i][j][0])+int(img[i][j][1])+int(img[i][j][2]))/3 # 需要先转化为int才算平均 不转化为uint8,数值计算会错误
# cv2.imshow('grey',img_gret)
# cv2.waitKey(0)
- 加权平均
每个通道乘以对应的权重值再相加
# 加权均值
# img = cv2.imread('./media/1.jpg')
# img_gret = np.zeros((img.shape[0],img.shape[1]),dtype=np.uint8)
# # print(img)
# cv2.imshow('1',img)
# x = 0.299
# y = 0.587
# z = 0.114
# for i in range(img.shape[0]):
# for j in range(img.shape[1]):
# img_gret[i,j] = int(x*img[i][j][0])+int(y*img[i][j][1])+int(z*img[i][j][2])
# cv2.imshow('grey',img_gret)
# cv2.waitKey(0)
- CV2内置加权灰度方式
读取图片时指定读取方式 (读取为灰度图,使用加权求和的灰度)
# gray = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE) # cv2内置的加权灰度 最常用
# cv2.imshow('gray',gray)
# cv2.waitKey(0)
# gray = cv2.imread('./media/1.jpg',cv2.IMREAD_REDUCED_GRAYSCALE_2)
# cv2.imshow('gray',gray)
# cv2.waitKey(0)
二值化
二值化,就是把图像修改为两个值,操作的图像为灰度图
- 阈值法THRESH_BINARY
设定一个阈值,超过的为255,小于的为0
# 阈值法 THRESH_BINARY
# gray = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE)
# cv2.imshow('gray',gray)
# _,erzhi = cv2.threshold(gray,189,255,cv2.THRESH_BINARY) # 图片 阈值 最大值 二值化方式 返回数组(布尔值是否成功,处理后的图片)
# # 小于阈值设置为0 大于阈值设置为最大值255(白)
# cv2.imshow('erzhi',erzhi)
# cv2.waitKey(0)
- 反阈值法THRESH_BINARY_INV
大于某个阈值设置为0,小于某个阈值设置为255
# 反阈值法 THRESH_BINARY_INV
# gray = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE)
# cv2.imshow('gray',gray)
# _,erzhi = cv2.threshold(gray,100,255,cv2.THRESH_BINARY_INV) # 图片 阈值 最大值 二值化方式 返回数组(布尔值是否成功,处理后的图片)
# # 小于阈值设置为255 大于阈值设置为最大值0(黑)
# cv2.imshow('erzhi',erzhi)
# cv2.waitKey(0)
3. 截断阈值法THRESH_TRUNC
大于阈值变为阈值,小于的不变
# 截断阈值法 THRESH_TRUNC
# gray = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE)
# cv2.imshow('gray',gray)
# _,erzhi = cv2.threshold(gray,127,255,cv2.THRESH_TRUNC) # 图片 阈值 最大值 二值化方式 返回数组(布尔值是否成功,处理后的图片)
# # 小于阈值不变 大于阈值设置为阈值 大于阈值则改为阈值 图片的亮部变暗 这里的最大值 255需要传入 但是函数内部未使用
# cv2.imshow('erzhi',erzhi)
# cv2.waitKey(0)
- 低阈值零处理THRESH_TOZERO
# 低阈值零处理 THRESH_TOZERO
# gray = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE)
# cv2.imshow('gray',gray)
# _,erzhi = cv2.threshold(gray,127,255,cv2.THRESH_TOZERO) # 图片 阈值 最大值 二值化方式 返回数组(布尔值是否成功,处理后的图片)
# # 小于阈值变为0 大于阈值不变 暗部变暗 这里的最大值 255需要传入 但是函数内部未使用
# cv2.imshow('erzhi',erzhi)
# cv2.waitKey(0)
- 超阈值零处理
# 超阈值零处理
# gray = cv2.imread('./media/1.jpg',cv2.IMREAD_GRAYSCALE)
# cv2.imshow('gray',gray)
# _,erzhi = cv2.threshold(gray,200,255,cv2.THRESH_TOZERO_INV) # 图片 阈值 最大值 二值化方式 返回数组(布尔值是否成功,处理后的图片)
# # 小于阈值不变 大于阈值变为0 白底变黑底 这里的最大值 255需要传入 但是函数内部未使用
# cv2.imshow('erzhi',erzhi)
# cv2.waitKey(0)
- OTSU阈值法THRESH_OTSU
通过对图像中的像素点进行遍历,然后找到计算出前景图和背景图的最大类间方差,也就是区分效果最好的阈值,设置阈值没有意义,会自动计算阈值
# OTSU阈值法
# gray = cv2.imread('./media/nut.png',cv2.IMREAD_GRAYSCALE)
# cv2.imshow('gray',gray)
# a,erzhi = cv2.threshold(gray,127,255,cv2.THRESH_OTSU) # 图片 阈值 最大值 二值化方式 返回数组(布尔值是否成功,处理后的图片)
# # 大于阈值设置为最大值255 小于设置为0 这里传入的参数阈值thresh127不再生效
# print(a) # 根据像素点求阈值 遍历阈值 直到前景和后景的方差最大
# cv2.imshow('erzhi',erzhi)
# cv2.waitKey(0)
- 自适应二值化
划分小区域单独设置阈值进行二值化,可以使用再明暗不分的图片上
# 自适应二值化
gray = cv2.imread('./media/nut.png',cv2.IMREAD_GRAYSCALE)
cv2.imshow('gray',gray)
erzhi = cv2.adaptiveThreshold(gray,
255,
cv2.ADAPTIVE_THRESH_MEAN_C,
cv2.THRESH_BINARY,
25,
10)
'''
cv2.ADAPTIVE_THRESH_GAUSSIAN_C: 自适应阈值类型。
ADAPTIVE_THRESH_MEAN_C高斯加权的累计分布函数(CDF),加常数 C 来计算阈值。
cv2.ADAPTIVE_THRESH_MEAN_C,邻域内的平均值加常数 C 计算阈值。
cv2.THRESH_BINARY: 输出图像的类型。
maxval:最大阈值
adaptiveMethod:小区域阈值的计算方式:
ADAPTIVE_THRESH_MEAN_C:小区域内取均值
ADAPTIVE_THRESH_GAUSSIAN_C:小区域内加权求和,权重是高斯核
thresholdType:二值化方法,使用THRESH_BINARY、THRESH_BINARY_INV,阈值法,反阈值法
blockSize:小区域的面积,核大小
c:计算之后减去c的到阈值
'''