第二章 处理文件 摄像头和图形用户界面
1 基本i/o脚本
读写图像文件
示例代码如下:
#!/usr/bin/env python # -*- coding: utf-8 -*- # @Time : 2016/11/27 12:22 # @Author : Retacn # @Site : 读/写图像文件 # @File : imageReadWrite.py # @Software: PyCharm import cv2 import numpy as np from 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) #将图像转化成BGR img2=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: PyCharm import cv2 import numpy as np import os from matplotlib import pyplot as plt #读入图像 img=cv2.imread('../test.jpg',cv2.IMREAD_GRAYSCALE) print(img) #显示转换为标准一维python bytearray byteArray=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: PyCharm import cv2 import numpy as np from 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: PyCharm import cv2 cameraCapture = cv2.VideoCapture('../test.avi') FPS = 30 size = (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: PyCharm import cv2 # cameraCapture=cv2.VideoCapture(0) FPS=30 size=(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-1 while success and numFramesRemaining>0: videoWrite.write(frame) success,frame=cameraCapture.read() numFramesRemaining-=1 cameraCapture.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: PyCharm import cv2 import numpy as np img=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: PyCharm import cv2 import numpy as np clicked=False def onMouse(event,x,y,flags,param): global clicked if event==cv2.EVENT_LBUTTONUP:#左健抬起 clicked=True cameraCapture=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: PyCharm import cv2 import numpy as np import 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: PyCharm import cv2 from Two.cameo.managers import WindowManager,CaptureManager class 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()