opencv3计算机视觉python百度云_OpenCV3计算机视觉Python语言实现笔记(二)

1. 图像与原始字节之间的转换

从概念上讲,一个字节能表示0到255的整数。目前,对于多有的实时图像应用而言,虽然有其他的表示形式,但一个像素通常由每个通道的一个字节表示。

一个OpenCV图像是.array类型的二维或三维数组。8位的灰度图像是一个含有字节值的二维数组。一个24位的BGR图像是一个三维数组,它也包含了字节值。可使用表达式访问这些值,如image[0,0]或image[0,0,0]。第一个值代表像素的y坐标啊或行,0表示顶部;第二个值是像素的x坐标或列,0表示最左边;第三个值(如果可用的话)表示颜色通道。如,对于一个左上角有白色像素的8位灰度图像而言,image[0,0]的值为255. 对于一个左上角有蓝色像素的24位BGR图像而言,image[0,0]是[255,0,0]。

可以用另外一个表示,如image[0,0]或image[0,0]=128,还可表示成image.item((0,0))或image.setitem((0,0),128)。对于单像素操作,第二种表示方式更有效。

若一幅图像的每个通道为8位,则可将其显示转换为标准的一维Python bytearray格式:

byteArray = bytearray(image)

反之,bytearray含有恰当顺序的字节,可以通过显示转换和重构,得到numpy.array形式的图像:

garyImage = numpy.array(garyByteArray ).reshape(height, width)

bgrImage = numpy.array(bgrByteArray ).reshape(height, width, 3)

下面介绍将含有随机字节的bytearray转换为灰度图像和BGR图像:

importcv2importnumpy as npimportos#创建一个120000个随机字节的数组

randomByteArray = bytearray(os.urandom(120000)) #os.urandom(n) 返回n个随机byte值的string,作为加密使用

flatNumpyArray =np.array(randomByteArray)#将数组转换为400 x 300的灰度图像

garyImage = flatNumpyArray.reshape(300, 400)

cv2.imwrite('randomGary.png', garyImage)#将数组转换为400 x 300的彩色图像

bgrImage = flatNumpyArray.reshape(100, 400, 3)

cv2.imwrite('randomColor.png', bgrImage)

运行该程序,将会在程序所在目录中生成两张灰度图像(如下所示)。尺寸分别为400 x 100,400 x 400

使用Python标准的os.urandom()函数可随机生成原始字节,随后会把该字节转换为NumPy数组。需要注意的是,诸如numpy.random.randint(0, 256, 120000).reshape(400, 300)语句也能直接(并且更高效地)随机生成NumPy数组。使用os.urandom()函数的原因是该语句有助于展示原始字节的转换。

2. 使用numpy.array访问图像数据

加载OpenCV图像最简单的方式是使用imread()函数,该函数会返回一幅图像,这幅图像是一个数组(根据imread()函数输入参数的不同,该图像可能是二维数组,也可能是三维数组)。

y.array结构针对数组操作有很好的优化,它允许某些块(bulk)操作,这些操作在通常的Python中不可用这些特定的.array操作在OpenCV的图像处理中会很方便。利用numpy.array函数来转换数组比用普通的Python数组转换要快得多。

importcv2importnumpy as np

img= cv2.imread('flower.jpg')

img[0,0]= [255, 255, 255]

cv2.imshow('my image', img)

cv2.waitKey()

在图像左上方会出现一个白点。

假设想要改变一个特定像素的蓝色值,numpy.array提供了item()方法。该函数有3个参数:x(或左)位置,y(或顶部)位置以及(x,y)位置的数组索引(注意,在BGR图像中,某一位置的数据是按B,G,R的顺序保存的三元数组),该函数能返回索引函数的值。另一个方法是通过itemset()函数可设置指定像素在指定通道的值(itemset()有两个参数:一个三元组(x,y和索引)和要设定的值)。如下例子将坐标(150,120)的当前蓝色值127变为255

importcv2importnumpy as np

img= cv2.imread('flower.jpg')print(img.item(150, 120, 0)) # 打印当前坐标点的蓝色值

img.itemset((150, 120, 0), 255)print(img.item(150, 120, 0))

建议使用内置的滤波器和方法来处理整个图像,上述方法只适合于处理特定的小区域。

下面介绍操作通道:将指定通道(B,G,R)的所有值置为0.(注:通过循环来处理Python数组的效率非常低,应该尽量避免这样的操作。使用数组索引可以高效地操作像素。像素操作是一个高代价的低效操作,特别是在视频数据处理时,会发现要等很久才能得到结果。可用索引(indexing)来解决该问题)

以下代码可将图像所有的G(绿色)值设为0

importcv2importnumpy as np

img= cv2.imread('flower.jpg')

img[:, :,1] =0

cv2.imshow('my image', img)

cv2.waitKey()

运行结果为:

通过NumPy数组的索引访问原始像素,还可设定感兴趣区域(Region Of Interest, ROI)。一旦设定了该区域,就可以执行许多操作,例如,将该区域与变量绑定,然后设定第二个区域,并将第一个区域的值分配给第二个区域(将图像的一部分拷贝到该图像的另一个位置):

importcv2importnumpy as np

img= cv2.imread('flower.jpg')

roi= img[0:100, 0:100]

img[100:200, 100:200] =roi # 此处需考虑所用图像的尺寸,不能超过,并确保两个区域的大小一样

cv2.imshow('my image', img)

cv2.waitKey()

运行结果为:

此外,还可使用numpy.array来获得图像其他属性。

shape:NumPy返回包含宽度、高度和通道数(如果图像是彩色的)数组,这在调试图像类型时很有用;如果图像是单色或灰度的,将不包含通道值;

size:该属性是指图像像素的大小;

datatype:该属性会得到图像的数据类型(通常为一个无符号整数类型的变量和该类型占的位数,比如unit8类型)

importcv2importnumpy as np

img= cv2.imread('flower.jpg')print(img.shape)print(img.size)print(img.dtype)

运行结果为:

(220, 252, 3)

166320

uint8

3.视频文件的读/写

OpenCV提供了VideoCapture类和VideoWriter类来支持各种格式的视频文件。支持的格式类型会因系统的不同而变化,但应该都支持AVI格式。在到达视频文件末尾之前,VideoCapture类可通过read()函数来获取新的帧,每帧都是一幅基于BGR格式的图像。

可将一幅图像传递给VideoWriter类的write()函数,该函数会将这幅图像加到VideoWriter类所指向的文件中。

如下示例读取AVI文件的帧,并采用YUV颜色编码将其写入另一帧中:

importcv2

videoCapture= cv2.VideoCapture('myvideo.avi')

fps=videoCapture.get(cv2.CAP_PROP_FPS)

size=(int(videoCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(videoCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))

videoWriter= cv2.VideoWriter('MyOutputVid.avi', cv2.VideoWriter_fourcc('I', '4', '2', '0'), fps, size)

success, frame=videoCapture.read()whilesuccess: # 循环直到所有帧结束

videoWriter.write(frame)

success, frame= videoCapture.read()

要特别注意:必须要为VideoWriter类的构造函数指定视频文件名,这个文件名对应的文件若存在,会被覆盖。也必须指定视频编解码器。编解码器的可用性根据系统不同而不同。下面是一些常用选项:

cv2.VideoWriter_force('I', '4', '2', '0'):该选项是一个未压缩的YUV颜色编码,是4:2:0色度子采样。这种编码有很好的兼容性,但会产生较大文件,文件扩展名为.avi。

cv2.VideoWriter_force('P', 'I', 'M', '1'):该选项是MPEG-1编码类型,文件扩展名为.avi。

cv2.VideoWriter_force('X', 'V', 'I', 'D'):该选项是MPEG-4编码类型,如果希望得到的视频大小为平均值,推荐使用此选项,文件扩展名为.avi。

cv2.VideoWriter_force('T', 'H', 'E', 'O'):该选项是Ogg Vorbis,文件扩展名应为.ogv。

cv2.VideoWriter_force('F', 'L', 'V', '1'):该选项是一个Flash视频,文件扩展名应为.flv。

帧速率和帧大小也必须要指定,因为需要从另一个视频文件复制视频帧,这些属性可以通过VideoCapture类的get()函数得到。

4. 捕获摄像头的帧

VideoCapture类可以获得摄像头的帧流。但对摄像头而言,通常不是用视频的文件名来构造VideoCapture类,而是需要传递摄像头的设备索引(device index)。

下面的例子会捕获摄像头10秒的视频信息,并将其写入一个AVI文件中:

importcv2

cameraCapture=cv2.VideoCapture(0)

fps= 30size=(int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))

videoWriter= cv2.VideoWriter('MyOutputVid.avi', cv2.VideoWriter_fourcc('I', '4', '2', '0'), fps, size)

success, frame=cameraCapture.read()

numFramesRemaining= 10 * fps - 1

while success and numFramesRemaining >0:

videoWriter.write(frame)

success, frame=cameraCapture.read()

numFramesRemaining-= 1cameraCapture.release()

然而,VideoCapture类的get()方法不能反悔摄像头帧速率的准确值,它总是返回0。

为了针对摄像头创建合适的VideoWriter类,要么对帧速率做出假设,要么使用计时器来测量。摄像头的数量和顺序由系统决定,但OpenCV没有提供任何查询摄像头数量和属性的方法。如果使用无效索引构造了VideoCapture类,就不会得到帧,VideoCapture的read()函数会返回(false, None)。为了不让read()函数从没有正确打开的VideoCapture类中获取数据,可在执行该函数之后使用VideoCapture.isOpened方法做一个判断,该方法返回一个Boolean值。

当需要同步一组摄像头或一个多头摄像头(例如立体摄像头或Kinect)时,read()方法就不再适合了,可用grab()和retrive()方法代替它。对于一组摄像头,可以使用以下代码:

success0 =cameraCapture0.grab()

success1=cameraCapture1.grab()if success0 andsuccess1:

frame0=cameraCapture0.retrive()

frame1= cameraCapture1.retrive()

5. 在窗口显示图像

用imshow()函数实现显示图像的操作。imshow()函数有两个参数:显示图像的帧名字以及要显示的图像本身。

importcv2importnumpy as np

img= cv2.imread('flower.jpg')

cv2.imshow('my image', img)

cv2.waitKey()

cv2.destroyAllWindows() # 释放由OpenCV创建的所有窗口

6. 在窗口显示摄像头帧

OpenCV的namedWindow()、imshow()和DestoryWindow()函数允许指定窗口名来创建、显示和销毁(destroy)窗口。此外,任何窗口都可以通过waitKey()函数来获取键盘输入,通过setMouseCallback()函数来获取鼠标输入。以下代码可实时显示摄像头帧:

importcv2

clicked=FalsedefonMouse(event, x, y, flags, param):globalclickedif event ==cv2.EVENT_LBUTTONUP:

clicked=True

cameraCapture=cv2.VideoCapture(0)

cv2.namedWindow('MyWindow')

cv2.setMouseCallback('MyWindow', onMouse)print('showing camera feed. Click window or press any key to stop.')

success, frame=cameraCapture.read()while success and cv2.waitKey(1) == -1 and notclicked:

cv2.imshow('MyWindow', frame)

success, frame= cameraCapture.read()

cv2.destroyWindow('MyWindow')

cameraCapture.release()

waitKey()的参数为等待键盘触发的时间,单位为毫秒,其返回值为-1(表示没有键被按下)或ASCII码。另外,Python提供了一个标准函数ord(),该函数可以将字符转换为ASCII码。(注:在一些系统中,waitKey()的返回值可能比ASCII码的值更大(在Linux系统中,如果OpenCV使用GTK作为后端的GUI库,就会出现bug),在所有系统中,可以通过读取返回值的最后一个字节来保证肢体去ASCII码,代码为:

keycode = cv2.waitkey(1)

if keycode != -1:

keycode &= 0xff )

OpenCV的窗口函数和waitKey()函数相互依赖。OpenCV的窗口只有在调用waitKey()函数时才会更新,waitKey()函数只有在OpenCV窗口成为活动窗口时,才能捕获输入信息。

鼠标回调函数setMouseCallback()有5个参数,param是可选参数,它是setMouseCallback()函数的第三个参数,默认情况下,该参数是0.回调时间参数可以取如下的值,它们分别对应不同的鼠标事件。

cv2.EVENT_MOUSEMOVE:该事件对应鼠标移动

cv2.EVENT_LBUTTONDOWN:该事件对应鼠标左键按下

cv2.EVENT_RBUTTONDOWN:该事件对应鼠标右键按下

cv2.EVENT_MBUTTONDOWN:该事件对应鼠标中间键按下

cv2.EVENT_LBUTTONUP:该事件对应鼠标左键松开

cv2.EVENT_RBUTTONUP:该事件对应鼠标右键松开

cv2.EVENT_MBUTTONUP:该事件对应鼠标中间键松开

cv2.EVENT_LBUTTONDBLCLK:该事件对应双击鼠标左键

cv2.EVENT_RBUTTONDBLCLK:该事件对应双击鼠标右键

cv2.EVENT_MBUTTONDBLCLK:该事件随影双击鼠标中间键

鼠标回调的标志参数可能是以下事件的按位组合:

cv2.EVENT_FLAG_LBUTTON:该事件对应按下鼠标左键

cv2.EVENT_FLAG_RBUTTON:该事件对应按下鼠标右键

cv2.EVENT_FLAG_MBUTTON:该事件对应按下鼠标中间键

cv2.EVENT_FLAG_CTRLKEY:该事件对应按下Ctrl键

cv2.EVENT_FLAG_SHIFTKEY:该事件对应按下Shift键

cv2.EVENT_FLAG_ALTKEY:该事件对应按下Alt键

OpenCV 3计算机视觉 Python语言实现(第版)(含示例代码) 编辑推荐 OpenCV 3是一种*先进的计算机视觉库,它提供了很多图像和视频处理操作,以及一些代表计算机视觉未来发展方向的功能,如人脸识别或目标跟踪。学习计算机视觉算法、模型和OpenCV API的基本概念之后,可以开发各种现实生活中的应用程序(如安全和监控方面的应用程序)。 本书从图像处理的基本操作出发,带你开启先进计算机视觉的探索之旅。计算机视觉是一个快速发展的学科,与其相关的现实应用也呈爆炸性增长,本书的目的就是帮助计算机视觉领域的新手和想要了解全新的OpenCV 3.0.0的计算机视觉专家快速掌握基于PythonOpenCV计算机视觉开发的实用方法、技巧和*佳实践。 通过阅读本书,你将学到:   安装和熟练使用基于PythonOpenCV 3的API   掌握图像处理和视频分析的基础知识   在图像和视频中检测和识别目标   使用OpenCV检测和识别人脸   训练和使用自己的对象分类器   了解计算机视觉中的机器学习概念   使用OpenCV的人工神经网络来解决实际问题   开发现实生活中的计算机视觉应用 内容简介 OpenCV是开源、跨平台的计算机视觉库,由英特 尔公司发起并参与开发,在商业和研究领域中可以免费使用。本书介绍了如何通过Python来开发基于OpenCV 3.0的应用。作为当前非常流行的动态语言之一,Python不仅使用非常简单,而且功能强大。通过Python来学习OpenCV框架,可以让你很快理解计算机视觉的基本概念以及重要算法。 本书分8章来介绍计算机视觉的重要概念,所有的概念都融入了一些很有趣的项目。本书首先详细介绍了多个平台下基于PythonOpenCV安装,继而介绍了计算机视觉应用的基本操作,包括图像文件的读取与显示,图像处理的基本操作(比如边缘检测等),深度估计与分割,人脸检测与识别,图像的检索,目标的检测与识别,目标跟踪,神经网络的手写体识别。可以这样说,本书是一本不可多得的采用OpenCV实践计算机视觉应用的好书。
├─1.计算机视觉简介、环境准备(python, ipython) │ computer vsion.pdf │ CS231 introduction.pdf │ ├─2.图像分类问题简介、kNN分类器、线性分类器、模型选择 │ 2. 图像分类简介、kNN与线性分类器、模型选择.mp4 │ 2.初识图像分类.pdf │ ├─3.再谈线性分类器 │ 3.再谈线性分类器.mp4 │ 再谈线性分类器.pdf │ ├─4.反向传播算法和神经网络简介 │ .反向传播算法和神经网络简介.pdf │ 4. 反向传播算法和神经网络简介.mp4 │ ├─5.神经网络训练1 │ 5.-神经网络训练1.pdf │ 5.神经网络训练1.mp4 │ ├─6.神经网络训练2、卷积神经网络简介 │ 6.神经网络训练2.mp4 │ 神经网络训练2.pdf │ ├─7.卷积神经网络 │ 7.卷积神经网络.mp4 │ Lession7.pdf │ ├─8.图像OCR技术的回顾、进展及应用前景 │ 8.图像OCR技术的回顾、进展及应用前景.mp4 │ PhotoOCR_xbai.pdf │ └─9.物体定位检测 物体定位检测.pdf │ ├─10.卷积神经网络可视化 │ .卷积神经网络可视化.pdf │ 10.卷积神经网络可视化.mp4 │ ├─11.循环神经网络及其应用 │ 11.循环神经网络及其应用.mp4 │ 循环神经网络.pdf │ ├─12.卷积神经网络实战 │ 12.卷积神经网络训练实战.mp4 │ 卷积神经网络实战.pdf │ ├─13.常见深度学习框架介绍 │ 常见深度学习框架介绍.pdf │ ├─14.图像切割 │ 14.图像切割.mp4
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值