【python opencv 计算机视觉零基础到实战】二、 opencv文件格式与摄像头读取

2021-01-14 17:18:08 浏览数 (1)

一、学习目标

  1. 了解图片的结构属性
  2. 了解如何捕获视频
  3. 了解waitkey的使用方法

二、了解opencv的图像属性

2.1 图像的属性

在我们获取到图像后,可以获取到图像的大小、类型以及通道等信息;通道指的是RGB这三个颜色通道,一幅完整的图像是由单独的红色图像、单独的绿色图像以及单独的蓝色图像组成;一幅图像若绿色通道没有,或者说关闭,它将会偏向其它两个颜色,同理,若其它颜色通道关闭后亦是如此。

我们可以操作这些通道信息,完成对图像的编辑。这三个通道的单独值范围都是0-255,显示方式如单独的红色则是(255,0,0),单独的绿色是(0,255,0)单独的蓝色则是(0,0,255),这些值对应一种数据类型uint8,表示取值范围就是0-255.

2.2 查看图像的宽高通道

那如何获取到图像的这些属性呢?在OpenCV中获取这些信息是十分简单的。首先我们可以使用shape获取图像的长宽以及通道个数。如下代码:

代码语言:javascript复制
import cv2

img = cv2.imread(r'C:UsersmxDesktop1.jpg')
cv2.namedWindow("Image",cv2.WINDOW_NORMAL)
cv2.destroyWindow("Image")
cv2.imshow("Image", img)
print(img.shape)

以上代码中除了最后一行代码,其余都是上一节的内容,最后一行代码调用了读取到的img图片文件的shape属性。shape属性是img图片的长宽和通道,当使用该属性时将会得到长宽和通道属性。结果如下:

在显示的结果中可以看到,该值为1080、1620与3,其中长是1080,宽是1620,通道数是3。我们可以查看该图片属性得到值,对比是否一致。改图片信息如下:

2.3 查看图像的整体大小

得到信息后,我们还可以具体查看这个图片的具体大小。使用size属性可以获取到当前图片的具体大小值。

代码语言:javascript复制
print(img.size)

在2.2示例代码末尾处添加以上代码。运行代码我们可以看到显示的内容如下:

我们可以发现,使用size查看大小后得到了5248800,这个数值是如何计算而来呢?我们可以通过计算器计算1080*1620的数值,当然得出的结果并不是5248800,因为我们还缺少一步,乘上3个通道值,因为我们的图片是需要有RGB三个通道的图片构成。最终通过计算机结果得出了大小的计算公式:长 * 宽 * 通道=size。

2.4 查看图像通道所占的位数

我们接下来可以查看一下每个通道占的位数。使用dtype属性可以查看每个通道数据的所占位数。

代码语言:javascript复制
import cv2

img = cv2.imread(r'C:UsersmxDesktop1.jpg')
cv2.namedWindow("Image",cv2.WINDOW_NORMAL)
cv2.destroyWindow("Image")
cv2.imshow("Image", img)

print(img.shape)
print(img.size)
print(img.dtype)

运行代码我们可以看到显示的内容如下:

在显示结果中的最后一行可以得知,所占的位数是uint8这个类型,这个类型所代表的一个数据范围就是0-255,以后若见到了该数据类型就可以很清楚的知道其中的数据的范围了,表示无符号的0-255这个范围的数据。

2.4 numpy

其实我们这个读取过来的img对象的数据类型是numpy的数据类型。numpy是一个做科学计算的数据计算包,通过numpy可以简单的去做很多运算。我们在读取这个图片时所存储的内容就是很多个0-255的数据组成的,这就是这个图片在这里最原始的样子。也可以说“这就是计算机所见到的图片的样子”,这句话并不严谨,但是有利于我们在这个层次去对这些图像数据做运算处理。

三、了解视频读取方法

3.1 了解视频与图片有什么关系

其实视频就是很多张图片而组成的,多张图片呈现流畅的视觉感受我们就可以叫做视频。越流畅,画面的视频更新率就越高,我们打游戏时有时候会说“卡成了ppt”,这个就是指视频更新率不够流畅,例如fps8,指每秒有8图片进行显示,fps 80则是表示有每秒有80张流畅的图片在你眼前飘过,但是你感受不出来;这种呈现出来流程的视觉效果让我们感受不出来是在看一张张的图片。

我们在使用pr进行视频剪辑的时候很容易感受到这种一张张图片,这种没一张张图片我们称为每一帧。如图:

我们每次左右移动一个帧那么就是一张图片,流程的图片就形成了视频动画。我们还有更为熟悉的在纸上画画,随后波动纸张就可以形成流程的动画效果。

其实我们可以从这个原理得到在之后课程中对视频中图像识别的启示。

3.2 了解捕捉视频的方法

要捕捉相机视频我们需要创建一个VideoCapture对象,VideoCapture方法可以选择相机,并且返回一个VideoCapture对象。代码如下:

代码语言:javascript复制
captrue = cv2.VideoCapture(0)

在VideoCapture方法中,传入的参数为选择相机是哪一个,0代表第一个,若你有多个相机,则可以添加其他数字进行选择。创建相机后将返回一个值,该值可以使用isOpened方法判断相机是否打开,若没有打开则返回,你可以可以在里面添加提示信息:

代码语言:javascript复制
if not capture.isOpened():
    exit()

我们可以逐帧的读取视频信息。编写一个while循环,使用capture的read方法。read方法将会返回2个结果,一个是是否正确读取时的布尔值,一个是帧图像:

代码语言:javascript复制
while(True):
    ret,frame=capture.read()
    if not ret:
        break

以上代码中,ret是读取的正确与否,frame是帧图像。若ret不正确则会直接跳出循环。这时我们可以使用imshow函数对帧图形进行显示,并且由于循环每次都在同一个窗口中进行显示,这时将会刷新显示,代码如下:

代码语言:javascript复制
cv2.imshow("vedio",frame)

由于我电脑跑不动,笔记本太老,需要添加个延时,并且延时设置为3秒,3000毫秒扥估3秒:

代码语言:javascript复制
c=cv2.waitKey (3000)

为什么要等于c呢?这时因为我需要判断是否按下esc键进行退出。waitkey可以在一定时间内等待你按下键并且进行记录,esc键的值是27,所以代码为:

代码语言:javascript复制
if c==27:
        break

整体代码为:

代码语言:javascript复制
import cv2

capture=cv2.VideoCapture(0)
if not capture.isOpened():
    exit()
while(True):
    ret,frame=capture.read()
    if not ret:
        break
    cv2.imshow("vedio",frame)
    c=cv2.waitKey (3000)
    if c==27:
        break

这时可以运行代码查看效果,如果你电脑比我的更差,嗯。。。那就延时设置更高吧。运行效果如下:

本人比较害羞所以打码了,并且由于我设备有些问题,所以出现了点不一样的情况,正常情况会清晰的显示出结果的。 注:文章首发于ebaina

四、总结

  1. 了解图片的属性是有3个通道,分别为红绿蓝,并且可以通过shape获取到图片的宽高和三个通道
  2. 了解了如何计算图片的大小,是宽高乘积再乘3
  3. 了解了一张完整的图片是由3个单张的红绿蓝三通道图片组成
  4. 了解捕获视频需要创建VideoCapture对象
  5. 了解了选择设备在VideoCapture方法中传入参数进行选择
  6. 了解waitkey的可以等待并且接受输入的按键值

0 人点赞