OpenCV

OpenCV的全稱是Open Source Computer Vision Library,是一個跨平台的電腦視覺庫。OpenCV是由英特爾公司發起並參與開發,以BSD授權條款授權發行,可以在商業和研究領域中免費使用。OpenCV可用於開發即時的圖像處理電腦視覺以及圖型識別程式。(From Wiki)

讀檔存檔

image = cv2.imread('filename')

#印出(h, w, c),分別代表圖片的高度、寬度與顏色通道

print(image.shape)

cv2.imwrite('filename',image)

#匯入OpenCV函式庫

import cv2

#設定從哪顆鏡頭讀取影像,在括弧中填入先前查詢到的webcam編號

webcam = cv2.VideoCapture(0)

#讀取影像

rt, image = webcam.read()

#儲存名為snapshot.jpg的照片

cv2.imwrite("snapshot.jpg", image)

#刪除webcam,避免影像佔用資源

del(webcam)

縮放、裁切、翻轉

image1 = cv2.resize(image, (640, 320))

image1 = cv2.resize(image, dsize=None, fx=0.5, fy=0.5)

# 起點座標

(x,y) = (50, 100)

# 剪裁區域的寬與高

(w, h) = (250, 300)

image1 = image[x:x+w, y:y+h]

show_img('crop', image1)

image1 = cv2.flip(image, 0)

image1 = cv2.flip(image, 1)

#0代表不旋轉,1代表逆時針旋轉90度、-1代表順時針旋轉90度

image1 = np.rot90(image, 0)

簡易影像處理

img_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) 

image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 


#大於127就為255,反之為0

ret1,image1 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)

show_img('BINARY', image1)

#大於127就為0,反之為255

ret2,image2 = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY_INV)

show_img('BINARY_INV', image2)

#大於127就為127,反之為不變

ret3,image3 = cv2.threshold(image, 127, 255, cv2.THRESH_TRUNC)

show_img('TRUNC', image3)

#大於127則不變,反之為0

ret4,image4 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO)

show_img('TOZERO', image4)

#大於127就為0,反之為不變

ret5,image5 = cv2.threshold(image, 127, 255, cv2.THRESH_TOZERO_INV)

show_img('TOZERO_INV', image5)

image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 

kernel = np.ones((3, 3), np.uint8)

erode_image = cv2.erode(image, kernel, iterations=1)

image = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) 

kernel = np.ones((3, 3), np.uint8)

dilate_image = cv2.dilate(image, kernel, iterations=1)

濾波器

#Kernal size(),須為奇數(3,3)

gaussian = cv2.GaussianBlur(image, (7, 7), 0)

#Kernal須為奇數

median = cv2.medianBlur(image, 7)

提取照片顏色

# 匯入函式庫

import cv2 

import numpy as np


# 讀取圖片

img = cv2.imread('snapshot.png')


# OpenCV的顏色預設是BGR格式,這邊將其轉換為HSV格式

hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)


# 以HSV格式決定要提取的顏色範圍,顏色格式的說明請參考後續內容

lower = np.array([30,70,80])

upper = np.array([200,255,255])

# 將HSV影像的閾值設定為想要提取的顏色

mask = cv2.inRange(hsv, lower, upper)

# 使用bitwise_and()合併掩膜(mask)和原來的影像

img_specific = cv2.bitwise_and(img,img, mask= mask)

# 存檔

cv2.imwrite('img_specific.jpg', img_specific)

# 展示原圖、掩膜、抽取顏色後的影像

cv2.imshow('img',img)

cv2.imshow('mask',mask)

cv2.imshow(' img_specific ', img_specific)

cv2.waitKey(0)

cv2.destroyAllWindows()

將灰階與提取的顏色疊合

import cv2

import numpy as np

# 讀取影像

img_gray = cv2.imread('img_gray.jpg')

img_specific = cv2.imread('img_specific.jpg')


# 將提取顏色的影像轉換為灰階

img_specific_gray = cv2.cvtColor(img_specific,cv2.COLOR_BGR2GRAY)     

# 下方數字20為閾值,可修改閾值範圍(0~255)來調整掩膜區域,並轉換為二元影像

ret, mask = cv2.threshold(img_specific_gray,20, 255, cv2.THRESH_BINARY)

# 將掩膜反相

mask_inv = cv2.bitwise_not(mask)


# 使用bitwise_and()和掩膜從灰階圖中排除已被提取顏色的區域

img_gray_bg = cv2.bitwise_and(img_gray,img_gray,mask = mask_inv)

# 使用bitwise_and()和掩膜設定提取顏色的區域

img_specific_fg = cv2.bitwise_and(img_specific,img_specific,mask = mask)


# 使用add()將兩張圖片疊加

img_result = cv2.add(img_gray_bg,img_specific_fg)

# 存檔並展示

cv2.imwrite(' img_result.jpg', img_result)

cv2.imshow(' img_result ', img_result)

cv2.waitKey(0)

cv2.destroyAllWindows()

PIL影像與cv2轉換

import cv2

import numpy as np

from PIL import Image


def cv2_to_pil(img): #Since you want to be able to use Pillow (PIL)

    return Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))


def pil_to_cv2(img):

    return cv2.cvtColor(np.array(img), cv2.COLOR_RGB2BGR)


cam = cv2.VideoCapture(0) #Define the camera, 0 is which camera, if you have more than 1

ret_val, img = cam.read() #cam.read() returns ret (0/1 if the camera is working) and img, 

#the actual image of the camera in a numpy array


cv2.imshow("Camera", img) #if you wanted to open a window to see this picture

cv2.waitKey(0) #waits for the enter key to continue, change to

#0 to X milliseconds to stop for a certain amount of time.


pil_img = cv2_to_pil(img) #convert the image to PIL so you can use it that way.

讀取與寫入中文檔名

cv2的imread()與imwrite不支援讀取和寫入中文檔名

因此需使用np讀取成陣列再顯示

import cv2

import numpy as np

image_path = './中文檔名.jpg'

image = cv2.imdecode(np.fromfile(image_path, dtype=np.uint8), -1)

image = cv2.cvtColor(cv_img, cv2.COLOR_BGRA2BGR)

cv2.imshow('image_title',image)

cv2.waitKey(0)

cv2.destroyAllWindows()


cv2.imencode('.jpg', image)[1].tofile('./輸出中文檔名.jpg')

cv2.putText

cv2.putText(img, text, org, fontFace, fontScale, color[, thickness[, lineType[, bottomLeftOrigin]]])

圖片影像/繪製的文字/左上角坐標/字體/字體大小/顏色/字體粗細/字體線條種類

img – 要繪製文字的影像

text – 要繪製的文字

org – 文字左下角在影像中的座標位置

fontFace – 文字字體 

fontScale – 文字縮放比例

color – 文字顏色

thickness – 文字線條粗細度

lineType – 文字線條樣式

bottomLeftOrigin – True:org是左下角;False:org是左上角

cv2畫面呈現中文

from PIL import Image, ImageDraw, ImageFont


#CV2顯示中文

def cv2ImgAddText(img, text, left, top, textColor=(0, 255, 0), textSize=20):

   if (isinstance(img, np.ndarray)):

        #將陣列資料轉成PLI影像(OpenCV要多加BRG2RGB)

        img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))

    #建立畫板

    draw = ImageDraw.Draw(img)

    #設定字型

    fontText = ImageFont.truetype("中文字型檔", textSize, encoding="utf-8")

    #在畫板上添加中文字

    draw.text((left, top), text, textColor, font=fontText)

    #回傳影像並再度轉回陣列資料與RGB2BGR

    return cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)


#應用

new_img = cv2ImgAddText(orin_img, 文字內容, 10, 10, (255,0, 0), 25)

官方網站:

https://opencv.org/