OpenCV 基礎運作

      在〈OpenCV 基礎運作〉中尚無留言

簡介及安裝

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

發佈留言

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