通過 Python 和 OpenCV 實現目標數量監控
今天我們將利用python+OpenCV實現對視訊中物體數量的監控,達到視訊監控的效果,比如洗煤廠的監控水龍頭的水柱顏色,當水柱為黑色的超過了一半,那麼將說明過濾網發生了故障。當然不僅如此,我們看的是影象視訊處理的技巧,你也可以將專案遷移到其他地方等,這僅僅是一個例子而已。我們知道計算機視覺中關於影象識別有四大類任務:
。
分類-Classification:解決“是什麼?”的問題,即給定一張圖片或一段視訊判斷裡面包含什麼類別的目標。
定位-Location:解決“在哪裡?”的問題,即定位出這個目標的的位置。
檢測-Detection:解決“是什麼?在哪裡?”的問題,即定位出這個目標的的位置並且知道目標物是什麼。
分割-Segmentation:分為例項的分割(Instance-level)和場景分割(Scene-level),解決“每一個畫素屬於哪個目標物或場景”的問題。
而定位不僅需要找到物體的位置在哪裡,還需要能夠統計目標的數目以及物體狀態。
除了影象分類以外,目標檢驗要解決問題的架構難題是:
1.目標有可能經常出現在影像的任何方位;
2.目標有各種有所不同的尺寸;
3.目標有可能有各種有所不同的外形。
如果用矩形框來界定目的,則長方形有有所不同的清晰度。由於目的的清晰度有所不同,因此使用經典之作的轉動視窗+影像圖形的計劃解決問題標準化目的檢驗難題的生產成本太低。近幾年來,目標檢測演算法取得了很大的突破。比較流行的演算法可以分為兩類,一類是基於Region Proposal的R-CNN系演算法(R-CNN,Fast R-CNN,Faster R-CNN等),它們是two-stage的,需要先演算法產生目標候選框,也就是目標位置,然後再對候選框做分類與迴歸。而另一類是Yolo,SSD這類one-stage演算法,其僅僅使用一個卷積神經網路CNN直接預測不同目標的類別與位置。第一類方法是準確度高一些,但是速度慢,但是第二類演算法是速度快,但是準確性要低一些。那麼今天我們的專案並不會太多的講解各種演算法,而是我們的核心主題,目標數量識別。
那麼我們將如何進行實現呢
多說無益,下面可以開始實現我們的專案。
首先匯入相關的庫
import cv2 from PIL import Image from PIL import ImageDraw,ImageFont import numpy as np
接著我們需要把水龍頭流出水柱的部分提取出來,即需要把圖片預先處理成這樣,作為背景圖來用,名為3ji.jpg如圖所示:
然後通過影象作差的方法找到水柱的部分,首先就需要將影象轉彩灰度圖然後高斯模糊便於計算,當然其實不這樣也是可以的。其中2.jpg是測試的圖片,
程式碼如下:
'''3ji是背景圖不可換,除錯換另一個圖片,3ji自己用畫圖找到水的位置清除掉水柱即可,所以說攝像頭不能動''' firstframe=cv2.imread("3ji.jpg") firstframe= cv2.cvtColor(firstframe,cv2.COLOR_BGR2GRAY) firstframe= cv2.GaussianBlur(firstframe,(21,21),0) secondframe0=cv2.imread("2.jpg") secondframe0= cv2.cvtColor(secondframe0,cv2.COLOR_BGR2GRAY) secondframe= cv2.GaussianBlur(secondframe0,0) frameDelta = cv2.absdiff(firstframe,secondframe) x,y=frameDelta.shape print(x,y)
接著通過邊緣檢測找到水柱邊界,方便檢視。
#frameDelta和canny一個是區域一個是輪廓 img = cv2.GaussianBlur(frameDelta,(3,3),0) canny = cv2.Canny(img,100)
定義水柱總面積變數。清水面積變數,ss陣列儲存畫素值位置
area=0 #6687,總面積 qingarea=0 ss=[]
然後畫出輪廓,並記錄水柱處畫素值得位置
#畫輪廓,儲存要識別的畫素值位置,記錄在ss陣列中 for i in range(x): for j in range(y): if any(frameDelta[i,j]!=[0,0]):#白色的時候,佔位 ss.append([i,j])
然後以原圖加輪廓圖顯示,圖片相加即可:
canny0=cv2.add(secondframe0,canny)
接著根據畫素值大小判斷顏色,通過除錯這個專案的閾值是50
#判斷水柱顏色,清水佔多少畫素 for t in ss: k,l=t area=area+1 if canny0[k,l] > 50: print(canny0[k,l]) qingarea+=1 接著統計黑色水柱佔比率為多少 deta=(qingarea/area)*100 print(qingarea) pred="清水佔比為"+str(deta)+"%" print(pred)
最後輸出影象結果:
cv2.imwrite("pred.jpg",canny0) canny0=cv2.imread("pred.jpg") img_PIL = Image.fromarray(cv2.cvtColor(canny0,cv2.COLOR_BGR2RGB)) myfont = ImageFont.truetype(r'C:/Windows/Fonts/simfang.ttf',40) draw = ImageDraw.Draw(img_PIL) draw.text((200,10),pred,font=myfont,fill=(255,23,140)) img_OpenCV = cv2.cvtColor(np.asarray(img_PIL),cv2.COLOR_RGB2BGR) cv2.imshow("frame",img_OpenCV) key = cv2.waitKey(0)
最終達到的演示效果如圖所示:
清水佔比96%,還是比較準確的
清水佔比38%,黑水佔比62%,也基本準確。
當然這僅僅是一個思路的問題,至少目前為止網上還沒有對物體數目去監控的專案例子,儘管並不是如此高深,但是卻是一個很好的探究方向。不僅僅是智慧採礦的需要,也可以是智慧農業或者智慧畜牧業等方面監控的一個想法。當然大家也是可以再次基礎上修改完善程式碼,完整的程式碼上面已經給出。伴隨著移動網際網路、手機及各交友的平臺的較慢持續發展,照片的廣泛傳播幅度大大增強,廣泛傳播範圍內也日益擴充套件。比起書寫、視訊、錄影等廣泛傳播方式,照片廣泛傳播極具“點睛”視覺效果,合乎節奏貧困下人們高效的讀者方法。
當照片給人們帶給快捷的資料紀錄和共享方法的同時,照片普遍地廣泛傳播在社會大眾視線下,適當的難題也接踵而來。書寫記述,使用者可以精彩通過關鍵字搜尋提供意願資料,而當照片記述,使用者難以必要通過搜尋照片索引到可藉助資料。
科技進步的變革常常與解決的表達意見如影隨形,在使用者痛點下,亟需高科技的改進創意,此自然環境下湧現的影象識別新技術之後變得尤為重要。由此也可見計算機視覺的日益高漲的地位。
總結
以上所述是小編給大家介紹的通過 Python 和 OpenCV 實現目標數量監控,希望對大家有所幫助!