# 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 解析圖片的是幾格* 幾格的架構,如下圖 ![](https://i.imgur.com/gXEZ7qU.png) 舉例來說,"3"這個數字在10* 10的顯示方式可以用下圖來代表 ![](https://i.imgur.com/nq1zStt.png) 規格 px * px VGA = 640 * 480 HD = 1280 * 720 FHD = 1920 * 1080 4K = 3840 * 2160 #### gray Binary Image ![](https://i.imgur.com/77dvoDb.png) this is a 2 levels image 0 = black 1 = white ![](https://i.imgur.com/QaGW3Hw.png) More levels mean more clear levels 就是黑到白分成幾階 目前總共會有0-255的分別 套用在RGB也是一樣用0-255來調整顏色 ![](https://i.imgur.com/ve2DU7D.png) 所以我們可以稱呼 ![](https://i.imgur.com/TFNsD8h.png) 這張圖片是"8bits" 或是 "256Levels" #### RGB ![](https://i.imgur.com/I7fwdV0.png) 可以看到合在一起就是原圖 ![](https://i.imgur.com/feD2UNH.png) 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前 ![](https://i.imgur.com/Jf3CWgO.png) blur後 ![](https://i.imgur.com/OMb4Ycz.png) ```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) ``` 閾值適當 ![](https://i.imgur.com/nSawpfF.png) 閾值過低 ![](https://i.imgur.com/KDeUzdU.png) <hr> ## Ch2 ### Basic Functions 座標化 ![](https://i.imgur.com/ZSBnXWP.png) ```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後 ![](https://i.imgur.com/u2N5f4C.png) 用途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後 ![](https://i.imgur.com/fgdbeoc.png) 用途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) ![](https://i.imgur.com/UGc2EAV.png) (300,200) ![](https://i.imgur.com/1Gd82zg.png) ```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 ![](https://i.imgur.com/72uJOBP.png) after ![](https://i.imgur.com/USJNyi3.png) <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 ![](https://i.imgur.com/0xFPRDi.png) 加上線條 ![](https://i.imgur.com/mF2xAwb.png) 另一種方法畫線 ![](https://i.imgur.com/4sQ7lqT.png) 正方形 ![](https://i.imgur.com/6xMAPpx.png) 圓 ![](https://i.imgur.com/nxjM1WY.png) Text ![](https://i.imgur.com/GPvrgPD.png) <hr> ## Ch5 ### Warp Prespective 範例圖片 ![](https://i.imgur.com/HZy5r2w.png) ```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(畫面左下角) ![](https://i.imgur.com/t8C5Tlp.png) output #圖片座標跟影片中不一樣,請用小畫家來確認座標 ![](https://i.imgur.com/yyGRqU6.png) [參考 透視變換](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) ``` 兩張圖片顯示在一個視窗 水平 ![](https://i.imgur.com/tTGwKjy.png) 垂直 ![](https://i.imgur.com/tGrJYID.png) 同時顯示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 ![](https://i.imgur.com/tKxaNGU.png) <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後 ![](https://i.imgur.com/5UDZ3B2.png) ```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 ![](https://i.imgur.com/22UaI4Z.png) 建立一個mask來顯示調整成果 ![](https://i.imgur.com/UsXrdR6.png) 這是調整V min的成果 ![](https://i.imgur.com/5FEfRoU.png) ```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 ![](https://i.imgur.com/dkKjxLI.png) 調整bar的值也可以同步調整stack的圖 <hr> ## Ch8 ### Contour / Shape Detection 範例圖片 ![](https://i.imgur.com/6go22uR.png) ```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 ![](https://i.imgur.com/lTl0uWU.png) ```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 ![](https://i.imgur.com/H1r3rNI.png) ```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 ![](https://i.imgur.com/YIbi4zo.png) ```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 的長度,用方形框起來 ![](https://i.imgur.com/A9YFtUA.png) ```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) ``` 判斷邊數來顯示字 ![](https://i.imgur.com/AiJKcNZ.png) ```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 ,判定圖形名稱 ![](https://i.imgur.com/wPtSGXA.png) <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) ``` 人臉辨識 ![](https://i.imgur.com/8K5W6OT.png) <hr> ## Projects1 ### Virtual Paint ## Projects2 ### Paper Scanner ## Projects3 ### Number Plate Detector