第二章 处理文件 摄像头和图形用户界面
1 基本i/o脚本
读写图像文件
示例代码如下:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/27 12:22# @Author : Retacn# @Site : 读/写图像文件# @File : imageReadWrite.py# @Software: PyCharmimport cv2import numpy as npfrom matplotlib import pyplot as plt#色正方形图像img=np.zeros((3,3),dtype=np.uint8)print(img)#输出内容如下:#[[0 0 0]# [0 0 0]# [0 0 0]]#查看图像结构print(img.shape)#输出结果# (3, 3)#将图像转化成BGRimg2=cv2.cvtColor(img,cv2.COLOR_BAYER_BG2BGR)print(img2)#输出内容如下:#[[[0 0 0]# [0 0 0]# [0 0 0]]## [[0 0 0]# [0 0 0]# [0 0 0]]## [[0 0 0]# [0 0 0]# [0 0 0]]]#查看图像结构print(img2.shape)#输出结果为:#(3, 3, 3)#将png格式图像转换为jpeg格式image=cv2.imread('../j.png')cv2.imwrite('../j.jpg',image)#imread参数# IMREAD_ANYCOLOR = 4# IMREAD_ANYDEPTH = 2# IMREAD_COLOR = 1# IMREAD_GRAYSCALE = 0 灰度图像# IMREAD_LOAD_GDAL = 8# IMREAD_UNCHANGED = -1#显示图像plt.subplot(221),plt.imshow(img)plt.title("img"),plt.xticks([]),plt.yticks([])plt.subplot(222),plt.imshow(img2)plt.title("img2"),plt.xticks([]),plt.yticks([])plt.subplot(223),plt.imshow(image)plt.title("image"),plt.xticks([]),plt.yticks([])plt.show()
图像与原始字节之间的转换
示例代码如下:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/27 12:48# @Author : Retacn# @Site : 图像与原始字节之间的转换# @File : image2array.py# @Software: PyCharmimport cv2import numpy as npimport osfrom matplotlib import pyplot as plt#读入图像img=cv2.imread('../test.jpg',cv2.IMREAD_GRAYSCALE)print(img)#显示转换为标准一维python bytearraybyteArray=bytearray(img)img=cv2.imread('../test1.jpg')byteArray1=bytearray(img)#将字节转换为图像grayImage=np.array(byteArray).reshape(220,265)bgrImage=np.array(byteArray1).reshape(800,480,3)#将随机字节转换为灰度图像和BGR图像#创建随机字节randomByteArray=bytearray(os.urandom(120000))flatNumpyArray=np.array(randomByteArray)#将字节转换为400*300 的灰度图像ran_grayImage=flatNumpyArray.reshape(300,400)#将字节转换为400*100的BGR图像ran_bgrImage=flatNumpyArray.reshape(100,400,3)#显示图像plt.subplot(221),plt.imshow(grayImage)plt.title("grayImage"),plt.xticks([]),plt.yticks([])plt.subplot(222),plt.imshow(bgrImage)plt.title("bgrImage"),plt.xticks([]),plt.yticks([])plt.subplot(223),plt.imshow(ran_grayImage)plt.title("ran_grayImage"),plt.xticks([]),plt.yticks([])plt.subplot(224),plt.imshow(ran_bgrImage)plt.title("ran_bgrImage"),plt.xticks([]),plt.yticks([])plt.show()
Array访问图形数据
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/27 13:17# @Author : Retacn# @Site : array访问图像数据# @File : arrayAccessImage.py# @Software: PyCharmimport cv2import numpy as npfrom matplotlib import pyplot as plt# 读入图像img = cv2.imread('../test.jpg')print(img[0, 0])# 修改图像数据img[0, 0] = [255, 251, 251]print(img[0, 0])# 修改指定坐标的颜色值print(img.item(150, 120, 0))img.itemset((150,120,0),255)print(img.item(150, 120, 0))#图像完全没有绿色img[:,:,1]=0#将图像的一部份复制到图像的另一个位置img_j = cv2.imread('../test1.jpg')my_roi=img_j[0:100,0:100]img_j[200:300,200:300]=my_roi#取得图像属性print(img.shape)#宽度/高度/通道数print(img.size)#图像像素的大小print(img.dtype)#图像的数据类型# 显示图像plt.subplot(121), plt.imshow(img)plt.title('change'), plt.xticks([]), plt.yticks([])plt.subplot(122), plt.imshow(img_j)plt.title('img_j'), plt.xticks([]), plt.yticks([])plt.show()
视频文件的读写
示例代码如下:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/27 13:57# @Author : Retacn# @Site : 视频文件的读写# @File : videoRead.py# @Software: PyCharmimport cv2cameraCapture = cv2.VideoCapture('../test.avi')FPS = 30size = (int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)) , int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))videoWrite = cv2.VideoWriter('../testOut.avi', cv2.VideoWriter_fourcc('I', '4', '2', '0'), FPS, size)success, frame = cameraCapture.read()while success: videoWrite.write(frame) success, frame = cameraCapture.read()cameraCapture.release()
捕获摄像头的帧
示例代码如下:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/27 13:39# @Author : Retacn# @Site : 捕获摄像头的帧# @File : videoReadWrite.py# @Software: PyCharmimport cv2#cameraCapture=cv2.VideoCapture(0)FPS=30size=(int(cameraCapture.get(cv2.CAP_PROP_FRAME_WIDTH)) ,int(cameraCapture.get(cv2.CAP_PROP_FRAME_HEIGHT)))videoWrite=cv2.VideoWriter('../test.avi',cv2.VideoWriter_fourcc('I','4','2','0'),FPS,size)success,frame=cameraCapture.read()numFramesRemaining=10*FPS-1while success and numFramesRemaining>0: videoWrite.write(frame) success,frame=cameraCapture.read() numFramesRemaining-=1cameraCapture.release()
当需要同步一组摄像头或是一个多头摄像头
success0=cameraCapture0.grab()success1=cameraCapture1.grab()if success0 and success1: frame0=cameraCapture0.retrieve() frame1=cameraCapture1.retrieve()
在窗口显示图像
示例代码如下:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/27 14:09# @Author : Retacn# @Site : 在窗口显示图像# @File : imageShow.py# @Software: PyCharmimport cv2import numpy as npimg=cv2.imread('../test.jpg')cv2.imshow('Image',img)cv2.waitKey()cv2.destroyAllWindows()
在窗口显示摄像头帧
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/27 14:13# @Author : Retacn# @Site : 在窗口显示摄像头帧# @File : videoCamera.py# @Software: PyCharmimport cv2import numpy as npclicked=Falsedef onMouse(event,x,y,flags,param): global clicked if event==cv2.EVENT_LBUTTONUP:#左健抬起 clicked=TruecameraCapture=cv2.VideoCapture(0)cv2.namedWindow("VideoWindow")cv2.setMouseCallback('VideoWindow',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 not clicked: cv2.imshow('VideoWindow',frame) success,frame=cameraCapture.read()cv2.destroyWindow('VideoWindow')cameraCapture.release()
2 cameo项目
3 cameo面向对象的设计
Managers.py文件
示例代码如下:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/28 13:30# @Author : Retacn# @Site : 面向对象的设计# @File : cameo.py# @Software: PyCharmimport cv2import numpy as npimport time''' 视频管理'''class CaptureManager(object): def __init__(self, capture, #摄像头通道 previewWindowManager=None,#窗口管理器 shouldMirrorPreview=False):#摄像头预览的镜像选项 self.previewWindowManager=previewWindowManager self.shouldMirrorPreview=shouldMirrorPreview #定义非公有变量,单下划线开始,为保护变量,只有类对象或子类对象可以访问 protected #如果以双下划线开始,为私有成员变量,只有类对象自已可以访问,像private self._capture=capture self._channel=0 self._enteredFrame=False self._frame=None self._imageFilename=None self._videoFilename=None self._videoEncoding=None self._videoWriter=None self.startTime=None self._framesElapsed=int(0) self._fpsEstimate=None @property def channel(self): return self._channel @channel.setter def channel(self,value): if self._channel!=value: self._channel=value self._frame=None @property def frame(self): if self._enteredFrame and self._frame is None: _,self._frame=self._capture.retrieve() return self._frame @property def isWritingImage(self): return self._imageFilename is not None @property def isWritingVideo(self): return self._videoFilename is not None #只能同步一帧 def enterFrame(self): assert not self._enteredFrame, \ 'previous enterFrame() had no matching exitFrame()' if self._capture is not None: self._enteredFrame=self._capture.grab() #可以从当前通道中取得图像,估计帧率,显示图像,执行暂停的请求,向文件中写入图像 def exitFrame(self): if self.frame is None: self._enteredFrame=False return #计算帧率 if self._framesElapsed==0: self._startTime=time.time() else: timeElapsed=time.time()-self._startTime self._fpsEstimate=self._framesElapsed/timeElapsed self._framesElapsed+=1 #通过窗体显示图像 if self.previewWindowManager is not None: if self.shouldMirrorPreview: mirroredFrame=np.fliplr(self._frame).copy() self.previewWindowManager.show(mirroredFrame) else: self.previewWindowManager.show(self._frame) #保存图像文件 if self.isWritingImage: cv2.imwrite(self._imageFilename,self._frame) self._imageFilename=None #保存视频文件 self._writeVideoFrame() #释放资源 self._frame=None self._enteredFrame=False #保存图片,公有函数 def writeImage(self,filename): self._imageFilename=filename #开始保存视频,公有函数 def startWritingVideo(self,filename,encoding=cv2.VideoWriter_fourcc('I','4','2','0')): self._videoFilename=filename self._videoEncoding=encoding #停止视频写入,公有函数 def stopWritingVideo(self): self._videoFilename=None self._videoEncoding=None self._videoWriter=None #写入视频帧 def _writeVideoFrame(self): if not self.isWritingVideo: return if self._videoWriter is None: fps=self._capture.get(cv2.CAP_PROP_FPS) if fps==0.0: if self._framesElapsed<20: return else: fps=self._fpsEstimate size=(int(self._capture.get(cv2.CAP_PROP_FRAME_WIDTH)), int(self._capture.get(cv2.CAP_PROP_FRAME_HEIGHT))) self._videoWriter=cv2.VideoWriter(self._videoFilename, self._videoEncoding, fps, size) self._videoWriter.write(self._frame)''' 窗口管理,支持键盘事件'''class WindowManager(object): def __init__(self, windowName,#窗体名称 keypressCallback=None):#按键回调函数 self.keypressCallback=keypressCallback self._windowName=windowName self._isWindowCreate=False #检查窗体是否被创建 @property def isWindowCreated(self): return self._isWindowCreate #创建窗体 def createWindow(self): cv2.namedWindow(self._windowName) self._isWindowCreate=True #显示图像 def show(self,frame): cv2.imshow(self._windowName,frame) #关闭窗体释放资源 def destroyWindow(self): cv2.destroyWindow(self._windowName) self._isWindowCreate=False #处理键盘事件 def processEvents(self): keycode=cv2.waitKey(1) if self.keypressCallback is not None and keycode!=-1: keycode&=0xFF #ESC 退出 self.keypressCallback(keycode)cameo.py文件
示例代码如下:
#!/usr/bin/env python# -*- coding: utf-8 -*-# @Time : 2016/11/28 14:45# @Author : Retacn# @Site : cameo实现,有两种启动方法: run() 和 onkeypress()# @File : cameo.py.py# @Software: PyCharmimport cv2from Two.cameo.managers import WindowManager,CaptureManagerclass Cameo(object): def __init__(self): self._windowManager=WindowManager('Cameo',self.onkeypress) self._captureManager=CaptureManager(cv2.VideoCapture(0),self._windowManager,True) def run(self): self._windowManager.createWindow() while self._windowManager.isWindowCreated: self._captureManager.enterFrame() frame=self._captureManager.frame self._captureManager.exitFrame() self._windowManager.processEvents() def onkeypress(self,keycode): ''' space-> 载图 tab->启动和停止视频录制 esc->退出应用 :param keycode: :return: ''' if keycode==32:#space self._captureManager.writeImage('screenshot.png') elif keycode==9:#tab if not self._captureManager.isWritingVideo: self._captureManager.startWritingVideo('screencast.avi') else: self._captureManager.stopWritingVideo() elif keycode==27:#esc self._windowManager.destroyWindow()if __name__=='__main__': Cameo().run()