Opencv学习笔记——基础知识
Posted zyw2002
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Opencv学习笔记——基础知识相关的知识,希望对你有一定的参考价值。
文章目录
1. Opencv 环境配置
为了避免依赖的冲突和python版本的不匹配,建议重新建立一个虚拟环境。
要确保python版本和opencv版本匹配。在这里,我采用的是opencv 3.8.8 和 opencv 4.5.3,并且已经配置好Anaconda。
1.1 创建opencv虚拟环境
-
创建虚拟环境(其中opencvEnv是自己起的名字,也可以用其他的名字)
Anaconda Prompt 中键入
conda create -n opencvEnv python=3.8.8
-
进入虚拟环境
activate opencvEnv
-
安装opencv
pip install opencv-python
pip install opencv-contrib-python
-
安装matplotlib库(后续画图需要)
pip install opencv-python
1.2 让notebook 进入虚拟环境
- 在当前虚拟环境下安装
conda install ipykernel
- 将当前环境写入notebook中
python -m ipykernel install --user --name opencvEnv --display-name opencvEnv
- 如果没有安装notebook ,则键入
pip install notebook
- 打开notebook
ipython notebook
- 切换当前环境为新建立的虚拟环境opencvEnv(在导航栏中点击“kernel","change kernel ",“opencvEnv”)
1.3 虚拟环境导入pycharm
-
点击"File" ,“setting”, “project”,“python interpreter”
-
点击
-
点击"add"
-
点击"Conda Environment",“Existing environment”
-
选择“opencvEnv”,“OK”
2. 图像的基本操作
图片数据大小 h e i g h t ∗ w i d t h ∗ 3 height*width*3 height∗width∗3
h e i g h t ∗ w i d t h height*width height∗width: 像素点的个数
3 3 3:R,G,B三个颜色通道
因此图片可以有三个大小为height*width的矩阵构成,矩阵中的元素值表示当前颜色通道的亮度大小,取值范围是[0,255], 数值越大,表明该区域越亮。
2.1 读取图片
2.1.1 基本操作
- 导入库
import cv2
import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
-
读取图片
opencv的读取格式是BGR, 读取格式是
cv2.imread()
, 参数是图片位置img=cv2.imread('cat.jpg') # 图片与源程序处于同一个目录下 img # 打印img的矩阵格式
-
显示图片
cv2.imshow( )
第一个参数是图片名字,第二个参数是已经读取完的图片
cv2.imshow('image',img) cv2.waitKey(0) # 等待时间,毫秒级,0表示任意键终止 cv2.destroyAllWindows()
定义显示图片的函数
def cv_show(name,img):
cv2.imshow(name,img)
cv2.waitKey(0)
cv2.destroyAllWindows()
-
图片的大小
img.shape
img.shape # (414,500,3)
-
灰度图片
cv2.imread(' ',cv2.IMREAD_GRAYSCALE)
- cv2.IMREAD_COLOR:彩色图像
- cv2.IMREAD_GRAYSCALE:灰度图像
img=cv2.imread('cat.jpg',cv2.IMREAD_GRAYSCALE) img.shape #(414,500) 灰度图片只有单通道,表示亮度
显示图片
cv2.imshow('image',img) cv2.waitKey(10000) #等待10000毫秒后自动关闭 cv2.destroyAllWindows()
-
保存图片
cv2.imwrite(' ', )
参数一:保存的文件名;参数二:保存的图片cv2.imwrite('mycat.png',img)
-
图片的类别
图片在计算机中一ndarray的数据结构保存
type(img) # numpy.ndarray
-
图片大小
img.size #207000
-
保存图片的数据类型
img.dtype #dtype('uint8')
-
截取部分图像数据
img=cv2.imread('cat.jpg') cat=img[0:50,0:200] cv_show('cat',cat)
2.1.2 颜色通道提取
-
颜色通道提取
cv2.split()
, 参数是图片,返回值分别为b,g,r1. b,g,r=cv2.split(img) r.shape #(414,500)
-
颜色通道合成
cv2.merge()
, 参数是颜色通道组成的元组,返回值是图片img=cv2.merge((b,g,r)) img.shape # (414, 500, 3)
-
保留单通道
只保留R
cur_img = img.copy() cur_img[:,:,0] = 0 #b通道置为0 cur_img[:,:,1] = 0 #g通道置为0 cv_show('R',cur_img)
只保留G
# 只保留G
cur_img = img.copy()
cur_img[:,:,0] = 0
cur_img[:,:,2] = 0
cv_show('G',cur_img)
只保留B
cur_img = img.copy()
cur_img[:,:,1] = 0
cur_img[:,:,2] = 0
cv_show('B',cur_img)
2.2 读取视频
- cv2.VideoCapture可以捕获摄像头,用数字来控制不同的设备,例如0,1。
- 如果是视频文件,直接指定好路径即可。
-
读视频
cv2.VideoCapture( )
参数是视屏路径vc = cv2.VideoCapture('test.mp4')
检查打开的是否正确,其中open 是bool类型的数据,为True表示可以正确打开,反之则不能; frame表示读取视频中的一帧数据。
if vc.isOpened(): oepn, frame = vc.read() else: open = False
while open: ret, frame = vc.read() if frame is None: #如果读取完,则退出循环 break if ret == True: gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) #将每一帧图片转化为灰度图片 cv2.imshow('result', gray) # 显示每一帧的灰度图片 if cv2.waitKey(100) & 0xFF == 27: #相邻两个帧展示间隔时间为100ms, 0xFF 是退出键 break vc.release() cv2.destroyAllWindows()
2.3 边界填充
cv2.copyMakeBorder()
参数是待处理的图片,上下左右边框大小,填充方式
- BORDER_REPLICATE:复制法,也就是复制最边缘像素。
- BORDER_REFLECT:反射法,对感兴趣的图像中的像素在两边进行复制例如:fedcba|abcdefgh|hgfedcb
- BORDER_REFLECT_101:反射法,也就是以最边缘像素为轴,对称,gfedcb|abcdefgh|gfedcba
- BORDER_WRAP:外包装法cdefgh|abcdefgh|abcdefg
- BORDER_CONSTANT:常量法,常数值填充。
top_size,bottom_size,left_size,right_size = (50,50,50,50) # 设置边界大小
replicate = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, borderType=cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size, cv2.BORDER_WRAP)
constant = cv2.copyMakeBorder(img, top_size, bottom_size, left_size, right_size,cv2.BORDER_CONSTANT, value=0)
画图展示处理效果
import matplotlib.pyplot as plt
plt.subplot(231), plt.imshow(img, 'gray'), plt.title('ORIGINAL')
plt.subplot(232), plt.imshow(replicate, 'gray'), plt.title('REPLICATE')
plt.subplot(233), plt.imshow(reflect, 'gray'), plt.title('REFLECT')
plt.subplot(234), plt.imshow(reflect101, 'gray'), plt.title('REFLECT_101')
plt.subplot(235), plt.imshow(wrap, 'gray'), plt.title('WRAP')
plt.subplot(236), plt.imshow(constant, 'gray'), plt.title('CONSTANT')
plt.show()
2.4 图像融合
2.4.1 数值计算
img_cat=cv2.imread('cat.jpg')
img_dog=cv2.imread('dog.jpg')
img_cat2= img_cat +10 # 相当于在每一个像素点位置加10
img_cat[:5,:,0]
'''
array([[142, 146, 151, ..., 156, 155, 154],
[108, 112, 118, ..., 155, 154, 153],
[108, 110, 118, ..., 156, 155, 154],
[139, 141, 148, ..., 156, 155, 154],
[153, 156, 163, ..., 160, 159, 158]], dtype=uint8)
'''
img_cat2[:5,:,0]
'''
array([[152, 156, 161, ..., 166, 165, 164],
[118, 122, 128, ..., 165, 164, 163],
[118, 120, 128, ..., 166, 165, 164],
[149, 151, 158, ..., 166, 165, 164],
[163, 166, 173, ..., 170, 169, 168]], dtype=uint8)
'''
(img_cat + img_cat2)[:5,:,0] #相当于% 256
'''
array([[ 38, 46, 56, ..., 66, 64, 62],
[226, 234, 246, ..., 64, 62, 60],
[226, 230, 246, ..., 66, 64, 62],
[ 32, 36, 50, ..., 66, 64, 62],
[ 60, 66, 80, ..., 74, 72, 70]], dtype=uint8)
'''
cv2.add
将两张图片相加时,当和超多255时,用255代替。
cv2.add(img_cat,img_cat2)[:5,:,0]
'''
array([[255, 255, 255, ..., 255, 255, 255],
[226, 234, 246, ..., 255, 255, 255],
[226, 230, 246, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255],
[255, 255, 255, ..., 255, 255, 255]], dtype=uint8)
'''
2.4.2 图像融合
当大小不同的两张图片相加会报错。
img_cat.shape # (414, 500, 3)
-
调整图片大小
cv2.resize()
参数是待处理的图片,和期望的宽高。img_dog = cv2.resize(img_dog, (500, 414)) img_dog.shape # (414, 500, 3)
还可以按照比例缩放
res = cv2.resize(img, (0, 0), fx=1, fy=3) plt.imshow(res)
-
按照权重融合
cv2.addWeighted()
参数是待处理的两张图片和各自的权重res = cv2.addWeighted(img_cat, 0.4, img_dog, 0.6, 0) plt.imshow(res)
2.5 灰度图
cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
import cv2 #opencv读取的格式是BGR
import numpy as np
import matplotlib.pyplot as plt#Matplotlib是RGB
%matplotlib inline
img=cv2.imread('cat.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
img_gray.shape #(414, 500)
展示图片
cv2.imshow("img_gray", img_gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
2.6 HSV
- H - 色调(主波长)。
- S - 饱和度(纯度/颜色的阴影)。
- V值(强度)
cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
hsv=cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2.imshow("hsv", hsv)
cv2.waitKey(0)
cv2.destroyAllWindows()
3. 阈值和平滑处理
3.1 图像阈值
ret, dst = cv2.threshold(src, thresh, maxval, type)
- src: 输入图,只能输入单通道图像,通常来说为灰度图
- dst: 输出图
- thresh: 阈值
- maxval: 当像素值超过了阈值(或者小于阈值,根据type来决定),所赋予的值
- type:二值化操作的类型,包含以下5种类型: cv2.THRESH_BINARY; cv2.THRESH_BINARY_INV; cv2.THRESH_TRUNC; cv2.THRESH_TOZERO;cv2.THRESH_TOZERO_INV
- cv2.THRESH_BINARY 超过阈值部分取maxval(最大值),否则取0
- cv2.THRESH_BINARY_INV THRESH_BINARY的反转
- cv2.THRESH_TRUNC 大于阈值部分设为阈值,否则不变
- cv2.THRESH_TOZERO 大于阈值部分不改变,否则设为0
- cv2.THRESH_TOZERO_INV THRESH_TOZERO的反转
ret, thresh1 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY)
ret, thresh2 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_BINARY_INV)
ret, thresh3 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TRUNC)
ret, thresh4 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO)
ret, thresh5 = cv2.threshold(img_gray, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original Image', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
plt.subplot(2, 3, i + 1), plt.imshow(images[i], 'gray')
plt.title(titles[i])
plt.xticks([]), plt.yticks([])
plt.show()
3.2 图像平滑
图像平滑的目的是降低噪声点的影响
img = cv2.imread('lenaNoise.png')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
滤波实际上时进行卷积
均值滤波:简单的平均卷积操作
blur = cv2.blur(img, (3, 3))
方框滤波: 基本和均值一样,可以选择归一化
box = cv2.boxFilter(img,-1,(3,3), normalize=True)
高斯滤波:高斯模糊的卷积核里的数值是满足高斯分布,相当于更重视中间
aussian = cv2.GaussianBlur(img, (5, 5), 1)
中值滤波:相当于用中值代替
median = cv2.medianBlur(img, 5)
展示所有的处理效果图
res = np.hstack((blur,aussian,median))
cv2.imshow('median vs average', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
4. 图像形态学操作
4.1 腐蚀操作
读入原始图片
img = cv2.imread('dige.png')
cv2.imshow('img', i
mg)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.erode()
, 参数分别是待处理的图片,卷积核,迭代次数
kernel = np.ones((3,3),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
读入原始图片
pie = cv2.imread('pie.png')
cv2.imshow('pie', pie)
cv2.waitKey(0)
cv2.destroyAllWindows()
观察迭代次数对于腐蚀的影响
kernel = np.ones((30,30),np.uint8)
erosion_1 = cv2.erode(pie,kernel,iterations = 1)
erosion_2 = cv2.erode(pie,kernel,iterations = 2)
erosion_3 = cv2.erode(pie,kernel,iterations = 3)
res = np.hstack((erosion_1,erosion_2,erosion_3))
cv2.imshow('res', res)
cv2.waitKey(0)
cv2.destroyAllWindows()
4.2 膨胀操作
展示原始图片
img = cv2.imread('dige.png')
cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
先进行腐蚀操作
kernel = np.ones((3,3),np.uint8)
dige_erosion = cv2.erode(img,kernel,iterations = 1)
cv2.imshow('erosion', erosion)
cv2.waitKey(0)
cv2.destroyAllWindows()
在进行膨胀操作
cv2.dilate()
膨胀操作, 参数是图片,卷积核,迭代次数
kernel = np.ones((3,3以上是关于Opencv学习笔记——基础知识的主要内容,如果未能解决你的问题,请参考以下文章