簡介及安裝
OpenCV是Open Source Computer Vision的縮寫,由英特爾公司於1999年推出。最初使用C/ C++編寫,是一個圖像和視頻處理庫,現今包含 C ++,C#,Python 和 Java 的綁定。 OpenCV 用於各種圖像和視頻分析,如人臉追蹤及辨識,車牌辨識,照片編輯,機器人視覺,光學字符辨識等等。
學習視覺辨識,當然是從圖片及影片處理開始,這也是為什麼一開始就要介紹OpenCV這套件的原因
在Python安裝OpenCV套件時,會將 C/C++所寫成的函數庫一併安裝,所以安裝時需花費一段時間。安裝指令如下
Windows: pip install opencv-python opencv-contrib-python Linux : sudo apt-get install python3-opencv
另外也常會用到 numpy及matplotlib,所以請一併安裝。請注意,numpy到了1.19.4的版本有bug,所以請指定安裝1.19.3的版本
pip install numpy matplotlib
讀取圖片
使用 OpenCV讀取圖片檔案非常簡單,只需使用cv2.imread()指定圖片檔名即可,另使用cv2.imshow()顯示圖片。顯示圖片後會一閃就結束,所以另需使用cv2.waitKey(0)等待使用者按下任何鍵才結束。
import cv2
img=cv2.imread('1.jpg')
#img=cv2.resize(img, (1024,768), interpolation=cv2.INTER_CUBIC)
cv2.namedWindow('Title', cv2.WINDOW_NORMAL)
cv2.imshow('Title', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
cv2.imread()讀取的img 為 numpy 三維陣列, 在讀取時有第二個參數可以指定,如cv2.imread(‘2.jpg’, cv2.IMREAD_UNCHANGED)
第二個參數可以指定如下:
cv2.IMREAD_COLOR:預設值, 讀取RGB三個channels,忽略透明度
cv2.IMREAD_GRAYSCALE : 讀取灰階格式
cv2.IMREAD_UNCHANGED : 讀取所有channels, 包含透明度
waitkey
cv2.waitkey()裏面的參數是指要等待多少ms的意思。比如 cv2.waitkey(1),則會停頓 1ms 去偵測是否有按鍵被按下,如果在這1ms 沒有按鍵被按下,就執行下一行的指令。
如果是 cv2.waitkey(0),則會無限期的一直等待,直到任何一按鍵被按下,才會執行下一行指令。
cv2.waitkey()會傳回被按下按鍵的ASCIl碼,所以如果要判定是否某一個字元被按下,需使用 ord將字元轉成ASCII碼,如下所示
key=cv2.waitkey(0)
if key==ord('q') or key==27: #按下 'q' 或 ESC
do something
寫入圖片
cv2.imwrite('output.jpg', img, [cv2.IMWRITE_JPEG_QUALITY, 90])
圖片大小
圖片讀入之後,可用shape取得圖片的高,寬及channel。如為灰階的話,則沒有channel
import cv2
buddha=cv2.imread('buddle.jpg')
h, w, channel=buddha.shape
print(h, w, channel)
結果:
3456 4608 3
中文檔名
可恨的是,OpenCV在讀取具有中文目錄或檔名時,無法順利讀取。這是OpenCV不支援中文的原因。為了解決這個惱人的問題,必需先使用numpy.fromfile讀取原始資料,再使用cv2.imdecode()進行解碼產生image物件。用如下所示
import numpy as np
import cv2
def cv_imread(filePath):
img=cv2.imdecode(np.fromfile(filePath,dtype=np.uint8),cv2.IMREAD_UNCHANGED)
return img
## imdecode讀取為bgr格式,opencv可以直接處理,若需在QT顯示,需使用cv2.cvtColor()轉換成rgb
##img=cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
img=cv_imread('D:/picture/2020/20200919_生技聚餐/DSCN2846.JPG')
#img=cv2.resize(img, (1024,768), interpolation=cv2.INTER_CUBIC)
cv2.namedWindow('Title', cv2.WINDOW_NORMAL)
cv2.imshow('Title', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
#底下為將img存成檔案
cv2.imencode('.jpg', img)[1].tofile('d:/中文.jpg')
Pillow中文檔名
Pillow可以直接讀取中文檔名,然後再轉成OpenCV格式即可
import cv2 import numpy as np from PIL import Image #img=cv2.imread("老虎.jpg") # img=cv2.imdecode(np.fromfile('老虎.jpg', dtype=np.uint8), cv2.IMREAD_UNCHANGED) # img=cv2.resize(img, (1024,768), interpolation=cv2.INTER_LINEAR) # pil=Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB)) pil=Image.open("老虎.jpg") img=np.asarray(pil) img=img[...,::-1].copy() img=cv2.resize(img, (1024,768), interpolation=cv2.INTER_LINEAR) cv2.imshow("tiger", img) cv2.waitKey(0)
視訊擷取
若電腦有安裝USB Web Cam,亦可以使用OpenCV擷取影像。第一支USB Web Cam,使用cv2.VideoCapture(0)即可抓取裝置。底下程式碼會顯示視訊,按下 ESC即可停止。
import cv2
cam = cv2.VideoCapture(0)
cam.set(cv2.CAP_PROP_FRAME_WIDTH, 1920)
cam.set(cv2.CAP_PROP_FRAME_HEIGHT, 1080)
while(True):
ret, frame = cam.read()
# 將圖片轉為灰階
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
cv2.imshow('frame', gray)
if cv2.waitKey(1) & 0xFF == 27:
break
cam.release()
cv2.destroyAllWindows()
todo
import cv2 import numpy as np from PIL import Image class MahalSdk(): # @staticmethod # def read(file): # img=cv2.imdecode( # np.fromfile(file, np.uint8), # cv2.IMREAD_COLOR # ) # return img @staticmethod def read(file): return np.asarray(Image.open(file))[:,:,::-1] @staticmethod def write(img, file): pil=Image.fromarray(img[:,:,::-1].copy()) pil.save(file) @staticmethod def resize(img, width=400): h, w, _=img.shape r=h/w if r<1: height=int(width*r) else: height=int(width/r) img=cv2.resize( img, (width, height), interpolation=cv2.INTER_LINEAR) return img