OpenCV 基礎

      在〈OpenCV 基礎〉中尚無留言

簡介

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

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *