環境設定

1
2
3
4
$ pip install numpy 
$ pip install matplotlib
$ pip install opencv-contrib-python
$ pip install caer

圖片上色、畫圖形、加文字

1
2
3
4
5
6
7
8
9
10
import cv2
import numpy

blank = numpy.zeros((500,500,3), dtype='uint8')

#-------block-------

#------endblock-----

cv2.waitKey(0)

uint8是圖片的一個資料型態

填滿特定顏色在特定位置

1
2
blank[200:300, 300:400] = 0,0,255
cv2.imshow('Green', blank)

畫長方形

1
2
cv2.rectangle(blank, (0,0), (blank.shape[1]//2, blank.shape[0]//2), (0,255,0), thickness=-1)
cv2.imshow('Rectangle', blank)

畫圓形

1
2
cv2.circle(blank, (blank.shape[1]//2, blank.shape[0]//2), 40, (0,0,255), thickness=-1)
cv2.imshow('Circle', blank)

畫線

1
2
cv2.line(blank, (100,250), (300,400), (255,255,255), thickness=3)
cv2.imshow('Line', blank)

加入文字

1
2
cv2.putText(blank, 'Hello, world!', (0,225), cv2.FONT_HERSHEY_TRIPLEX, 1.0, (0,255,0), 2)
cv2.imshow('Text', blank)

圖片讀取、顯示到儲存

完整程式碼👇

1
2
3
4
5
6
7
8
9
10
11
12
13
import cv2

img = cv2.imread("1.jpeg")

cv2.imshow("wimdows", img)

key = cv2.waitKey()
if key == ord("q"):
print("exit")

cv2.imwrite(“output.jpg”, img)

cv2.destroyWindow("windows")
1
img = cv2.imread("1.jpeg")

讀取一影像,可再夾帶參數設定讀取影像的類型:
img = cv2.imread(“1.jpeg”, cv2.IMREAD_UNCHANGED)表示讀取圖片中的所有channel,包括透明度

1
key = cv2.waitKey()

在圖片顯示時,等待使用者按按鍵回應,預設值為0,表示程式會一直等待使用者按按鍵

1
cv2.destroyWindow("windows")

釋放視窗,也可以cv2.destroAllWindow()釋放所有視窗

若是圖片帶大可能會有部分圖片顯示不了

目前為止(影片發布當下)opencv還沒有內建方法可以直接處理類似問題,只能透過後續resize、rescale等手法來處理~

讀取、顯示和儲存影片

完整程式碼👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import cv2

capture = cv2.VideoCapture(0)
capture = cv2.VideoCapture('../Resources/Videos/dog.mp4')

while True:
isTrue, frame = capture.read()

# if cv.waitKey(20) & 0xFF==ord('d'):
# This is the preferred way - if `isTrue` is false (the frame could
# not be read, or we're at the end of the video), we immediately
# break from the loop.
if isTrue:
cv2.imshow('Video', frame)
if cv2.waitKey(20) & 0xFF==ord('d'):
break
else:
break

capture.release()
cv.destroyAllWindows()

完整程式碼👇

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import cv2

cap = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.avi', fourcc, 20, (640, 480))
while (cap.isOpened()):
ret, frame = cap.read()
if ret == True:
out.write(frame)
cv2.imshow('frame', frame)

key = cv2.waitKey(1)
# ESC
if key == 27:
break

else:
break

cap.release()
out.release()
cv2.destroyAllWindows()
1
cap = cv2.VideoCapture(0)

函數內可放攝影機名稱,需要同步多個鏡頭時可改用cv2.VideoCapture.grab() 和 cv2.VideoCapture.retrieve() 或是放入檔案名稱可以直接讀取檔案,例:cv2.VideoCapture(‘../Resources/Videos/dog.mp4’)

1
out = cv2.VideoWriter('output.avi', fourcc, 20, (640, 480))

儲存影片,函數內參數依序為:影片名稱、影片編碼與解碼的格式、影片的播放速度、影片的長度與寬度

影像加法、加權融合

1
2
3
4
5
6
7
8
9
10
11
12
import cv2
import numpy as np

img = cv2.imread("1.jpeg")

#-------block-------

#------endblock-------

cv2.imshow("windows", img)
cv2.waitKey()
cv2.destroyWindow("windows")

block替換成以下內容可以達到不同效果:

和隨機數值相加

1
2
a = np.random.randint(0, 256, size=img.shape, dtype=np.uint8)
img = cv2.add(img, a)

和全白陣列相加

1
2
3
a = np.ones(img.shape, dtype=np.uint8)
a *= 255
img = cv2.addWeighted(img, 0.8, a, 0.1, 50)

將圖片轉為灰階

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

要注意若是將轉換成灰調影像再轉回成彩色調會發現圖片還是灰階是因為所有的通道值都設為相同的值

將圖片霧化

1
img = cv2.GaussianBlur(img, (7,7), cv2.BORDER_DEFAULT)

(7,7)為kernel的大小,越大圖片越模糊

邊緣偵測

1
img = cv2.Canny(img, 125, 175)

如果先將圖片霧化再進行邊緣偵測所偵測到的邊緣數會變少

膨脹

1
2
img = cv2.Canny(img, 125, 175)
img = cv2.dilate(img, (7,7), iterations=3)

先進行邊緣偵測再把邊緣膨脹

腐蝕

1
2
img = cv2.Canny(img, 125, 175)
img = cv2.erode(img, (7,7), iterations=3)

先進行邊緣偵測再把邊緣腐蝕

影像翻轉、平移、縮放、仿射、裁切

1
2
3
4
5
6
7
8
9
10
11
12
import cv2
import numpy as np

img = cv2.imread("1.jpeg")

#-------block-------

#------endblock-------

cv2.imshow("windows", img)
cv2.waitKey()
cv2.destroyWindow("windows")

block替換成以下內容可以達到不同效果:

影像縮放·

圖片:

1
2
3
4
5
6
7
scale_percent = 60 # percent of original size
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent / 100)
dim = (width, height)
img = cv2.resize(img, dim, interpolation=cv2.INTER_NEAREST)
print('Original Dimensions : ',img.shape)
print('Resized Dimensions : ',dst.shape)

影片縮放(完整程式碼):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import cv2

def rescale(frame, scale=0.75):
width = int(frame.shape[1] * scale)
height = int(frame.shape[0] * scale)
dimesions = (width, height)

return cv2.resize(frame, dimesions, interpolation=cv2.INTER_AREA)

capture = cv2.VideoCapture('dog.mp4')

while True:
isTrue, frame = capture.read()
frame_resize = rescale(frame)
cv2.imshow('video, frame', frame)
cv2.imshow('Video_resize', frame_resize)

if cv2.waitKey(20) & 0xFF==ord('d'):
break

capture.release()
cv2.destroyAllWindows()

scale=0.75代表縮放為原來的0.75倍

影像裁切

1
img = img[50:200, 200:400]

影像翻轉

1
img = cv2.flip(img, 0) 

0 -> x-axis
0+ -> y-axis
0- ->x and y-axis

影像仿射

1
2
3
rows, cols, channel = img.shape
M = np.float32([[1,0,100],[0,1,50]])
img = cv2.warpAffine(img, M, (rows, cols))

影像旋轉

1
2
3
rows, cols, channel = img.shape
M = cv2.getRotationMatrix2D((120, 60), 45, 0.8)
img = cv2.warpAffine(img, M, (rows, cols))

參考

  1. Python-OpenCV — 讀取顯示及儲存影像、影片

  2. Python-OpenCV — 影像運算及轉換

  3. OpenCV Course - Full Tutorial with Python