OpenCV
讀檔存檔
讀檔
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)
90度旋轉
#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)
濾波器
Gaussian Filtering(線性濾波器):保留圖像主要特徵,同時降低躁點影響
#Kernal size(),須為奇數(3,3)
gaussian = cv2.GaussianBlur(image, (7, 7), 0)
Median Filtering(非線性濾波器):過濾圖像中的椒鹽雜訊
#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 – 文字字體
FONT_HERSHEY_SIMPLEX
FONT_HERSHEY_PLAIN
FONT_HERSHEY_DUPLEX
FONT_HERSHEY_COMPLEX
FONT_HERSHEY_TRIPLEX
FONT_HERSHEY_COMPLEX_SMALL
FONT_HERSHEY_SCRIPT_SIMPLEX
FONT_HERSHEY_SCRIPT_COMPLEX
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)
官方網站: