亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

利用OpenCV、Python和Ubidots構建行人計數器程序(附完整代碼)

系統 2045 0
原文鏈接: https://mp.weixin.qq.com/mp/profile_ext?action=home\x26amp;__biz=MzI0ODcxODk5OA==\x26amp;scene=124#wechat_redirect

作者 | Jose Garcia

譯者 | 吳振東

校對 | 張一豪、林亦霖, 編輯 | 于騰凱

來源 |? 數據派(ID:datapi)

讀: 本文將利用OpenCV,Python和Ubidots來編寫一個行人計數器程序,并對代碼進行了較為詳細的講解。


數字圖像處理(DIP)技術 目前發展非常迅速,這在很大程度上要歸功于開發人員可以訪問云來運用機器學習技術。通過云處理數字圖像可以繞過任何專用硬件的要求,這使得使用DIP成為了大家的首選。作為處理圖像最經濟和最通用的方法,DIP已經被廣泛應用。這種其中最常見的當屬行人檢測和計數 - 這對于機場、火車站、零售店體育館、公共活動和博物館來說都是一項非常有用的指標。

現有的傳統行人計數技術不僅價格昂貴,而且它們所生成的數據通常與專有系統相關聯,這些系統限制了數據提取和KPI的優化選擇。相反,使用你的個人相機和SBC的嵌入式DIP不僅可以節省時間和金錢,還可以根據你所關注的KPI來自由定制應用程序,并從云中獲取獨特的領悟。

使用云來啟用DIP IoT(物聯網)應用程序可以增強整體的功能性。隨著可視化、報告、警報和交叉引用外部數據源(如天氣、實時供應商定價或業務管理系統)等功能的增強,DIP為開發人員提供了他們所需的自由空間。

想象一下一家擺著冰淇淋冰柜的雜貨店:他們想要追蹤統計經過店門口的人數,顧客所選擇的產品,以及門被打開的次數和冰柜的內部溫度。?從這幾個數據點中,零售商可以運行相關性分析,以更好地了解和優化他們的產品定價和冰箱的整體能耗。

為了開啟你的數字圖像處理應用程序開發工作,Ubidots運用OpenCV和Python來創建了一套人員計數系統教程,用于分析統計給定區域中的人數。其實不僅是統計人數這樣簡單,添加Ubidots IoT開發平臺的資源還可以擴展你的應用程序。在這里,你可以看到如何實現利用Ubidots來構建的實時人數統計儀表板。

在本文中,我們將介紹如何使用OpenCV和Ubidots來實現簡單的DIP疊加并創建行人計數器。此示例最適用于任何基于Linux的發行版系統,也適用于Raspberry Pi,Orange Pi或類似的嵌入式系統。
有關其他集成的查詢,請與Ubidots支持中心取得聯系,以便來了解你的企業如何使用這項增值技術。

目錄:

  1. 應用需求
  2. 編碼?– 8個小節
  3. 測試
  4. 創造你自己的儀表板
  5. 結果展示


1、應用需求

  • 任何帶有Ubuntu衍生版本的嵌入式Linux
  • 操作系統中安裝了Python 3或更高版本
  • OS中安裝了OpenCV 3.0或更高版本。如果使用Ubuntu或其衍生產品,請按照官方安裝教程或運行以下命令:

                
                  pip?install?opencv-contrib-python
                
              

當你成功安裝Python 3和OpenCV時,你可以通過這段簡單的代碼來進行檢驗(首先在你的terminal里輸入‘python’)

                
                  import cv2 cv2.__version__
                
              

你應該在屏幕上看到你所安裝的OpenCV版本:


按照官方操作指南來安裝Numpy,或者運行下面的命令
                
                  pip install numpy
                
              

安裝imutils
                
                  pip install imutils
                
              

安裝requests
                
                  pip?install?requests
                
              

2、編碼

可以在這一章節找到檢測和發送數據的整個例程。為了更好地解釋這段代碼,我們將其分為八個部分,以便更好地解釋代碼的各個方面,讓你更容易理解。

第1節
                
                  from imutils.object_detection	
import non_max_suppression	
import numpy as np	
import imutils	
import cv2	
import requests	
import time	
import argparse	

	
URL_EDUCATIONAL = "http://things.ubidots.com"	
URL_INDUSTRIAL = "http://industrial.api.ubidots.com"	
INDUSTRIAL_USER = True  # Set this to False if you are an educational user	
TOKEN = "...."  # Put here your Ubidots TOKEN	
DEVICE = "detector"  # Device where will be stored the result	
VARIABLE = "people"  # Variable where will be stored the result	
 	
 	
# Opencv pre-trained SVM with HOG people features	
HOGCV = cv2.HOGDescriptor()	
HOGCV.setSVMDetector(cv2.HOGDescriptor_getDefaultPeopleDetector())
                
              
在第1節中,我們導入必要的庫來實現我們的探測器,imutils是一個有用的DIP庫工具,讓我們從結果中執行不同的轉換,cv2是我們的OpenCV Python包裝器,requests 可以通過HTTP發送數據/結果到Ubidots,argparse讓我們從腳本中的命令終端來讀取命令。

重要提示:不要忘記使用您的Ubidots帳戶TOKEN更改這段代碼,如果是學生用戶,請務必將INDUSTRIAL_USER設置為FALSE。

導入庫后,我們將對方向梯度直方圖(Histogram of Oriented Gradient)進行初始化。方向梯度直方圖的簡稱是HOG,它是最受歡迎的對象檢測技術之一,已經在多個應用程序中實現并取得成功。OpenCV已經以高效的方式將HOG算法與支持向量機這種用于預測目的的經典機器學習技術(SVM)相結合,成為了一筆我們可以利用的財富。

這項聲明:
cv2.HOGDescriptor_getDefaultPeopleDetector()調用了預先訓練的模型,用于OpenCV的行人檢測,并提供支持向量機特征的評估功能。

第2節
                
                  def detector(image):	
    '''	
    @image is a numpy array	
    '''	
 	
    image = imutils.resize(image, width=min(400, image.shape[1]))	
    clone = image.copy()	
 	
    (rects, weights) = HOGCV.detectMultiScale(image, winStride=(8, 8),	
                                              padding=(32, 32), scale=1.05)	
 	
    # Applies non-max supression from imutils package to kick-off overlapped	
    # boxes	
    rects = np.array([[x, y, x + w, y + h] for (x, y, w, h) in rects])	
    result = non_max_suppression(rects, probs=None, overlapThresh=0.65)	
 	
    return result
                
              

detector()函數是“神奇”誕生的地方,它可以接收分成三個顏色通道的RGB圖像。為了避免出現性能問題,我們用imutils來調整圖像大小,再從HOG對象調用detectMultiScale()方法。然后,檢測多尺度方法可以讓我們使用SVM的分類結果去分析圖像并知曉人是否存在。關于此方法的參數介紹超出了本教程的范圍,但如果你想了解更多信息,請參閱官方OpenCV文檔或查看Adrian Rosebrock的精彩解釋。

HOG分析將會生成一些捕獲框(針對檢測到的對象),但有時這些框的重疊會導致誤報或檢測錯誤。為了避免這種混淆,我們將使用imutils庫中的非最大值抑制實用程序來刪除重疊的框 - 如下所示:
?
圖片轉載自
https://www.pyimagesearch.com

第3節
                
                  def localDetect(image_path):	
    result = []	
    image = cv2.imread(image_path)	
    if len(image) <= 0:	
        print("[ERROR] could not read your local image")	
        return result	
    print("[INFO] Detecting people")	
    result = detector(image)	
 	
    # shows the result	
    for (xA, yA, xB, yB) in result:	
        cv2.rectangle(image, (xA, yA), (xB, yB), (0, 255, 0), 2)	
 	
    cv2.imshow("result", image)	
    cv2.waitKey(0)	
    cv2.destroyAllWindows()	
 	
return (result, image)
                
              

現在,在這一部分代碼中,我們必須定義一個函數來從本地文件中讀取圖像并檢測其中是否有人存在。為了實現這一點,我只是簡單地調用了detector()函數并添加了一個簡單的循環來繪制探測器的圓框。它會返回檢測到的框的數量和帶有繪制檢測的圖像。然后,只需在新的OS窗口中重新創建結果即可。

第4節
                
                  def cameraDetect(token, device, variable, sample_time=5):	
 	
    cap = cv2.VideoCapture(0)	
    init = time.time()	
 	
    # Allowed sample time for Ubidots is 1 dot/second	
    if sample_time < 1:	
        sample_time = 1	
 	
    while(True):	
        # Capture frame-by-frame	
        ret, frame = cap.read()	
        frame = imutils.resize(frame, width=min(400, frame.shape[1]))	
        result = detector(frame.copy())	
 	
        # shows the result	
        for (xA, yA, xB, yB) in result:	
            cv2.rectangle(frame, (xA, yA), (xB, yB), (0, 255, 0), 2)	
        cv2.imshow('frame', frame)	
 	
        # Sends results	
        if time.time() - init >= sample_time:	
            print("[INFO] Sending actual frame results")	
            # Converts the image to base 64 and adds it to the context	
            b64 = convert_to_base64(frame)	
            context = {"image": b64}	
            sendToUbidots(token, device, variable,	
                          len(result), context=context)	
            init = time.time()	
 	
        if cv2.waitKey(1) & 0xFF == ord('q'):	
            break	
 	
    # When everything done, release the capture	
    cap.release()	
    cv2.destroyAllWindows()	
 	
def convert_to_base64(image):	
    image = imutils.resize(image, width=400)	
    img_str = cv2.imencode('.png', image)[1].tostring()	
    b64 = base64.b64encode(img_str)	
    return b64.decode('utf-8')
                
              

與第3節的函數類似,第4節的函數將調用detector()方法和繪圖框,并使用OpenCV中的VideoCapture()方法直接從網絡攝像頭檢索圖像。我們還稍微修改了officialOpenCV,從而在相機中獲取圖像,并且每隔“n”秒將結果發送到一個Ubidots帳戶(sendToUbidots()函數將在本教程的后面部分進行回顧)。?函數convert_to_base64()會將圖像轉換為基本的64位字符串,這個字符串對于在HTML Canvas widget中使用JavaScript代碼查看Ubidots中的結果非常重要。

第5節
                
                  def detectPeople(args):	
    image_path = args["image"]	
    camera = True if str(args["camera"]) == 'true' else False	
 	
    # Routine to read local image	
    if image_path != None and not camera:	
        print("[INFO] Image path provided, attempting to read image")	
        (result, image) = localDetect(image_path)	
        print("[INFO] sending results")	
        # Converts the image to base 64 and adds it to the context	
        b64 = convert_to_base64(image)	
        context = {"image": b64}	
 	
        # Sends the result	
        req = sendToUbidots(TOKEN, DEVICE, VARIABLE,	
                            len(result), context=context)	
        if req.status_code >= 400:	
            print("[ERROR] Could not send data to Ubidots")	
            return req	
 	
    # Routine to read images from webcam	
    if camera:	
        print("[INFO] reading camera images")	
        cameraDetect(TOKEN, DEVICE, VARIABLE)
                
              

這個方法旨在通過終端插入參數并觸發例程,對本地存儲的圖像文件或通過網絡攝像來搜索行人。

第6節
                
                  def buildPayload(variable, value, context):	
    return {variable: {"value": value, "context": context}}	
 	
 	
def sendToUbidots(token, device, variable, value, context={}, industrial=True):	
    # Builds the endpoint	
    url = URL_INDUSTRIAL if industrial else URL_EDUCATIONAL	
    url = "{}/api/v1.6/devices/{}".format(url, device)	
 	
    payload = buildPayload(variable, value, context)	
    headers = {"X-Auth-Token": token, "Content-Type": "application/json"}	
 	
    attempts = 0	
    status = 400	
 	
    while status >= 400 and attempts <= 5:	
        req = requests.post(url=url, headers=headers, json=payload)	
        status = req.status_code	
        attempts += 1	
        time.sleep(1)	
 	
return req
                
              

第6節的這兩個函數是把結果發送給Ubidots從而理解和對數據進行可視化的兩條主干道。第一個函數 def buildPayload是在請求中構建有效的負載,而第二個函數 def sendToUbidots則接收你的Ubidots參數(TOKEN,變量和設備標簽)用于存儲結果。在這種情況下,OpenCV可以檢測到圓盒的長度。作為備選,也可以發送上下文來將結果存儲為base64圖像,以便稍后進行檢索。

第7節
                
                  def argsParser():	
    ap = argparse.ArgumentParser()	
    ap.add_argument("-i", "--image", default=None,	
                    help="path to image test file directory")	
    ap.add_argument("-c", "--camera", default=False,	
                    help="Set as true if you wish to use the camera")	
    args = vars(ap.parse_args())	
 	
    return args
                
              

對于第7節,我們即將完成對代碼的分析。函數 argsParser()簡單地解析并通過終端將腳本的參數以字典的形式返回。在解析器中有兩個參數:
· image:在你的系統中圖片文件的路徑
· camera:這個變量如果設置為‘true’,那么就會調用cameraDetect()方法

第8節
                
                  def main():	
    args = argsParser()	
    detectPeople(args)	
 	
if __name__ == '__main__':	
    main()
                
              

第8節是我們主函數代碼中的最終部分,只是用來獲取console中的參數,然后發起指定的程序。
別忘了,全部的代碼都可以從Github上下載。

3、測試

打開你最喜愛的代碼編輯器(sublime-text,notepad,nano等),然后復制并粘貼此處所提供的完整代碼。使用你特定的Ubidots TOKEN更新代碼并將文件另存為“peopleCounter.py”。

正確保存代碼后,讓我們從Caltech Dataset和Pexels公共數據集中隨機選擇的下面四個圖像來進行測試:

? 利用OpenCV、Python和Ubidots構建行人計數器程序(附完整代碼)_第3張圖片
?
為了對這些圖像進行分析,首先你必須將圖像存儲在筆記本電腦或PC中,并記錄好要分析圖像的存放路徑。

                
                  python peopleCounter.py PATH_TO_IMAGE_FILE
                
              

在我的例子中,我將圖像存儲在標記為“dataset”的路徑中。要執行一項有效的命令,請運行以下命令,但請更換為你個人的文件存放路徑。

                
                  python peopleCounter.py -i dataset/image_1.png
                
              

如果你希望是從相機而不是本地文件中獲取圖像,只需運行以下命令:

                
                  python?peopleCounter.py?-c?true
                
              

測試結果:
?

除了這種查看測試結果的方式之外,你還可以實時查看存儲在Ubidots帳戶中的測試的結果:

4、創造你自己的儀表板

我們將使用HTML Canvas來實時觀察所取得的結果,本教程不對HTML canvas widget做講解,如果你不了解如何使用它們,請參閱以下文章:

  • Canvas Widget Examples
  • Canvas Widget Introductory Demo
  • Canvas Creating a Real Time Widget


我們將使用基本的實時示例加上微小的修改,便于觀看我們的圖像。?你可以在下面看到關于widget的代碼。

                
                  HTML	

                  
                  	
JS	
var socket;	
var srv = "industrial.ubidots.com:443";	
// var srv = "app.ubidots.com:443"  // Uncomment this line if you are an educational user	
var VAR_ID = "5ab402dabbddbd3476d85967"; // Put here your var Id	
var TOKEN = ""  // Put here your token	
$( document ).ready(function() {	
  	
function renderImage(imageBase64){	
  if (!imageBase64) return;	
  $('#img').attr('src', 'data:image/png;base64, ' + imageBase64);	
}	
  	
// Function to retrieve the last value, it runs only once  	
function getDataFromVariable(variable, token, callback) {	
  var url = 'https://things.ubidots.com/api/v1.6/variables/' + variable + '/values';	
  var headers = {	
    'X-Auth-Token': token,	
    'Content-Type': 'application/json'	
  };	
  	
  $.ajax({	
    url: url,	
    method: 'GET',	
    headers: headers,	
    data : {	
      page_size: 1	
    },	
    success: function (res) {	
      if (res.results.length > 0){	
      renderImage(res.results[0].context.image);	
      }	
      callback();	
    }	
  });	
}	
 	
// Implements the connection to the server	
socket = io.connect("https://"+ srv, {path: '/notifications'});	
var subscribedVars = [];	
 	
// Function to publish the variable ID	
var subscribeVariable = function (variable, callback) {	
  // Publishes the variable ID that wishes to listen	
  socket.emit('rt/variables/id/last_value', {	
    variable: variable	
  });	
  // Listens for changes	
  socket.on('rt/variables/' + variable + '/last_value', callback);	
  subscribedVars.push(variable);	
};	
 	
// Function to unsubscribed for listening	
var unSubscribeVariable = function (variable) {	
  socket.emit('unsub/rt/variables/id/last_value', {	
    variable: variable	
  });	
  var pst = subscribedVars.indexOf(variable);	
  if (pst !== -1){	
    subscribedVars.splice(pst, 1);	
  }	
};	
 	
var connectSocket = function (){	
  // Implements the socket connection	
  socket.on('connect', function(){	
    console.log('connect');	
    socket.emit('authentication', {token: TOKEN});	
  });	
  window.addEventListener('online', function () {	
    console.log('online');	
    socket.emit('authentication', {token: TOKEN});	
  });	
  socket.on('authenticated', function () {	
    console.log('authenticated');	
    subscribedVars.forEach(function (variable_id) {	
      socket.emit('rt/variables/id/last_value', { variable: variable_id });	
    });	
  });	
}	
 	
/* Main Routine */	
getDataFromVariable(VAR_ID, TOKEN, function(){	
  connectSocket();	
});	
  	
connectSocket();	
 	
//connectSocket();	
// Subscribe Variable with your own code.	
subscribeVariable(VAR_ID, function(value){	
  var parsedValue = JSON.parse(value);	
  console.log(parsedValue);	
  //$('#img').attr('src', 'data:image/png;base64, ' + parsedValue.context.image);	
  renderImage(parsedValue.context.image);	
  })	
});
                
              

不要忘記把你的帳戶TOKEN和變量ID放在代碼段的開頭。

第三部分的LIBRARIES

增加下面第三部分的libraries:

  • https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js
  • https://iot.cdnedge.bluemix.net/ind/static/js/libs/socket.io/socket.io.min.js
  • 當你保存你的widget,你可以獲得類似于下面的結果:

?

5、結果展示

?
在此鏈接中你可以看到帶有結果的儀表板。

在本文中,我們探討了如何使用DIP(圖像處理),OpenCV和Ubidots來創建物聯網人員計數器。通過這些服務,在對人物、場景或事物的檢測與識別問題上,你的DIP應用程序會比PIR或其他光學傳感器更加準確 –?這套程序提供了高效的行人計數器,而且不需要對早期數據的靜態進行任何操作。

做一個快樂的碼農!

關于作者Jose García:

UIS電子工程師,Ubuntu用戶,布卡拉曼加人,程序員,有時很無聊,想要環游世界但卻沒太有希望完成這一夢想。?硬件和軟件開發人員@Ubidots
譯者介紹:
法國洛林大學計算機與決策專業碩士。現從事人工智能和大數據相關工作,以成為數據科學家為終生奮斗目標。來自山東濟南,不會開挖掘機,但寫得了Java、Python和PPT。

原文標題:?
People?Counting?with?OpenCV,?Python?&?Ubidots?
原文鏈接:
https://ubidots.com/blog/people-counting-with-opencv-python-and-ubidots/

(*本文為AI科技大本營轉載文章, 轉載 聯系作者 )

精彩推薦


倒計時!由易觀攜手CSDN聯合主辦的第三屆易觀算法大賽還剩 5?天,冠軍團隊將獲得3萬元!

本次比賽主要預測訪問平臺的相關事件的PV,UV流量 (包括Web端,移動端等),大賽將會提供相應事件的流量數據,以及對應時間段內的所有事件明細表和用戶屬性表等數據,進行模型訓練,并用訓練好的模型預測規定日期范圍內的事件流量。

推薦閱讀

  • 知乎算法團隊負責人孫付偉: Graph?Embedding在知乎的應用實踐

  • 大數據工程師手冊: 全面系統的掌握必備知識與工具

  • 經典再讀 | NASNet:神經架構搜索網絡在圖像分類中的表現

激光雷達,馬斯克看不上,卻又無可替代?

  • 卷積神經網絡中十大拍案叫絕的操作

  • Docker是啥?容器變革的火花?

  • 5大必知的圖算法,附Python代碼實現

  • 阿里云彈性計算負責人蔣林泉:億級場景驅動的技術自研之路

你點的每個“在看”,我都認真當成了喜歡


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 精品视频网站 | 视频一区二区三区在线观看 | 欧美一级毛片免费高清aa | 日本一区二区三区高清在线观看 | 看全大色黄大色黄大片一级爽 | 国产精品视频免费观看 | 欧美三级做爰在线 | 欧美日韩综合高清一区二区 | 婷婷综合久久中文字幕 | 精品久久久99大香线蕉 | 免费看黄色片视频 | 乱子伦xxxx厨房 | 日韩亚射 | 久久精品高清 | 欧美黑人巨大肥婆性视频 | 一区二区三区四区在线观看视频 | 欧美日韩中文在线视频 | julia中文字幕在线 | 国产骚b| 日日日视频 | 欧美成人免费高清二区三区 | 欧美日韩一本 | 奇米激情 | 在线久草视频 | 久久久免费视频观看 | 精品视频在线视频 | 毛片免费观看网址 | 国产成人精品无缓存在线播放 | 99热这里只有精品首页 | 欧美日韩国产成人高清视频 | 成人精品视频在线观看播放 | 热99热| 91在线网站 | 国产人成午夜免视频网站 | 国产一区二区三区四区在线观看 | 国产精品福利在线观看 | 日本三级一区 | 久久毛片免费看一区二区三区 | 视频二区中文字幕 | 日本一级毛片高清免费观看视频 | 一区二区精品在线观看 |