git:https://github.com/linyi0604/Computer-Vision
思路: 開啟攝像頭后 設置一個當前幀為背景, 在之后檢測到的幀都與背景對比不同,對不同的地方進行檢測
1 # coding:utf-8
2
3 """
4 計算幀之間的差異 考慮背景幀與其他幀之間的差異 5 """
6
7 import cv2 8 import numpy as np 9
10 # 調用攝像頭
11 camera = cv2.VideoCapture(0) 12
13
14 kernel = np.ones((5, 5), np.uint8) 15 background = None 16
17 while True: 18 # 讀入攝像頭的幀
19 ret, frame = camera.read() 20 # 把第一幀作為背景
21 if background is None: 22 background = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 23 background = cv2.GaussianBlur(background, (21, 21), 0) 24 continue
25 # 讀入幀
26 gray_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) 27 # 高斯平滑 模糊處理 減小光照 震動等原因產生的噪聲影響
28 gray_frame = cv2.GaussianBlur(gray_frame, (21, 21), 0) 29
30 # 檢測背景和幀的區別
31 diff = cv2.absdiff(background, gray_frame) 32 # 將區別轉為二值
33 diff = cv2.threshold(diff, 25, 255, cv2.THRESH_BINARY)[1] 34 # 定義結構元素
35 es = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (9, 4)) 36 # 膨脹運算
37 diff = cv2.dilate(diff, es, iterations=2) 38 # 搜索輪廓
39 image, cnts, hierarcchy = cv2.findContours(diff.copy(), 40 cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) 41 """
42 cv.findContours() 43 參數: 44 1 要尋找輪廓的圖像 只能傳入二值圖像,不是灰度圖像 45 2 輪廓的檢索模式,有四種: 46 cv2.RETR_EXTERNAL表示只檢測外輪廓 47 cv2.RETR_LIST檢測的輪廓不建立等級關系 48 cv2.RETR_CCOMP建立兩個等級的輪廓,上面的一層為外邊界, 49 里面的一層為內孔的邊界信息。 50 如果內孔內還有一個連通物體,這個物體的邊界也在頂層 51 cv2.RETR_TREE建立一個等級樹結構的輪廓 52 3 輪廓的近似辦法 53 cv2.CHAIN_APPROX_NONE存儲所有的輪廓點, 54 相鄰的兩個點的像素位置差不超過1, 55 即max(abs(x1-x2),abs(y2-y1))==1 56 cv2.CHAIN_APPROX_SIMPLE壓縮水平方向,垂直方向,對角線方向的元素, 57 只保留該方向的終點坐標,例如一個矩形輪廓只需4個點來保存輪廓信息 58 返回值: 59 contours:一個列表,每一項都是一個輪廓, 不會存儲輪廓所有的點,只存儲能描述輪廓的點 60 hierarchy:一個ndarray, 元素數量和輪廓數量一樣, 61 每個輪廓contours[i]對應4個hierarchy元素hierarchy[i][0] ~hierarchy[i][3], 62 分別表示后一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號,如果沒有對應項,則該值為負數 63 """
64 for c in cnts: 65 # 輪廓太小忽略 有可能是斑點噪聲
66 if cv2.contourArea(c) < 1500: 67 continue
68 # 將輪廓畫出來
69 (x, y, w, h) = cv2.boundingRect(c) 70 cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2) 71
72 cv2.imshow("contours", frame) 73 cv2.imshow("diff", diff) 74 if cv2.waitKey(5) & 0xff == ord("q"): 75 break
76
77 cv2.destroyAllWindows() 78 camera.release()