日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

利用OpenCV、Python和Ubidots構(gòu)建行人計(jì)數(shù)器程序(附完整代碼)

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

作者 | Jose Garcia

譯者 | 吳振東

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

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

導(dǎo) 讀: 本文將利用OpenCV,Python和Ubidots來編寫一個(gè)行人計(jì)數(shù)器程序,并對代碼進(jìn)行了較為詳細(xì)的講解。


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

現(xiàn)有的傳統(tǒng)行人計(jì)數(shù)技術(shù)不僅價(jià)格昂貴,而且它們所生成的數(shù)據(jù)通常與專有系統(tǒng)相關(guān)聯(lián),這些系統(tǒng)限制了數(shù)據(jù)提取和KPI的優(yōu)化選擇。相反,使用你的個(gè)人相機(jī)和SBC的嵌入式DIP不僅可以節(jié)省時(shí)間和金錢,還可以根據(jù)你所關(guān)注的KPI來自由定制應(yīng)用程序,并從云中獲取獨(dú)特的領(lǐng)悟。

使用云來啟用DIP IoT(物聯(lián)網(wǎng))應(yīng)用程序可以增強(qiáng)整體的功能性。隨著可視化、報(bào)告、警報(bào)和交叉引用外部數(shù)據(jù)源(如天氣、實(shí)時(shí)供應(yīng)商定價(jià)或業(yè)務(wù)管理系統(tǒng))等功能的增強(qiáng),DIP為開發(fā)人員提供了他們所需的自由空間。

想象一下一家擺著冰淇淋冰柜的雜貨店:他們想要追蹤統(tǒng)計(jì)經(jīng)過店門口的人數(shù),顧客所選擇的產(chǎn)品,以及門被打開的次數(shù)和冰柜的內(nèi)部溫度。?從這幾個(gè)數(shù)據(jù)點(diǎn)中,零售商可以運(yùn)行相關(guān)性分析,以更好地了解和優(yōu)化他們的產(chǎn)品定價(jià)和冰箱的整體能耗。

為了開啟你的數(shù)字圖像處理應(yīng)用程序開發(fā)工作,Ubidots運(yùn)用OpenCV和Python來創(chuàng)建了一套人員計(jì)數(shù)系統(tǒng)教程,用于分析統(tǒng)計(jì)給定區(qū)域中的人數(shù)。其實(shí)不僅是統(tǒng)計(jì)人數(shù)這樣簡單,添加Ubidots IoT開發(fā)平臺的資源還可以擴(kuò)展你的應(yīng)用程序。在這里,你可以看到如何實(shí)現(xiàn)利用Ubidots來構(gòu)建的實(shí)時(shí)人數(shù)統(tǒng)計(jì)儀表板。

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

目錄:

  1. 應(yīng)用需求
  2. 編碼?– 8個(gè)小節(jié)
  3. 測試
  4. 創(chuàng)造你自己的儀表板
  5. 結(jié)果展示


1、應(yīng)用需求

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

                
                  pip?install?opencv-contrib-python
                
              

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

                
                  import cv2 cv2.__version__
                
              

你應(yīng)該在屏幕上看到你所安裝的OpenCV版本:


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

安裝imutils
                
                  pip install imutils
                
              

安裝requests
                
                  pip?install?requests
                
              

2、編碼

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

第1節(jié)
                
                  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節(jié)中,我們導(dǎo)入必要的庫來實(shí)現(xiàn)我們的探測器,imutils是一個(gè)有用的DIP庫工具,讓我們從結(jié)果中執(zhí)行不同的轉(zhuǎn)換,cv2是我們的OpenCV Python包裝器,requests 可以通過HTTP發(fā)送數(shù)據(jù)/結(jié)果到Ubidots,argparse讓我們從腳本中的命令終端來讀取命令。

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

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

這項(xiàng)聲明:
cv2.HOGDescriptor_getDefaultPeopleDetector()調(diào)用了預(yù)先訓(xùn)練的模型,用于OpenCV的行人檢測,并提供支持向量機(jī)特征的評估功能。

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

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

第3節(jié)
                
                  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)
                
              

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

第4節(jié)
                
                  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節(jié)的函數(shù)類似,第4節(jié)的函數(shù)將調(diào)用detector()方法和繪圖框,并使用OpenCV中的VideoCapture()方法直接從網(wǎng)絡(luò)攝像頭檢索圖像。我們還稍微修改了officialOpenCV,從而在相機(jī)中獲取圖像,并且每隔“n”秒將結(jié)果發(fā)送到一個(gè)Ubidots帳戶(sendToUbidots()函數(shù)將在本教程的后面部分進(jìn)行回顧)。?函數(shù)convert_to_base64()會(huì)將圖像轉(zhuǎn)換為基本的64位字符串,這個(gè)字符串對于在HTML Canvas widget中使用JavaScript代碼查看Ubidots中的結(jié)果非常重要。

第5節(jié)
                
                  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)
                
              

這個(gè)方法旨在通過終端插入?yún)?shù)并觸發(fā)例程,對本地存儲(chǔ)的圖像文件或通過網(wǎng)絡(luò)攝像來搜索行人。

第6節(jié)
                
                  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節(jié)的這兩個(gè)函數(shù)是把結(jié)果發(fā)送給Ubidots從而理解和對數(shù)據(jù)進(jìn)行可視化的兩條主干道。第一個(gè)函數(shù) def buildPayload是在請求中構(gòu)建有效的負(fù)載,而第二個(gè)函數(shù) def sendToUbidots則接收你的Ubidots參數(shù)(TOKEN,變量和設(shè)備標(biāo)簽)用于存儲(chǔ)結(jié)果。在這種情況下,OpenCV可以檢測到圓盒的長度。作為備選,也可以發(fā)送上下文來將結(jié)果存儲(chǔ)為base64圖像,以便稍后進(jìn)行檢索。

第7節(jié)
                
                  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節(jié),我們即將完成對代碼的分析。函數(shù) argsParser()簡單地解析并通過終端將腳本的參數(shù)以字典的形式返回。在解析器中有兩個(gè)參數(shù):
· image:在你的系統(tǒng)中圖片文件的路徑
· camera:這個(gè)變量如果設(shè)置為‘true’,那么就會(huì)調(diào)用cameraDetect()方法

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

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

3、測試

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

正確保存代碼后,讓我們從Caltech Dataset和Pexels公共數(shù)據(jù)集中隨機(jī)選擇的下面四個(gè)圖像來進(jìn)行測試:

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

                
                  python peopleCounter.py PATH_TO_IMAGE_FILE
                
              

在我的例子中,我將圖像存儲(chǔ)在標(biāo)記為“dataset”的路徑中。要執(zhí)行一項(xiàng)有效的命令,請運(yùn)行以下命令,但請更換為你個(gè)人的文件存放路徑。

                
                  python peopleCounter.py -i dataset/image_1.png
                
              

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

                
                  python?peopleCounter.py?-c?true
                
              

測試結(jié)果:
?

除了這種查看測試結(jié)果的方式之外,你還可以實(shí)時(shí)查看存儲(chǔ)在Ubidots帳戶中的測試的結(jié)果:

4、創(chuàng)造你自己的儀表板

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

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


我們將使用基本的實(shí)時(shí)示例加上微小的修改,便于觀看我們的圖像。?你可以在下面看到關(guān)于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
  • 當(dāng)你保存你的widget,你可以獲得類似于下面的結(jié)果:

?

5、結(jié)果展示

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

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

做一個(gè)快樂的碼農(nóng)!

關(guān)于作者Jose García:

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

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

(*本文為AI科技大本營轉(zhuǎn)載文章, 轉(zhuǎn)載 聯(lián)系作者 )

精彩推薦


倒計(jì)時(shí)!由易觀攜手CSDN聯(lián)合主辦的第三屆易觀算法大賽還剩 5?天,冠軍團(tuán)隊(duì)將獲得3萬元!

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

推薦閱讀

  • 知乎算法團(tuán)隊(duì)負(fù)責(zé)人孫付偉: Graph?Embedding在知乎的應(yīng)用實(shí)踐

  • 大數(shù)據(jù)工程師手冊: 全面系統(tǒng)的掌握必備知識與工具

  • 經(jīng)典再讀 | NASNet:神經(jīng)架構(gòu)搜索網(wǎng)絡(luò)在圖像分類中的表現(xiàn)

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

  • 卷積神經(jīng)網(wǎng)絡(luò)中十大拍案叫絕的操作

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

  • 5大必知的圖算法,附Python代碼實(shí)現(xiàn)

  • 阿里云彈性計(jì)算負(fù)責(zé)人蔣林泉:億級場景驅(qū)動(dòng)的技術(shù)自研之路

你點(diǎn)的每個(gè)“在看”,我都認(rèn)真當(dāng)成了喜歡


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 宿松县| 紫云| 日土县| 曲周县| 西吉县| 安义县| 门头沟区| 阿瓦提县| 泌阳县| 上蔡县| 新乡市| 安图县| 铅山县| 永登县| 石泉县| 合山市| 长沙县| 杨浦区| 巴林右旗| 乡宁县| 安西县| 高州市| 高淳县| 中江县| 阿拉善右旗| 定襄县| 镇康县| 宁波市| 普格县| 卢龙县| 涟水县| 昆山市| 诸城市| 大英县| 桓仁| 永清县| 分宜县| 巢湖市| 民权县| 东平县| 阳春市|