2.1 基本IO腳本
2.1.1 讀/寫圖像文件
主要關(guān)注顏色空間變換
def convertColorSpace():
""""
圖像顏色空間轉(zhuǎn)換
"""
# 創(chuàng)建3*3大小的黑色正方形圖像
img = np.zeros((3, 3), dtype=np.uint8)
print('Black Image\n', img)
# 將灰度圖轉(zhuǎn)化為BGR顏色空間的彩色圖,輸出為三通道
img = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
print('BGR Image\n', img)
- 讀寫圖片:OpenCV中的imread()函數(shù)和imwrite()函數(shù)(支持靜態(tài)圖像文件格式,不同系統(tǒng)支持的文件格式不一樣,但都支持BMP格式由桌,通常還支持PNG\JPEG和TIEF格式)
- 主要關(guān)注讀取圖片時,原圖片和讀取后數(shù)據(jù)的變化,及寫入圖片時位深和透明通道的處理
def readWriteImage():
""" 讀寫圖片
imread()函數(shù)行您,默認(rèn)情況下铭乾,即使圖片為灰度圖,依舊返回BGR格式的圖片
(除IMREAD_UNCHANGED娃循,IMREAD_LOAD_GDAL情況下炕檩,會刪除alpha通道信息)
其可選參數(shù)flags:
IMREAD_UNCHANGED = -1 用圖片的原來格式打開, 位深不變, 通道數(shù)不變
IMREAD_GRAYSCALE = 0 用灰度圖像的方式打開圖片捌斧, 位深8bit, 通道數(shù)1
IMREAD_COLOR = 1 用彩色圖像打開圖片笛质, 位深8bit, 通道數(shù)3
IMREAD_ANYDEPTH = 2 用灰度圖像的方式打開圖片, 位深不變骤星, 通道數(shù)1
IMREAD_ANYCOLOR = 4 用圖片的原來格式打開经瓷, 位深8bit, 通道數(shù)不變但<=3
IMREAD_LOAD_GDAL = 8 使用GDAL驅(qū)動讀取文件, 位深不變, 通道數(shù)不變
"""
# 圖片原始位深位16位洞难,4通道數(shù)
imgPath = './images/img1.png'
# 默認(rèn)情況
img = cv.imread(imgPath)
print('默認(rèn)情況:', '位深', img.dtype, '舆吮,通道數(shù)', img.shape)
# IMREAD_UNCHANGED
img = cv.imread(imgPath, cv.IMREAD_UNCHANGED)
print('IMREAD_UNCHANGED:', '位深', img.dtype, ',通道數(shù)', img.shape)
# IMREAD_GRAYSCALE
img = cv.imread(imgPath, cv.IMREAD_GRAYSCALE)
print('IMREAD_GRAYSCALE:', '位深', img.dtype, '队贱,通道數(shù)', img.shape)
# IMREAD_COLOR
img = cv.imread(imgPath, cv.IMREAD_COLOR)
print('IMREAD_COLOR:', '位深', img.dtype, '色冀,通道數(shù)', img.shape)
# IMREAD_ANYDEPTH
img = cv.imread(imgPath, cv.IMREAD_ANYDEPTH)
print('IMREAD_ANYDEPTH:', '位深', img.dtype, ',通道數(shù)', img.shape)
# IMREAD_ANYCOLOR
img = cv.imread(imgPath, cv.IMREAD_ANYCOLOR)
print('IMREAD_ANYCOLOR:', '位深', img.dtype, '柱嫌,通道數(shù)', img.shape)
# IMREAD_LOAD_GDAL
img = cv.imread(imgPath, cv.IMREAD_LOAD_GDAL)
print('IMREAD_LOAD_GDAL:', '位深', img.dtype, '锋恬,通道數(shù)', img.shape)
# print(img[:, : 3])
# 寫入16位深,通道數(shù)4的圖像數(shù)據(jù)编丘,返回bool值
# JPG与学、BMP存儲的視頻是unit8位深 RGB編碼的,寫入時將RGB三通道都用depth填充
# PNG允許每個通道8位位深或16位位深
cv.imwrite('./images/MyErrorJPGImg1.jpg', img)
cv.imwrite('./images/MySucceedPNGImg1.png', img)
# 位深分離嘉抓,16位->8位
cv.imwrite('./images/MySucceedJPGImg1.jpg', img // 255)
2.1.2 圖像與原始字節(jié)之間的轉(zhuǎn)換
主要就是形狀的變化索守,reshape
def rawBytesImage():
# 返回隨機(jī)字節(jié)
randomByteArray = bytearray(os.urandom(120000))
flatNumpyArray = np.array(randomByteArray)
# 將字節(jié)數(shù)組轉(zhuǎn)換為400*300的灰度圖片
grayImg = flatNumpyArray.reshape((300, 400))
cv.imwrite('./images/RandomGray.png', grayImg)
# 將字節(jié)數(shù)組轉(zhuǎn)換為400*100*3的彩色圖片
colorImg = flatNumpyArray.reshape((100, 400, 3))
cv.imwrite('./images/RandomColor.png', colorImg)
2.1.3 使用numpy.array訪問圖像數(shù)據(jù)
以前沒注意item用法,但索引用法更方便和趁手抑片,切片對區(qū)域的操作也更友好卵佛,時間無差
def acccessImageData():
# 使用item的方式
img = cv.imread('./images/img1.png')
print(img.item(150, 120, 0))
itemStart = time.time()
img.itemset((150, 120, 0), 255)
itemEnd = time.time()
print(img.item(150, 120, 0), 'itme time is', itemEnd - itemStart)
# 使用索引和切片的方式
sliceStart = time.time()
img[150,120, 0] = 254
sliceEnd = time.time()
print(img.item(150, 120, 0), 'itme time is', sliceEnd - sliceStart)
2.1.4 視頻文件的讀/寫
OpenCV提供VideoCapture類和VideoWriter類支持各種格式的視頻文件,
文件指針到達(dá)文件末尾前敞斋,VideroCapture的read()函數(shù)獲取新幀
主要關(guān)注讀寫函數(shù)截汪,視頻幀率、尺寸的獲取與設(shè)置植捎,及視頻編碼操作
def videoReadWrite():
"""
cv.VideoWriter_fourcc('I','4','2','0') = 未壓縮YUV顏色編碼衙解,4:2:0色度子采樣
cv.VideoWriter_fourcc('M','J','P','G') = motion-jpeg 編碼
cv.VideoWriter_fourcc('P','I','M','1') = MPEG-1 編碼
cv.VideoWriter_fourcc('M', 'P', '4', '2') = MPEG-4.2 編碼
cv.VideoWriter_fourcc('D', 'I', 'V', '3') = MPEG-4.3 編碼
cv.VideoWriter_fourcc('D', 'I', 'V', 'X') = MPEG-4 編碼
cv.VideoWriter_fourcc('U', '2', '6', '3') = H263 編碼
cv.VideoWriter_fourcc('I', '2', '6', '3') = H263I 編碼
cv.VideoWriter_fourcc('F', 'L', 'V', '1') = FLV1 編碼
"""
# 參數(shù)為0時,表示攝像頭設(shè)備0
videoFile = cv.VideoCapture('./videos/test.mp4')
success, frame = videoFile.read()
# 獲取視頻幀率
fps = videoFile.get(cv.CAP_PROP_FPS)
# 獲取視頻尺寸
size = (int(videoFile.get(cv.CAP_PROP_FRAME_WIDTH)), int(videoFile.get(cv.CAP_PROP_FRAME_HEIGHT)))
# 寫入新視頻文件中焰枢,cv.VideoWriter_fourcc('F', 'L', 'V', '1')指定視頻編碼
videoWriter = cv.VideoWriter('./videos/ccNew.flv', cv.VideoWriter_fourcc('F', 'L', 'V', '1'), fps, size)
while success:
videoWriter.write(frame)
success, frame = videoFile.read()
2.1.5 捕獲攝像頭的幀
def capFromCam():
cap = cv.VideoCapture(0)
# 假設(shè)幀率為30
fps = 25
# 獲取視頻尺寸
size = (int(cap.get(cv.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv.CAP_PROP_FRAME_HEIGHT)))
# 寫入新視頻文件中丢郊,cv.VideoWriter_fourcc('F', 'L', 'V', '1')指定視頻編碼
videoWriter = cv.VideoWriter('./videos/capFromCam.flv', cv.VideoWriter_fourcc('F', 'L', 'V', '1'), fps, size)
success, frame = cap.read()
# 存儲10秒的攝像頭圖像
numFramRema = 10 * fps - 1
while success and numFramRema > 0:
videoWriter.write(frame)
success, frame = cap.read()
numFramRema -= 1
cap.release()
# 兩個攝像頭
def multiCam():
cap0 = cv.VideoCapture(0)
cap1 = cv.VideoCapture(1)
success0 = cap0.grab()
success1 = cap1.grab()
if success0 and success1:
print("沒有兩個攝像頭")
frame0 = cap0.retrieve()
frame1 = cap1.retrieve()
if success0:
print('捕捉到攝像頭0')
su, frame0 = cap0.retrieve()
cap0.release()
cv.imshow('cam1', np.asarray(frame0))
cv.waitKey()
# cv2.destroyAllWindows()
2.1.7 在窗口顯示攝像頭幀
def showCamFrame():
clicked = False
# 鼠標(biāo)點(diǎn)擊事件回調(diào)
def onMouse(event, x, y, flags, param):
global clicked
if event == cv.EVENT_LBUTTONUP:
clicked = True
print(clicked)
cap = cv.VideoCapture(0)
cv.namedWindow('Myself')
cv.setMouseCallback('Myself', onMouse)
print('點(diǎn)擊窗口或按任意鍵退出')
sucess, frame = cap.read()
while sucess and cv.waitKey(1) == -1 and not clicked:
cv.imshow('Myself', frame)
sucess, frame = cap.read()
cv.destroyAllWindows()
cap.release()
參考自《OpenCV3計算機(jī)視覺 Python語言實(shí)現(xiàn)》