opencv-python学习笔记(1)图像基本操作

基于对学校所学课程的完善和补充,在寒假决定自学opencv,将学习过程以笔记形式上传至csdn方便以后复习。学习过程主要参考唐宇迪的opencv实战课程,此笔记参考网络相关资料。学习使用的实验环境是python3.6+opencv3.4.1,在jupyter notebook上进行的实验。首先导入所需的库:import cv2import matplotlib.pyplot as pltimport numpy as np#%matplotlib inline”’% matplot

目录

1.图像的读取和显示

 2.视频的读取

3.截取部分图像数据

 4.颜色通道的提取

 5.边界填充

 6.数值计算

7.图像融合

 8.图像阈值

基于对学校所学课程的完善和补充(老师摆大烂),在寒假决定自学opencv,将学习过程以笔记形式上传至csdn方便以后复习。学习过程主要参考唐宇迪老师的opencv实战课程,此笔记参考网络相关资料,因为opencv方面属于新手,若有错误或者不妥的地方欢迎指出。

学习使用的实验环境是python3.6+opencv3.4.1,在jupyter notebook上进行的实验。

首先导入所需的库:

import cv2
import matplotlib.pyplot as plt
import numpy as np
#%matplotlib inline

1.图像的读取和显示

图像的读取:

使用imread函数,括号内可指定同一文件夹下的文件或者直接指定文件的绝对路径。

#图像的读取,使用imread函数
img=cv2.imread('C:/photo/happy.jpg')

查看读入的图像:

img

opencv-python学习笔记(1)图像基本操作

可见图像在opencv中被储存为array数组。

将图像显示出来:

其中imshow函数将指定图片显示出来。

WaitKey(int k)函数的功能是刷新图像,其中参数k单位是毫秒,表示刷新频率,显示函数和刷新函数一起使用,否则无法正常显示。因为一条指令的执行速率约为0.0000000001s,人眼很难捕捉到,必须通过延时函数才能正确显示。 返回值为k毫秒内键盘按键的ASCII码值。若没有按键,则返回-1。

destroyWindow(winname)函数用来关闭winname所指定的窗口,输入winname是要关闭窗口的窗口名。

#图像的显示,也可以创建多个窗口
cv2.imshow('image',img)
#等待时间,毫秒级,0表示按任意键终止
#waitKey(delay )在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下键,则继续等待。有按键按下,返回按键的ASCII值。无按键按下,返回-1
cv2.waitKey(0)
cv2.destroyAllWindows()

 显示出图像:

opencv-python学习笔记(1)图像基本操作

 定义一个显示图像用的函数,之后操作更加简便:

#定义一个函数用来显示图像
def cv_show(name,img):
    cv2.imshow(name,img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

查看图像文件的形状:

img.shape

opencv-python学习笔记(1)图像基本操作

 其中321,400表示图像的像素值尺寸,3表示图像的通道数。rgb彩色图像有三个通道分别为r、g、b(在opencv中储存顺序为bgr),灰度图像有只有一个通道,二值图像仅有黑白两个颜色组成。

将图像转换为灰度图像:

在imread函数读取时可以添加参数转换图像的格式,这里使用cv2.IMREAD_GRAYSCALE将图像抓换为灰度图。

#读取图像将图像转换为灰度图像,第一个参数指定文件,第二个对图像进行转换
img=cv2.imread('C:/photo/happy.jpg',cv2.IMREAD_GRAYSCALE)
print(img,img.shape)

 输出数组和shape:

opencv-python学习笔记(1)图像基本操作

 观察可以发现由rgb彩色图像转换为灰度图像后,通道数由原本的3个变为1个。

保存图像:

#保存
cv2.imwrite('veryhappy.jpg',img)

返回true保存成功。

 其他:

#查看格式
print(type(img))
#查看像素点个数
print(img.size)
#查看数据类型
print(img.dtype)

相应输出:

opencv-python学习笔记(1)图像基本操作

 2.视频的读取

使用VideoCapture函数读取视频,其可以用来捕获摄像头或捕获视频,括号内为取0,1等数字来选择不同的摄像设备,或直接指定文件路径读取视频文件。

#cv2.VideoCapture可以用来捕获摄像头或捕获视频,括号内为取0,1等数字来选择不同的设备,或直接指定文件路径
vc=cv2.VideoCapture('C:/Users/86158/Videos/movie/沈阳大街.mp4')

 读取后检查文件是否能打开:

read()函数用来按帧读取视频,read()有两个返回值,open为布尔值——若读取帧是成功则返回True,如果文件读取到结尾则返回False,Frame返回每一帧的图像。

#检查视频是否能打开,若能打开isopened()返回true
if vc.isOpened():
    #若能打开,open被赋予true值,frame被赋予第一帧的图像
    open, frame =vc.read() 
else:
    #无法打开,赋予false
    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)
        #waitKey(delay )在一个给定的时间内(单位ms)等待用户按键触发;如果用户没有按下键,则继续等待。有按键按下,返回按键的ASCII值。无按键按下,返回-1。
        #关于&0xFF可以参考https://blog.csdn.net/qq_31622345/article/details/98070787
        #当按esc(ASCII值为27)时,退出while循环
        if cv2.waitKey(10) & 0xFF == 27:
            break
#release()用来停止捕获视频。
vc.release()
cv2.destroyAllWindows()

opencv-python学习笔记(1)图像基本操作

 输出的结果,将视频中每一帧都转换为灰度图。

3.截取部分图像数据

通过数组切片可以实现图像的裁剪截取操作:

img=cv2.imread('C:/photo/happy.jpg')
#通过数组切片实现对图像的部分截取
cat=img[0:300,0:300,] 
cv_show('cat',cat)

 截取的部分图像:

opencv-python学习笔记(1)图像基本操作

 4.颜色通道的提取

split()函数用来提取出图像的颜色通道,rgb彩色图像有三个通道分别为r、g、b(在opencv中储存顺序为bgr),灰度图像有只有一个通道。

#通过split()分别提取出三个通道,opencv中三个通道的顺序是bgr
b,g,r=cv2.split(img)

 查看其中一个通道中的内容和shape:

r

opencv-python学习笔记(1)图像基本操作

r.shape

opencv-python学习笔记(1)图像基本操作

 将单独的通道组合为一个rgb图像:

使用merge()函数将通道组合起来。

#merge函数可以将三个通道组合起来
img=cv2.merge((b,g,r))
img.shape

尝试更该通道中的取值查看图像的变化:

将图像中的r,g通道中的数值全部设置为0,只保留b通道。

#只保留b通道
#copy复制图像
cur_img=img.copy()
#把r,g通道的值全部设置为0
cur_img[:,:,1]=0
cur_img[:,:,2]=0
cv_show('B',cur_img)

 观察结果发现图像变成了蓝色。

opencv-python学习笔记(1)图像基本操作

 5.边界填充

cv2.copyMakeBorder()方法用于在像相框一样的图像周围创建边框。

用法:

cv2.copyMakeBorder(src, top, bottom, left, right, borderType, value)

参数:

src:它是源图像。

top:它是顶部方向上的像素数的边框宽度。

bottom:它是底部方向上的像素数的边框宽度。

left:它是左侧像素的边界宽度。

right:它是右侧像素数的边框宽度。

borderType:它描述了要添加哪种边框。它由cv2.BORDER_CONSTANT,cv2.BORDER_REFLECT等参数定义

value:这是一个可选参数,如果borderType为cv2.BORDER_CONSTANT时需要填充的常数值。

填充方法:

BORDER_CONSTANT:它添加一个恒定的彩色边框。该值应作为下一个参数给出。

BORDER_REFLECT:边框将是边框元素的镜像反射。假设,若图像包含字母“abcdefg”,则输出为“gfedcba | abcdefg | gfedcba”。

BORDER_REFLECT_101:它与cv2的工作原理相同。边界反射,但略有变化。假设,若图像包含字母“abcdefgh”,则输出为“gfedcb | abcdefgh | gfedcba”。

BORDER_REPLICATE:它复制最后一个元素。假设,若图像包含字母“abcdefgh”,则输出将为“aaaaa | abcdefgh | hhhh”。

BORDER_WARP:外包装法,输出为“cdefg|abcdefg|abcdefg”

设置五种不同的边界填充方法并输出:

img=cv2.imread('C:/photo/happy.jpg')
#指定上下左右的填充大小值
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,borderType=cv2.BORDER_REFLECT)
reflect101=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_REFLECT101)
wrap=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_WRAP)
constant=cv2.copyMakeBorder(img,top_size,bottom_size,left_size,right_size,borderType=cv2.BORDER_CONSTANT,value=0)

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('REFLECT101')
plt.subplot(235),plt.imshow(wrap,'gray'),plt.title('WRAP')
plt.subplot(236),plt.imshow(constant,'gray'),plt.title('CONSTANT')

 填充结果:

因为 opencv 的接口使用BGR模式,而 matplotlib.pyplot 接口使用的是RGB模式,图像的输出会有色差。

opencv-python学习笔记(1)图像基本操作

 6.数值计算

因为在opencv中图像以ndarray格式储存,故可以在数组上直接进行部分数值运算。

#截取图像数组中的一部分进行数值计算实验
img=cv2.imread('C:/photo/happy.jpg')
img[:5,:5,0]

原始数组为:

opencv-python学习笔记(1)图像基本操作

 在数组上进行数值运算并输出结果:

#直接在ndarry数组上相减
img2=img-10
img2[:5,:5,0]

opencv-python学习笔记(1)图像基本操作

#对应位置相加,超过255的取余
(img+img2)[:5,:5,0]

opencv-python学习笔记(1)图像基本操作

#越界的取255
cv2.add(img,img2)[:5,:5,0]  

opencv-python学习笔记(1)图像基本操作

直接相加和cv2.add方法的不同:前者越界的数值进行取余操作,后者越界直接取255。

7.图像融合

addWeighted()方法用于将两个图像加权融合

用法:

cv2.addWeighted(src1, alpha, src2, beta, gamma,dst,dtype)

参数:

第1个参数是图像1 src;

第2个参数是图像1的权值 alpha;

第3个参数为图像2 dst;

第4个参数为图像2的权值 beta;

第5个参数附加数值gamma,单个数值,即使是多通道图像也使用单个数值;

第6个参数可选,返回图像的实例,等同于函数返回结果

第7个参数可选,dtype,表示像素值的数据类型

dst(I)=saturate(src1(I)∗alpha+src2(I)∗beta+gamma)。

实例:

首先读取两幅图像并将其转换为相同的尺寸(若不转换无法进行融合)。

img=cv2.imread('C:/photo/happy.jpg')
img_cat=cv2.imread('C:/photo/cat.jpg')
img.shape

opencv-python学习笔记(1)图像基本操作

#resize函数改变图形尺寸
img_cat=cv2.resize(img_cat,(400,321))
img_cat.shape

opencv-python学习笔记(1)图像基本操作

使用addWeighted()方法将两个图像加权融合:

res=cv2.addWeighted(img,0.5,img_cat,0.5,0)
cv_show('res',res)

 融合效果:

opencv-python学习笔记(1)图像基本操作

 8.图像阈值

threshold()函数用于图像阈值处理

用法:

ret,dst=cv2.threshold(img, threshold, maxval,type)

参数

ret是返回阈值

dst是返回的输出图像

threshold是设定的阈值

maxval是当灰度值大于(或小于)阈值时将该灰度值赋成的值

type规定的是当前处理的方式

处理方式:

cv2.THRESH_BINARY    大于阈值的部分被置为maxval,小于部分被置为0 

cv2.THRESH_BINARY_INV    大于阈值部分被置为0,小于部分被置为maxval

cv2.THRESH_TRUNC     大于阈值部分被置为threshold,小于部分保持原样  

cv2.THRESH_TOZERO   小于阈值部分被置为0,大于部分保持不变

cv2.THRESH_TOZERO_INV    大于阈值部分被置为0,小于部分保持不变 

五种不同的阈值处理方法通过实例进行对比:

img_gray=cv2.imread('C:/photo/happy.jpg',cv2.IMREAD_GRAYSCALE)
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()

 输出结果:

opencv-python学习笔记(1)图像基本操作

版权声明:本文为博主sen233333原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/sen233333/article/details/122648086

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
心中带点小风骚的头像心中带点小风骚普通用户
上一篇 2022年1月23日 下午5:47
下一篇 2022年1月23日 下午6:17

相关推荐