轉載來自https://blog.csdn.net/retacn_yue/article/details/53608358
第二章 處理文件 攝像頭和圖形用戶界面
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()