赞
踩
笔者主要在winodows上利用Pycharm来使用opencv库,首先安装opencv库,按下win+R键,输入cmd进入终端窗口,确保已安装python环境后,利用命令跳转到习惯安装库的路径下,安装opencv库
- e: #e是你的盘名称,跳转到该盘
- cd python #cd 打开名为 python的文件夹
- cd Script #打开Script文件夹
- pip install opencv-python
ps:一般会需要python-OpenCV,Numpy 和 Matplotlib三个库,第三个相对不常使用
图像在计算机视角里是一个个的像素点组成的,对于彩色的图像一般是使用G(green)B(blue)R(red)三个三原色通道,同理黑白图像一般只有一个控制亮度的通道,最亮为白,最暗为黑。每一张图片都可以看成一个个像素点存储在矩阵中,一张彩色图片就是有三重矩阵组成,下面我尝试用opencv导入一张图片并打印图片,可以看到,一张图片在计算机眼中就是一个个矩阵,矩阵数值由0(黑)-255(白)表示不同的像素值,每个矩阵数所代表的就是一个像素点。
ps:opencv开发人员最初选择是gbr格式,现在也有其他python包使用的是rgb格式,譬如Matplotilb,bgr格式和rgb格式可以通过简单的代码进行转换,后面会提及
我们可以利用cv2.imread函数导入图片。导入图片分为绝对路径与相对路径,绝对路径需要提供全部的路径信息,而相对路径则是在当前工作目录文件下查找文件
- img = cv2.imread(r'C:\Users\yuehen\Desktop\Snipaste_2023-08-05_19-03-24.png')
- #img是变量名,r表示这是原始字符串,将反斜杠视为字符而非转移字符,''内是文件的路径
- img = cv2.imread(r'Snipaste_2023-08-05_19-03-24.png')
- #相对路径导入,会在当前工作目录下查找对象文件,如过不存在,则会返回一个空的图像对象
一个图片对象常用的主要有一下几个属性:1. .shape 2. .size 3. .dtype
我们在导入一个图片对象后便可以通过代码来输入图片的几个属性
- print(img.shape)
- #输出结果(1089, 1014, 3) 1089,1014便是长宽像素,3表示是彩色图,如果是灰度图会输出:(1089, 1014)
- print(img.size)
- #整体尺寸 =长*宽*i 彩色图i=3 灰度图 i=1
- print(img.dtype)
- #输出像素值的数据类型,一般是:uint8 ,表示数值范围为0-255
- print(type(img))
- #<class 'numpy.ndarray'>图片对象的数据类型
我们可以使用imshow来新建一个窗口展示图片,ps:如果只执行imshow会在瞬间弹出图片然后立刻关闭窗口,需要配合waitkey来控制展示时间,利用以下代码可以分别生成一个彩色的图片预览窗口以及一个灰度图预览窗口
- import cv2
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')#彩色图
- img2 = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png',cv2.IMREAD_GRAYSCALE)#灰度图
- #定义一个ishow函数用来展示图片,name是窗口名称,img是需要show的对象
- def ishow(name,img):
- cv2.imshow('image',img)#创建一个名字是image的窗口来展示img对象
- cv2.waitKey(0) #等待时间,毫秒级,0表示按任意键中值,比如设置为1000,则会在1000毫秒后执行destroywindow 关闭窗口
- cv2.destroyWindow('image') #关闭image窗口
- ishow(img,img)
- ishow(img2,img)
利用imwrite函数保存图片,执行如下代码,便可将修改后的灰度图保存到特定路径或当前工作路径下了:
- cv2.imwrite(r'C:\Users\yuehen\Desktop\cat-grayscale.png',img2)
- #这是绝对路径写法,相对路径''中只需写上cat-grayscale.png,但相对的会保存在当前工作目录下
我们可以将视频看成一帧帧的图片,视频的播放我们可以看做是一帧帧读取去每一个图片然后播放出去,所以我们导入视频文件后,需要写一个简单的循环来获取所有的帧
- video = cv2.VideoCapture(r'C:\Users\yuehen\Desktop\文豪野犬第五季04.mp4')
- #导入视频文件、
- while True:
- #利用一个无限循环,每次循环会读取一帧
- ret, frame = video.read()
- #video.read会返回两个值表示是否成功读取到帧,ret成功,frame失败
- if not ret:
- break
- #如果读取不到帧表示视频结束退出循环
- imgray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)#将所有的帧转换为灰度图像,当然可以不转换哈
- cv2.imshow('video', imgray)
- cv2.waitKey(10)#没过10毫秒进行下一帧的播放,可以通过更改数据来实现倍速播放
此时视频会一直播放直到结束,但是关闭窗口是无法停止视频播放的,你所关闭的只是那一帧的图片,可以添加一个条件判断来作为中断操作指令,例如:
- if cv2.waitKey(10) & 0xFF == 13:#ASCII码13对应的是回车键,此时追加了中断条件用户按下回车键
- break
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')#导入图片对象
- cat = img[0:300,0:600]#截取高0-300像素宽0-600像素的部分
- ishow('cat',cat)#用上文定义的图片展示函数展示图片
对比图如下:
我们可以通过split函数来拆分三色通道,利用merge函数来整合三色通道,merge函数中切换三色顺序,便可以实现rgb格式和bgr格式的互换
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')#声明一个图片对象
- b,g,r = cv2.split(img) #分别将三色通道赋予参数b,g,r
- img=cv2.merge((r,g,b))#由bgr格式切换成rgb格式
我们尝试用print函数输出b,g,r三个参数可以看到三个规格一致的像素矩阵。
这是bgr格式以及切换成rgb格式后的对比图,左侧为bgr原格式
我们同样可以通过更改三重矩阵的值来保留单色通道,并输出图片,下图为只取b通道的图片
- #只取b通道
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')#导入对象
- img[:,:,1]=0#g通道值全赋予0即b通道为白
- img[:,:,2]=0#r通道,同理b为0,可以自己选择需要保留的通道
-
主要基于copyMakeBorder函数
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')
- top,bottom,left,right = (50,100,150,250)#输入需要扩充的像素长度
- replicate = cv2.copyMakeBorder(img,top,bottom,left,right,borderType=cv2.BORDER_REPLICATE)
replicate函数是用边界的像素复制到需要扩充的区域,呈现出边界拉伸的效果
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')
- top,bottom,left,right = (50,100,150,250)#输入需要扩充的像素长度
- wrap = cv2.copyMakeBorder(img,top,bottom,left,right,borderType=cv2.BORDER_WRAP)
如下图,wrap函数是自左往右填充右侧,自上往下填充下侧,同理左侧以及上侧
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')
- top,bottom,left,right = (50,100,150,250)#输入需要扩充的像素长度
- reflect = cv2.copyMakeBorder(img,top,bottom,left,right,borderType=cv2.BORDER_REFLECT)
reflect的反射规则如下:edcba|abcde|edcba会连边界一起反射
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')
- top,bottom,left,right = (50,100,150,250)#输入需要扩充的像素长度
- reflect_101 = cv2.copyMakeBorder(img,top,bottom,left,right,borderType=cv2.BORDER_REFLECT_101)
101的反射规则如下: edcb|abcde|dcba,不包含边界的反射
- img = cv2.imread(r'C:\Users\yuehen\Desktop\cat.png')
- top,bottom,left,right = (50,100,150,250)#输入需要扩充的像素长度
- constant = cv2.copyMakeBorder(img,top,bottom,left,right,borderType=cv2.BORDER_CONSTANT)
- #默认填充黑色==value=0
- constant = cv2.copyMakeBorder(img,top,bottom,left,right,borderType=cv2.BORDER_CONSTANT,value=155)
不设置数值会默认填充黑色
图片在计算机眼中是一个大矩阵,所以我们可以对这个矩阵进行一些例如相加的基本操作,直接加减就等于将矩阵中的所有数据同时进行加减。
img2=img+50
同样的,我们可以将两张图片相加,注意,两张图片的shape属性需要一致,shape属性可以通过cv2.resize(对象,(x,y))函数来进行更改,(x,y)需要的shape值
img=img2+img
这里要注意的是,像素值只在0-255区间内,两者相加如果超过了上限值会对256取余,例如150+150会输出300%256=44
cv2自带add函数,add函数是一种饱和加法,一旦超出上限只会取上限值即255
img=cv2.add(img,img2)
利用addWeighted进行图像按权重融合,注意两张图片必须shape属性一致,可以通过下述代码更改shape
- img2=cv2.resize(img2,(750,500))#我的img2的shape值更改成与img一致
- fiximg = cv2.addWeighted(img,0.5,img2,0.5,0)#两者按0.5权重互相重叠,偏移值为0
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。