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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

使用python和树莓派实现远程监控

發布時間:2025/3/21 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用python和树莓派实现远程监控 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言

前段時間因為各種雜事纏身,一直沒時間自己玩玩。今天元旦,打算給自己放個假,所以就尋思著玩玩手邊吃了幾個月灰的樹莓派。花了些時間自己寫了點代碼,實現了在樹莓派端啟動服務器,并實時將從連接到樹莓派的攝像頭讀取的數據傳輸到服務器上,在客戶端接收服務器的數據并實時顯示圖像。功能很簡單,代碼也很簡陋,希望勿噴。
我并沒有做完整圖像處理的功能,本來打算放yolo上去進行實時目標檢測,于是我試著在樹莓派上跑了yolo,但是跑一個epoch進行預測花了將近40s,這個速度太感人了,讓我完全打消了前面的年頭。不過如果在配置稍微好點的服務器上還是可行的,但是對于樹莓派也真的別期待有多好的效果了。

依賴庫

樹莓派(服務器端)

安裝系統

關于樹莓派的系統如何安裝我就不做介紹了,網上很多,也很容易。下面直接給個鏈接,照著做就是了:
https://www.cnblogs.com/suzhengsheng/p/5044924.html
安裝好官方的raspbian系統后,最好先更新一下(不是必須的):

sudo apt-get update sudo apt-get upgrade

安裝opencv

通常安裝opencv有兩種方式:使用apt-get直接從軟件源獲取編譯好的opencv,或是自己從官網下載源碼編譯后安裝。我個人比較喜歡后者,通常在自己的電腦上都會自己取編譯想要用的版本。但是在樹莓派上編譯著實比較麻煩,各種依賴庫的問題,如果不想折騰的話建議還是使用前者的方法。

sudo apt-get install libopencv-dev sudo apt-get install python-opencv

安裝PIL

PIL(python image library)是十分好用的一個可用于python的圖像處理庫,后面要用到它進行圖像的壓縮。

sudo apt-get install python-imaging

其他

如果還碰到其他的庫沒有的情況,請自行使用pip安裝。

客戶端

我的客戶端就是自己的筆記本,環境都是很早就配好的,因為經常用到opencv、numpy等庫。考慮到有些人的電腦可能沒有安裝好,所以還是簡要介紹一下。自己配開發環境是最基本的技能了。

numpy

太常用了,不過安裝是不要用pip來,可能會報錯,我通常是使用如下指令來安裝:

sudo apt-get install python-numpy

PIL

指令同樹莓派。

sudo apt-get install python-imaging

opencv

可以直接apt-get安裝,不過不能指定版本;我個人喜歡用opencv3.0以上的,所以是從源碼安裝的。相關安裝教程請問度娘,花些時間就能搞定。

其他

如果在后面運行程序時碰到了某些庫沒有,可以考慮用pip安裝或是向前面一樣使用sudo apt-get install python-(庫的名字)。

程序實現

使用python在本地讀取攝像頭并實時顯示

在進入正題之前,我們要先實現在本地讀取攝像頭,測試正常通過后再放到服務器上測試。
創建一個python腳本,名字為:local_camera.py,代碼如下:

#coding=utf-8 import cv2# 打開攝像頭 capture = cv2.VideoCapture(0)while True:# 從攝像頭讀取一幀圖像;如果讀取失敗,ret為False,如果成功,ret為true;frame存儲了那一幀的數據。ret, frame = capture.read()# print(ret)# 顯示圖像cv2.imshow("camera", frame)if cv2.waitKey(10) == 27:breakcv2.destroyAllWindows() capture.release()

程序很簡單,不多說了,運行通過后,再往下一步走。

數據源端

創建一個python腳本,名字為:src_camera,py,代碼如下:

import cv2 import time import socket import Image import StringIO# 獲取攝像頭 cap = cv2.VideoCapture(0) # 調整采集圖像大小為640*480 cap.set(cv2.cv.CV_CAP_PROP_FRAME_WIDTH, 640) cap.set(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT, 480)# 這里的HOST對應樹莓派的IP地址(自己輸入ifconfig查),端口號自己隨便定一個即可,但注意后面的程序中要保持統一 HOST, PORT = '192.168.0.113', 9999 # 連接服務器 sock =socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((HOST, PORT))while True:# 獲取一幀圖像ret, img = cap.read()# 如果ret為false,表示沒有獲取到圖像,退出循環if ret is False:print("can not get this frame")continue # 將opencv下的圖像轉換為PIL支持的格式pi = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))buf = StringIO.StringIO()# 緩存對象pi.save(buf, format='JPEG')# 將PIL下的圖像壓縮成jpeg格式,存入buf中jpeg = buf.getvalue()# 從buf中讀出jpeg格式的圖像buf.close()transfer = jpeg.replace('\n', '\-n')# 替換\n為\-n,因為后面傳輸時,終止的地方會加上\n,可以便于區分print len(transfer), transfer[-1]sock.sendall(transfer + "\n")# 通過socket傳到服務器# time.sleep(0.2)sock.close()

這部分代碼實現的功能是:在樹莓派端讀取攝像頭,使用socket包連接到服務器,并將從攝像頭讀取的數據發送到服務器上。
注釋都在程序中。程序中我們使用socket包來將數據傳到服務器,為了減少數據量,所以我們還需要對原始圖像進行壓縮。而壓縮則是通過PIL將圖像壓縮成jpeg格式,而PIL支持的圖像格式與opencv不同,所以在程序中還對其進行了轉換。

服務器端

創建一個python腳本,名字為:server_camera,py,代碼如下:

import socket import timesock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(("192.168.0.113", 9999))# 注意bind的這里,IP地址和端口號都要與前面的程序中一樣 sock.listen(2)# 監聽端口# 等待數據源端連接 src, src_addr = sock.accept() print "Source Connected by", src_addr# 等待目標端連接 dst, dst_addr = sock.accept() print "Destination Connected by", dst_addrwhile True:msg = src.recv(1024 *1024)if not msg:breaktry:dst.sendall(msg)except Exception as ex:dst, dst_addr = sock.accept()print "Destination Connected Again by", dst_addrexcept KeyboardInterrupt:print "Interrupted"breaksrc.close() dst.close() sock.close()

這個服務器端可以說是很簡陋了,整體流程是:監聽端口–>等待數據端連接–>等待目標端連接–>從數據端接受數據,轉發給目標端。

目標端(客戶端)

創建一個python腳本,名字為:dst_camera,py,代碼如下:

import cv2 import socket import time import Image import StringIO import numpy as np# 注意IP地址和端口號與前面的程序中的保持一致 HOST, PORT = "192.168.0.113", 9999 # 連接到服務器 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect((HOST, PORT)) f = sock.makefile()cv2.namedWindow("camera")while True:# 從服務器讀取數據,一行的結尾是'\n',注意我們前面已經將每一幀數據的'\n'替換成'\-n',而結尾就是'\n'msg = f.readline()if not msg:breakprint len(msg), msg[-2]# 將'\-n'換回來成'\n'jpeg = msg.replace("\-n", "\n")buf = StringIO.StringIO(jpeg[0:-1])# 緩存數據buf.seek(0)pi = Image.open(buf)# 使用PIL讀取jpeg圖像數據# img = np.zeros((640, 480, 3), np.uint8)img = cv2.cvtColor(np.asarray(pi), cv2.COLOR_RGB2BGR)# 從PIL的圖像轉成opencv支持的圖像 buf.close()cv2.imshow("camera", img)# 實時顯示if cv2.waitKey(10) == 27:breaksock.close() cv2.destroyAllWindows()

目標端,也可以說是客戶端,這是真正的我們可以看到實際輸出的部分了。從服務器讀出數據然后顯示即可。

運行結果

接下來看下運行結果了。

  • 先運行服務器端的程序,輸入python server_camera.py;
  • 然后運行數據源端的程序,輸入python src_camera.py;
  • 最后在自己的客戶端上運行程序,輸入python dst_camera.py;
  • 結果截圖:
    數據源端和服務器端:

    目標端:

    我看了下,實時顯示的效果還行。如果你想要控制幀率,可以在src_camera.py中更改time.sleep(0.2)這句代碼的參數,來控制延時時間。

    可能遇到的錯誤

    對號入座:

    • HIGHGUI ERROR: V4L: index 0 is not correct!:http://blog.csdn.net/youhongaa/article/details/55054970
    • socket.error:[errno 99] cannot assign requested address and namespace in python:https://stackoverflow.com/questions/19246103/socket-errorerrno-99-cannot-assign-requested-address-and-namespace-in-python

    參考資料:
    樹莓派+python opencv實現遠程監控:寫的很不錯,但是它用的是老版本的opencv,不保證一定能運行成功。

    總結

    以上是生活随笔為你收集整理的使用python和树莓派实现远程监控的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。