# Open CV 三小時基礎
# [作者的github](https://github.com/murtazahassan/Learn-OpenCV-in-3-hours/blob/master/chapter8.py)
# [影片連結](https://www.youtube.com/watch?v=WQeoO7MI0Bs&t=5543s)
###### tags: `自己加油`
## Ch1
### Read Images Videos and Webcams
解析圖片的是幾格* 幾格的架構,如下圖

舉例來說,"3"這個數字在10* 10的顯示方式可以用下圖來代表

規格 px * px
VGA = 640 * 480
HD = 1280 * 720
FHD = 1920 * 1080
4K = 3840 * 2160
#### gray
Binary Image

this is a 2 levels image
0 = black
1 = white

More levels mean more clear
levels 就是黑到白分成幾階
目前總共會有0-255的分別
套用在RGB也是一樣用0-255來調整顏色

所以我們可以稱呼

這張圖片是"8bits" 或是 "256Levels"
#### RGB

可以看到合在一起就是原圖

RGB套用到VGA 裡面,就會有640 * 480 * 3
接下來是一個簡單的印出灰階圖片的程式
```python=
import cv2
img = cv2.imread("C:\\Users\\User\\Downloads\\IMG20210607233134.jpg")
#讓cv讀取圖片,括號裡面打檔案path
#圖片尺寸要挑好
#檔案路徑要用\\或/
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#把img的RGB轉成GRAY
cv2.imshow("Gray Image",imgGray)
#"Gray Image"是顯示的圖片的名稱
#imgGray檔案
cv2.waitKey(0)
```
Blur 處理
```python=
import cv2
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#把img的RGB轉成GRAY
imgBlur = cv2.GaussianBlur(imgGray,(7,7),0)
#7,7是ksize(kernal size),會模糊化
#0是sigmaX ,調X軸的標準差
cv2.imshow("Blur Image",imgBlur)
#印降解析後的
cv2.imshow("Gray Image",imgGray)
#印灰階的
cv2.waitKey(0)
```
blur前

blur後

```python=
import cv2
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
imgCanny = cv2.Canny(img,700,700)
imgCanny2 = cv2.Canny(img,15,20)
#Canny採用雙閾值
#設置的閾值過高,可能會漏掉重要信息
#閾值過低,將會把枝節信息看得很重要。
cv2.imshow("Canny Image",imgCanny)
cv2.imshow("Canny2 Image",imgCanny2)
cv2.waitKey(0)
```
閾值適當

閾值過低

<hr>
## Ch2
### Basic Functions
座標化

```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
kernel = np.ones((5,5),np.uint8)
#有符號: int8, int16, int32, int64
#無符號: uint8, uint16, uint32, uint64
#依據平台自動對應上面的其中一個,例如在32位元系統和64位元系統上使用int的長度就會不同
imgCanny = cv2.Canny(img,700,700)
imgDialation = cv2.dilate(imgCanny,kernel,iterations=1)#迭代一次
#迭代會重複執行,逐漸接近目標
cv2.imshow("Dialation Image",imgDialation)
cv2.waitKey(0)
```
dilate後

用途1:Dilation 影像膨脹通常是配合著影像侵蝕 Erosion 使用,先使用侵蝕的方式使影像中的線條變窄,同時也去除雜訊,之後再透過 Dilation 將影像膨脹回來。
用途2:用來連接兩個很靠近但分開的物體。
```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
kernel = np.ones((5,5),np.uint8)
#有符號: int8, int16, int32, int64
#無符號: uint8, uint16, uint32, uint64
#依據平台自動對應上面的其中一個,例如在32位元系統和64位元系統上使用int的長度就會不同
imgCanny = cv2.Canny(img,700,700)
imgDialation = cv2.dilate(imgCanny,kernel,iterations=1)#迭代一次
imgErode = cv2.erode(imgDialation,kernel,iterations=1)
cv2.imshow("Dialation Image",imgDialation)
cv2.imshow("ErodeImage",imgErode)
cv2.waitKey(0)
```
Erode後

用途1:Erosion 影像侵蝕對於移除影像中的小白雜點很有幫助,可用來去噪,例如影像中的小雜點,雜訊。
用途2:細化影像,消除毛刺。
<hr>
## Ch3
### Resizing and Cropping
```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
print(img.shape)
#以 cv2.imread 讀進來的資料,會儲存成一個 NumPy 的陣列
#此 NumPy 陣列的前兩個維度分別是圖片的高度與寬度,第三個維度則是圖片的 channel(RGB 彩色圖片的 channel 是 3,灰階圖片則為 1)。
imgResize = cv2.resize(img,(300,200))
cv2.imshow("ErodeImage",img)
cv2.imshow("imgResize",imgResize)
cv2.waitKey(0)
```
Numpy array更改
(221,228,3)

(300,200)

```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
imgCropped = img[0:300,200:500]
# 裁切區域的 x 與 y 座標(左上角)
#x = 100
#y = 100
# 裁切區域的長度與寬度
#w = 250
#h = 150
# 裁切圖片
#crop_img = img[y:y+h, x:x+w]
cv2.imshow("ErodeImage",img)
cv2.imshow("imgCropped",imgCropped)
cv2.waitKey(0)
```
before

after

<hr>
## Ch4
### Shapes and Text
```python=
import cv2
import numpy as np
img = np.zeros((512,512,3),np.uint8)
#zero = black
#512,512 means size (px)
print(img)
#print 很多frame
#print出的frame代表RGB三層的DATA
#目前的圖片是全黑,所以三層都是[0 0 0]
#順序BGR
#所以調成[255 0 0]
img[0:200,200:500]=255,0,0#就會是blue
#加上一個blue的mask
#[]內是尺寸
#如果寫img[:]=255,0,0
#就會全覆蓋
cv2.line(img,(0,0),(300,300),(0,255,0),3)
#放在img上
#start (0,0)
#end (300,300)
#color (0,255,0)
#thickness 3
cv2.line(img,(0,0),(img.shape[1],img.shape[0]),(255,0,0),3)
#img.shape[1] --> weigh
#img.shape[0] --> heigh
#跟著圖片大小做縮放
cv2.rectangle(img,(0,0),(150,250),(0,0,255),3)
#如果thickness欄位改成cv2.FILLED,效果是填滿
cv2.circle(img,(150,250),50,(0,255,255),3)
#起始點(150,250)
#半徑50
cv2.putText(img,"test",(150,300),cv2.FONT_HERSHEY_TRIPLEX,1,(0,150,150),2)
#顯示test
#起始點(150,300)
#font = cv2.FONT_HERSHEY_TRIPLEX
#scale = 1
#color
#thickness
print(img.shape)
#print (512,512)
cv2.imshow("Image",img)
cv2.waitKey(0)
```
加上一個藍色mask

加上線條

另一種方法畫線

正方形

圓

Text

<hr>
## Ch5
### Warp Prespective
範例圖片

```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\cards.jpg")
width,height = 250,350
pts1 = np.float32([[111,219],[287,188],[154,482],[352,440]])
#four points value -->use paint open the image
#訂出圖片的四角座標來做其他調整
pts2 = np.float32([[0,0],[width,0],[0,height],[width,height]])
#width,height 要另外定義
matrix = cv2.getPerspectiveTransform(pts1,pts2)
#透視變換matrix
#input: 欲顯示片段的四點座標 , 轉換視角後的座標
imgOutput = cv2.warpPerspective(img,matrix,(width,height))
#要有matrix才能做變換
cv2.imshow("Image",img)
cv2.imshow("o Image",imgOutput)
cv2.waitKey(0)
```
得到圖片座標
用小畫家開啟圖片,游標的位置會顯示x,y的px(畫面左下角)

output
#圖片座標跟影片中不一樣,請用小畫家來確認座標

[參考 透視變換](https://blog.csdn.net/guduruyu/article/details/72518340)
<hr>
## Ch6
### Joining Images
```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
imgHor = np.hstack((img,img))
#水平
imgVer = np.vstack((img,img))
#垂直
cv2.imshow("Horizontal",imgHor)
cv2.imshow("Vertical",imgVer)
cv2.waitKey(0)
```
兩張圖片顯示在一個視窗
水平

垂直

同時顯示gray跟BGR的function
```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
#請去github複製
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
imgGray= cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#這個function可以同時處理gray跟BGR
imgStack = stackImages(0.5,([img,img,img],[imgGray,img,img]))
#調用stackImage
#兩個輸入值
#scale 0.5
#row ,column 隨意調整
cv2.imshow("imgStack",imgStack)
cv2.waitKey(0)
```
包含gray跟BGR的stack

<hr>
## Ch7
### Color Detection
HSV即色相、飽和度、明度
```python=
import cv2
import numpy as np
img = cv2.imread("C:\\Users\\User\\Desktop\\test.png")
imgHSV= cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
cv2.imshow("imgHSV",imgHSV)
cv2.waitKey(0)
```
HSV後

```python=
import cv2
import numpy as np
path = ("C:\\Users\\User\\Desktop\\test.png")
img = cv2.imread(path)
def empty(a):
pass
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,240)
cv2.createTrackbar("Hue Min","TrackBars",0,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",179,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",0,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",255,255,empty)
cv2.createTrackbar("Val Min","TrackBars",0,255,empty)
cv2.createTrackbar("Val Max","TrackBars",255,255,empty)
#0是起始值
#179是最大值
while True:
img = cv2.imread(path)
imgHSV= cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
h_max = cv2.getTrackbarPos("Hue Max","TrackBars")
s_min = cv2.getTrackbarPos("Sat Min","TrackBars")
s_max = cv2.getTrackbarPos("Sat Max","TrackBars")
v_min = cv2.getTrackbarPos("Val Min","TrackBars")
v_max = cv2.getTrackbarPos("Val Max","TrackBars")
print(h_min,h_max,s_min,s_max,v_min,v_max)
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(imgHSV,lower, upper)
cv2.imshow("imgHSV",imgHSV)
cv2.imshow("mask",mask)
cv2.waitKey(1)
```
建立一個bar來調整HSV

建立一個mask來顯示調整成果

這是調整V min的成果

```python=
import cv2
import numpy as np
path = ("C:\\Users\\User\\Desktop\\test.png")
img = cv2.imread(path)
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def empty(a):
pass
cv2.namedWindow("TrackBars")
cv2.resizeWindow("TrackBars",640,240)
cv2.createTrackbar("Hue Min","TrackBars",0,179,empty)
cv2.createTrackbar("Hue Max","TrackBars",179,179,empty)
cv2.createTrackbar("Sat Min","TrackBars",0,255,empty)
cv2.createTrackbar("Sat Max","TrackBars",255,255,empty)
cv2.createTrackbar("Val Min","TrackBars",100,255,empty)
cv2.createTrackbar("Val Max","TrackBars",255,255,empty)
#0是起始值
#179是最大值
while True:
img = cv2.imread(path)
imgHSV= cv2.cvtColor(img,cv2.COLOR_BGR2HSV)
h_min = cv2.getTrackbarPos("Hue Min","TrackBars")
h_max = cv2.getTrackbarPos("Hue Max","TrackBars")
s_min = cv2.getTrackbarPos("Sat Min","TrackBars")
s_max = cv2.getTrackbarPos("Sat Max","TrackBars")
v_min = cv2.getTrackbarPos("Val Min","TrackBars")
v_max = cv2.getTrackbarPos("Val Max","TrackBars")
#print(h_min,h_max,s_min,s_max,v_min,v_max)
lower = np.array([h_min,s_min,v_min])
upper = np.array([h_max,s_max,v_max])
mask = cv2.inRange(imgHSV,lower, upper)
imgResult = cv2.bitwise_and(img,img,mask=mask)
cv2.imshow("img",img)
cv2.imshow("imgHSV",imgHSV)
cv2.imshow("mask",mask)
cv2.imshow("result",imgResult)
imgStack = stackImages(0.6,([img,imgHSV],[mask,imgResult]))
cv2.imshow("stack",imgStack)
#如果按下ESC键,就退出
if cv2.waitKey(10) == 27:
break
#關閉所有視窗
cv2.destroyAllWindows()
```
把四張圖放上同一個stack

調整bar的值也可以同步調整stack的圖
<hr>
## Ch8
### Contour / Shape Detection
範例圖片

```python=
import cv2
import numpy as np
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def getContours(img):#define a function named "getContours"
countours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in countours:
area = cv2.contourArea(cnt)
print(area)
path = ("C:\\Users\\User\\Desktop\\shape.png")
img = cv2.imread(path)
imgGray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)
getContours(imgCanny)
imgStack = stackImages(0.6,([img,imgGray,imgBlur],[imgCanny,img,img]))
cv2.imshow("Stack",imgStack)
cv2.waitKey(0)
```
算出area

```python=
import cv2
import numpy as np
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def getContours(img):
countours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in countours:
area = cv2.contourArea(cnt)
print(area)
cv2.drawContours(imgContour,cnt,-1,(255,0,0),3)
#contour index =-1,means draw all the contours
#thickness =3
path = ("C:\\Users\\User\\Desktop\\shape.png")
img = cv2.imread(path)
imgContour = img.copy()
imgGray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)
getContours(imgCanny)
imgStack = stackImages(0.6,([img,imgCanny,imgContour]))
cv2.imshow("Stack",imgStack)
cv2.waitKey(0)
```
用area來draw

```python=
import cv2
import numpy as np
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def getContours(img):
countours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in countours:
area = cv2.contourArea(cnt)
print(area)
if area>500:
cv2.drawContours(imgContour,cnt,-1,(255,0,0),3)
#contour index =-1,means draw all the contours
#thickness =3
peri = cv2.arcLength(cnt,True)
print(peri)
#印出length
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
print(approx)
#印出圖形的point
path = ("C:\\Users\\User\\Desktop\\shape.png")
img = cv2.imread(path)
imgContour = img.copy()
imgGray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)
getContours(imgCanny)
imgStack = stackImages(0.6,([img,imgCanny,imgContour]))
cv2.imshow("Stack",imgStack)
cv2.waitKey(0)
```
知道圖形的area,lenght,point

```python=
import cv2
import numpy as np
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def getContours(img):
countours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in countours:
area = cv2.contourArea(cnt)
print(area)
if area>500:
cv2.drawContours(imgContour,cnt,-1,(255,0,0),3)
#contour index =-1,means draw all the contours
#thickness =3
peri = cv2.arcLength(cnt,True)
print(peri)
#印出length
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
print(approx)
objCor = len(approx)
x,y,w,h = cv2.boundingRect(approx)
cv2.rectangle(imgContour,(x,y),(x+w,y+h),(255,0,0),2)
path = ("C:\\Users\\User\\Desktop\\shape.png")
img = cv2.imread(path)
imgContour = img.copy()
imgGray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)
getContours(imgCanny)
imgStack = stackImages(0.6,([img,imgCanny,imgContour]))
cv2.imshow("Stack",imgStack)
cv2.waitKey(0)
```
知道approx 的長度,用方形框起來

```python=
import cv2
import numpy as np
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def getContours(img):
countours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in countours:
area = cv2.contourArea(cnt)
print(area)
if area>500:
cv2.drawContours(imgContour,cnt,-1,(255,0,0),3)
#contour index =-1,means draw all the contours
#thickness =3
peri = cv2.arcLength(cnt,True)
print(peri)
#印出length
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
print(approx)
objCor = len(approx)
x,y,w,h = cv2.boundingRect(approx)
#設定一個object,如果邊數=3,印出tri
if objCor == 3:ObjectType = "Tri"
else:ObjectType = "None"
cv2.rectangle(imgContour,(x,y),(x+w,y+h),(255,0,0),2)
cv2.putText(imgContour,ObjectType,(x+(w//2)-10,y+(h//2)-10),cv2.FONT_HERSHEY_COMPLEX,0.5,(0,255,0),2)
#Text要顯示在圖形的哪裡
path = ("C:\\Users\\User\\Desktop\\shape.png")
img = cv2.imread(path)
imgContour = img.copy()
imgGray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)
getContours(imgCanny)
imgStack = stackImages(0.6,([img,imgCanny,imgContour]))
cv2.imshow("Stack",imgStack)
cv2.waitKey(0)
```
判斷邊數來顯示字

```python=
import cv2
import numpy as np
def stackImages(scale,imgArray):
rows = len(imgArray)
cols = len(imgArray[0])
rowsAvailable = isinstance(imgArray[0], list)
width = imgArray[0][0].shape[1]
height = imgArray[0][0].shape[0]
if rowsAvailable:
for x in range ( 0, rows):
for y in range(0, cols):
if imgArray[x][y].shape[:2] == imgArray[0][0].shape [:2]:
imgArray[x][y] = cv2.resize(imgArray[x][y], (0, 0), None, scale, scale)
else:
imgArray[x][y] = cv2.resize(imgArray[x][y], (imgArray[0][0].shape[1], imgArray[0][0].shape[0]), None, scale, scale)
if len(imgArray[x][y].shape) == 2: imgArray[x][y]= cv2.cvtColor( imgArray[x][y], cv2.COLOR_GRAY2BGR)
imageBlank = np.zeros((height, width, 3), np.uint8)
hor = [imageBlank]*rows
hor_con = [imageBlank]*rows
for x in range(0, rows):
hor[x] = np.hstack(imgArray[x])
ver = np.vstack(hor)
else:
for x in range(0, rows):
if imgArray[x].shape[:2] == imgArray[0].shape[:2]:
imgArray[x] = cv2.resize(imgArray[x], (0, 0), None, scale, scale)
else:
imgArray[x] = cv2.resize(imgArray[x], (imgArray[0].shape[1], imgArray[0].shape[0]), None,scale, scale)
if len(imgArray[x].shape) == 2: imgArray[x] = cv2.cvtColor(imgArray[x], cv2.COLOR_GRAY2BGR)
hor= np.hstack(imgArray)
ver = hor
return ver
def getContours(img):
countours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
for cnt in countours:
area = cv2.contourArea(cnt)
print(area)
if area>500:
cv2.drawContours(imgContour,cnt,-1,(255,0,0),3)
#contour index =-1,means draw all the contours
#thickness =3
peri = cv2.arcLength(cnt,True)
print(peri)
#印出length
approx = cv2.approxPolyDP(cnt,0.02*peri,True)
print(approx)
objCor = len(approx)
x,y,w,h = cv2.boundingRect(approx)
#設定一個object,如果邊數=3,印出tri
if objCor == 3:ObjectType = "Tri"
elif objCor == 4:
aspRatio = w/float(h)
if aspRatio >0.95 and aspRatio <1.05 :ObjectType="Square"
else:ObjectType = "Rectangle"
elif objCor > 4:ObjectType = "Circle"
else:ObjectType = "None"
cv2.rectangle(imgContour,(x,y),(x+w,y+h),(255,0,0),2)
cv2.putText(imgContour,ObjectType,(x+(w//2)-10,y+(h//2)-10),cv2.FONT_HERSHEY_COMPLEX,0.5,(0,255,0),2)
#Text要顯示在圖形的哪裡
path = ("C:\\Users\\User\\Desktop\\shape.png")
img = cv2.imread(path)
imgContour = img.copy()
imgGray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
imgBlur = cv2.GaussianBlur(imgGray,(7,7),1)
imgCanny = cv2.Canny(imgBlur,50,50)
getContours(imgCanny)
imgStack = stackImages(0.6,([img,imgCanny,imgContour]))
cv2.imshow("Stack",imgStack)
cv2.waitKey(0)
```
用if elif else ,判定圖形名稱

<hr>
## Ch9
### Face Detection
```mermaid
graph LR
A[Positives Faces] --> B[Train] --> D[XML File]
C[Negatives Non Faces] -->B
```
```python=
import cv2
import numpy as np
faceCascade = cv2.CascadeClassifier("C:\\Users\\User\\Desktop\\haarcascade_frontalface_default.xml")
#
path = ("C:\\Users\\User\\Desktop\\lena.jpg")
img = cv2.imread(path)
呼叫model
imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
faces = faceCascade.detectMultiScale(imgGray,1.1,4)
for (x,y,w,h) in faces:
cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,0),2)
cv2.imshow("Result", img)
cv2.waitKey(0)
```
人臉辨識

<hr>
## Projects1
### Virtual Paint
## Projects2
### Paper Scanner
## Projects3
### Number Plate Detector