簡介
OpenCV 是 Open Source Computer Vision 的縮寫,由英特爾 (Intel) 於 1999 年推出,使用 C/ C++ 編寫的圖像和視頻處理庫,可以在 C#,Python 和 Java 調用。 OpenCV 用於各種圖像和視頻分析,比如人臉追蹤及辨識、車牌辨識、照片編輯、機器人視覺、光學字符辨識等等。學習視覺辨識當然要由圖片及影片處理開始,這也是為什麼一開始就要介紹 OpenCV 這套件的原因。
安裝
在 Python 安裝 OpenCV 套件時,會將 C/C++所寫成的函數庫一併安裝,所以安裝時需花費一段時間,安裝指令如下
pip install opencv-python 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_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()
sdk 如下
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