日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

基于python的移动物体检测_感兴趣区域的移动物体检测,框出移动物体的轮廓 (固定摄像头, opencv-python)...

發(fā)布時間:2025/3/21 python 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于python的移动物体检测_感兴趣区域的移动物体检测,框出移动物体的轮廓 (固定摄像头, opencv-python)... 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

感興趣區(qū)域、特定區(qū)域、框出移動物體的輪廓、越界檢測、入侵物體檢測、使用 opencv-python庫的函數(shù)cv2.findContours、cv2.approxPolyDP、cv2.arcLength,利用固定攝像頭拍攝的實時視頻,框出移動物體的輪廓(即FrogEyes蛙眼移動物體偵測)

對移動目標的輪廓的框選,將使用下面這篇文章提及的方法:曾伊言:邊緣檢測,框出物體的輪廓(使用opencv-python的函數(shù)cv2.findContours() )?zhuanlan.zhihu.com

移動物體框選結(jié)果預(yù)覽(即便鏡頭被移動了,它也能夠自己調(diào)整回來,方法后面會講):https://www.zhihu.com/video/997056905654755328

核心代碼預(yù)覽(可以先看看我用到了哪些函數(shù),完整版代碼(點擊查看)已上傳到github):

...

# 差值提取的核心代碼

dif = np.abs(dif - img_back)

gray = cv2.cvtColor(dif, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, self.min_thresh, 255, 0) # 對差值取閾值,和激活函數(shù)Relu有點像

thresh = cv2.blur(thresh, (self.thresh_blur, self.thresh_blur)) # 模糊的這個操作是很重要的

...

...

# 計算得出輪廓的核心代碼

thresh, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

...

approxs = [cv2.approxPolyDP(cnt, self.min_side_len, True) for cnt in contours]

approxs = [approx for approx in approxs

if len(approx) > self.min_side_num and cv2.arcLength(approx, True) > self.min_poly_len]

contours = approxs

...2018-06-30 初版 Yonv1943

2018-07-02 對RrawROI的注釋方案,即對region_of_interest_pts 的賦值

傳言青蛙蹲在地上不動的時候,將死掉不動的小昆蟲擺放在它的眼前,青蛙也無動于衷。而當(dāng)某些小昆蟲在青蛙眼前飛來飛去的時候,青蛙會注意到它們,然后將它們吃了。我這個程序也可“注意到”鏡頭拍攝到的移動物體,因此我也將它稱為 FrogEyes。

這是傳統(tǒng)的圖像處理(不涉及深度學(xué)習(xí)),所以算法的本質(zhì)是:對固定攝像頭前后兩幀圖片做差值,得到并框出不同的區(qū)域(使用opencv-python 的 cv2.findContours()函數(shù))

因此,該方法只適用于固定鏡頭的移動物體識別,如果拍攝實時圖像的時候鏡頭是移動的,那么此時移動物體的識別就只能交由深度學(xué)習(xí)去解決了。

不能簡單地對比前后兩幀的圖片如果簡單地對比前后兩幀圖片,那么對圖片做差值,將會得到前后幀圖片中不同的區(qū)域,這個區(qū)域并不是目標的輪廓

如果目標是純色的,那么對圖片做差值得到的結(jié)果,將不能得到目標的完整輪廓左邊是背景圖片,右邊是實時圖片

若將實時圖片與背景圖片做差值,那么將會得到紅色區(qū)域

若將實時圖片與先前圖片做差值,那么將會得到黃色區(qū)域

實際情況中,當(dāng)圖片幀率比較高,目標移動速度慢(甚至不移動),由前后兩幀圖片做對比的算法的黃色區(qū)域會非常小。當(dāng)然可以通過對比更久前的圖片(兩幀差別更大)來得到更大的不同區(qū)域,不過,這樣一來,黃色的區(qū)域就不是目標的輪廓了,而是目標在兩個時段區(qū)域的并集。所以,如果事先保存好背景圖片,那么就可以將實時圖片與背景圖片對比,并得到準確的目標輪廓。代碼的流程圖

簡單地設(shè)置背景圖片會來兩個新的問題:若相機視角被移動(比如路過的人不小心碰了一下),那么實時圖片和背景圖片做差值,將會得到整個畫面,目標檢測失效

若背景發(fā)生變化,比如鏡頭中的桌子被移動了,或者環(huán)境光突然發(fā)生變化,或者有目標進入鏡頭后,賴著不走,etc. 那么鏡頭如實將會一直把這變化為框出來,這不智能

這些都是不更新背景圖片導(dǎo)致的,所以要設(shè)置更新背景圖片的策略

下面講流程圖中【對比并有策略地更新背景圖片】的策略:背景圖片更新策略

相關(guān)代碼

由邊緣檢測改寫而來的函數(shù),它根據(jù)輸入的兩張圖片,返回被檢測出的目標輪廓,如果兩張圖片相似,那么就返回一個空列表 [] ,空列表在Python的邏輯判斷中,是False,方便背景圖片更改的邏輯判斷:

def get_polygon_contours(self, img, img_back):

img = np.copy(img)

dif = np.array(img, dtype=np.int16)

dif = np.abs(dif - img_back)

dif = np.array(dif, dtype=np.uint8) # get different

gray = cv2.cvtColor(dif, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, self.min_thresh, 255, 0)

thresh = cv2.blur(thresh, (self.thresh_blur, self.thresh_blur))

if np.max(thresh) == 0: # have not different

contours = [] # 空列表在Python的邏輯判斷中,是False

else:

thresh, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# hulls = [cv2.convexHull(cnt) for cnt, hie in zip(contours, hierarchy[0]) if hie[2] == -1]

# hulls = [hull for hull in hulls if cv2.arcLength(hull, True) > self.min_hull_len]

# contours = hulls

approxs = [cv2.approxPolyDP(cnt, self.min_side_len, True) for cnt in contours]

approxs = [approx for approx in approxs

if len(approx) > self.min_side_num and cv2.arcLength(approx, True) > self.min_poly_len]

contours = approxs

return contours

位于類EdgeDetection 中的 函數(shù)main_get_img_show(),執(zhí)行更換背景的邏輯判斷:

...

contours = self.get_polygon_contours(img, self.img_back) # 這個函數(shù)框出并返回目標輪廓

self.img_list.append(img) # 將實時圖片加入歷史圖片隊列

img_prev = self.img_list.pop(0) # 取出最在的歷史圖片

# 兩個邏輯判斷,決定是否更換背景圖片

# 一個是背景圖片微調(diào),即背景與實時相似的時候,更新背景圖片

# 另一個是背景圖片更換,當(dāng)歷史圖片與實時圖片相似的時候,證明背景已經(jīng)更改一段時間了,因此更新背景

self.img_back = img \

if not contours or not self.get_polygon_contours(img, img_prev) \

else self.img_back

...

需要明白的Python小技巧——空列表在Python的邏輯判斷中,是False

print("[] is %s" % bool([]))

if []:

print("[] is True")

else:

print("[] is False")

如下,被視為背景的卡片移動了,出現(xiàn)兩個框,一段時間后紅框消失,證明背景圖片被更換,伸入手進行測試,其他功能正常:https://www.zhihu.com/video/997434329294729216

還有一個對目標輪廓的篩選過程——根據(jù)輪廓多邊形的邊數(shù)、周長進行篩選:

...

# 在 類的初始化中 def __init__(self, img, roi_pts):

self.min_side_len = int(self.img_len0 / 24) # min side len of polygon

self.min_poly_len = int(self.img_len0 / 12)

self.thresh_blur = int(self.img_len0 / 8)

...

# 在 類的函數(shù) get_polygon_contours() 中

approxs = [cv2.approxPolyDP(cnt, self.min_side_len, True) for cnt in contours]

approxs = [approx for approx in approxs

if len(approx) > self.min_side_num and cv2.arcLength(approx, True) > self.min_poly_len]

contours = approxs

...

視頻的前面幾秒,手指在灰色部分,即ROI(Regin of Interest)以外,沒有觸發(fā)輪廓框選,進入?yún)^(qū)域后,出現(xiàn)了一個四邊形將目標框出,而且周長足夠:https://www.zhihu.com/video/997459527129841664

(從這個視頻中還可以看出,我的移動目標輪廓框選算法還是有疏漏的,比如影子也框進去了、手指退出后,還留有錯誤的紅框)

感興趣區(qū)域的設(shè)定

感興趣區(qū)域的設(shè)定視頻 ↓https://www.zhihu.com/video/997462804596600832

↑ 視頻中的操作:按退格鍵重新劃定ROI ,鼠標點擊定義多邊形,按enter 確認ROI

應(yīng)用討論

移動物體識別的這個特性,在固定攝像頭實時視頻偵測的時候比較有用,比如:監(jiān)控攝像頭,檢測到鏡頭畫面有變化(移動物體出現(xiàn))的時候,才開啟記錄功能,錄下視頻,避免記錄重復(fù)視頻,節(jié)省磁盤空間。(即電子蛙眼)

保留前景,過濾掉無關(guān)的背景。

比較前后幀像素差異算法的缺點 @朱琦

這種方法受光線變化影響非常大。如果我們只想要檢測闖入感興趣區(qū)域的物體,那么這種方法會不可避免地把影子認為是闖入物體。

而深度學(xué)習(xí)目標檢測可以排除這種影響。因此這種算法最好是和深度學(xué)習(xí)相結(jié)合:使用這種像素差異算法進行低準確率的檢測,然后使用深度學(xué)習(xí)進行最終的判斷。如:對于畫面長時間持續(xù)不動的多個攝像頭,我們使用像素差異算法進行檢測,當(dāng)檢測到有物體闖入時,程序?qū)惓蠼o給深度學(xué)習(xí)卷積網(wǎng)絡(luò),由它進行把關(guān)。(這樣子可以減少計算,同時維持判斷精度。例如:車庫車輛檢測,異常闖入檢測)。

用在自動生成訓(xùn)練集上:(自從2018年數(shù)據(jù)集逐漸完善、以及半監(jiān)督算法的發(fā)展,以下方法已經(jīng)過時)

將要識別的物體放在鏡頭前,不斷地移動物體(最好是換不同高度環(huán)繞拍攝),識別出物體輪廓,處理成邊緣羽化的png圖片,然后和其他背景合成大量訓(xùn)練集(此時可以通過輪廓輸出框選完畢的box,再批量創(chuàng)建label,自動導(dǎo)出成為xml格式,就可以為所欲為了)(可以看我的另外一篇:利用初步訓(xùn)練的深度學(xué)習(xí)模型自動生成訓(xùn)練圖片,包括csv文件、Python字典、TensorFlow目標檢測訓(xùn)練圖片xml注釋 相互轉(zhuǎn)換(還沒寫完))

用傳統(tǒng)圖像識別將目標準確框出,并過濾掉背景,傳給目標檢測模型,甚至可以取代目標檢測提取候選框的那一步,將目標檢測的工作,從:生成候選框 → 分類器處理多個候選框,得到類別匹配度信息 →

計算匹配度,篩選出得分高的目標 → 調(diào)整對應(yīng)候選框的位置 →

輸出目標及對應(yīng)的候選框

簡化為:傳統(tǒng)圖形識別框出待分類的目標移動目標 →

分類器計算目標匹配度,判斷目標類別 →

輸出目標輪廓,以及目標的類別

簡化的內(nèi)容如下:簡化目標檢測的任務(wù):從“判斷目標位置,確定目標類型”簡化為“判斷目標類型”

處理的圖片變小了:從原來的全圖檢測 縮減為對移動目標對應(yīng)圖片的檢測

減小背景的影響:框出移動目標輪廓,并刪去背景,減少了影響分類判斷的干擾因素

在縮小了目標檢測應(yīng)用范圍的情況下(只能用來檢測固定鏡頭的移動物體/入侵物體,用在安防攝像頭上面最好了),預(yù)計這樣子處理可以減少計算量,提高檢測準確率。

用在固定攝像頭實時目標檢測上:(自2018年Mask-RCNN發(fā)展成熟后,以下方法已過時)

移動物體框選結(jié)果預(yù)覽(深度學(xué)習(xí)結(jié)合目標檢測結(jié)合(這里用的是Yolo目標檢測),假裝把segmentation 做出來了)

參考資料:

在評論區(qū)指出的問題,我會修改到正文中,并注明貢獻者的名字。

在評論區(qū)提出的問題,我可能會嘗試解答,并添加到正文中。

交流可以促進社區(qū)與自身成長,歡迎評論,謝謝大家。

總結(jié)

以上是生活随笔為你收集整理的基于python的移动物体检测_感兴趣区域的移动物体检测,框出移动物体的轮廓 (固定摄像头, opencv-python)...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。