计算机视觉——利用openCV与Socket结合进行远程摄像头实时视频传输并保存图片数据
提示:文章寫完后,目錄可以自動生成,如何生成可參考右邊的幫助文檔
文章目錄
- 前言
- 一、TCP協議通信步驟
- 二、代碼實現
- 1.客戶端
- 2.服務端
- 三、IP設置方法
- 四、效果演示
前言
本文的內容是利用openCV與Socket結合進行遠程攝像頭實時視頻傳輸并保存圖片數據,其原理是由Client客戶端采集攝像頭圖像后經Socket傳輸到Server服務器端再顯示出來。同時服務器端可通過鍵盤按動截圖并保存。
本文內容參考自:
https://blog.csdn.net/qq_43665891/article/details/104362386
https://blog.csdn.net/u012736685/article/details/77131633
一、TCP協議通信步驟
首先了解一下TCP協議的一般通信步驟。
客戶端:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt();* 可選
3、綁定IP地址、端口等信息到socket上,用函數bind();* 可選
4、設置要連接的對方的IP地址和端口等屬性;
5、連接服務器,用函數connect();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網絡連接;
服務器端:
1、創建一個socket,用函數socket();
2、設置socket屬性,用函數setsockopt(); * 可選
3、綁定IP地址、端口等信息到socket上,用函數bind();
4、開啟監聽,用函數listen();
5、接收客戶端上來的連接,用函數accept();
6、收發數據,用函數send()和recv(),或者read()和write();
7、關閉網絡連接;
8、關閉監聽;
二、代碼實現
1.客戶端
代碼如下(示例):
import socket import struct import time import tracebackimport cv2 import numpyclass Client(object):"""客戶端"""def __init__(self, addr_port=('192.168.29.1', 11000)):# 連接的服務器的地址# 連接的服務器的端口self.addr_port = addr_port# 創建套接字self.client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 地址端口可以復用self.client.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)# 分辨率self.resolution = (640, 480)def connect(self):"""鏈接服務器"""try:self.client.connect(self.addr_port)return Trueexcept Exception as e:traceback.print_exc() # 打印原始的異常信息print('連接失敗')return Falsedef send2server(self):"""讀攝像頭數據 發送給服務器"""camera = cv2.VideoCapture(0) # 攝像頭對象print('isOpened:', camera.isOpened())while camera.isOpened():try:# 獲取攝像頭數據ret, frame = camera.read()# 對每一幀圖片做大小處理 和大小的壓縮frame = cv2.resize(frame, self.resolution)# 參1圖片后綴名 參2 原圖片的數據 參3圖片質量 0-100 越大越清晰ret, img = cv2.imencode('.jpg', frame, [cv2.IMWRITE_JPEG_QUALITY, 100])# img 是被壓縮后的數據 無法正常顯示print(img)print('-------------')print(img.tostring())# 轉換為numpy格式數據img_code = numpy.array(img)# 轉為二進制數據img = img_code.tostring()# 獲取數據長度length = len(img)# 發送的數據 大小 寬 高 圖片數據# 數據打包變為二進制# pack方法參數1 指定打包數據的數據大小 i 4字節 h代表2字節all_data = struct.pack('ihh', length, self.resolution[0], self.resolution[1]) + imgself.client.send(all_data)time.sleep(0.01)except:camera.release() # 釋放攝像頭traceback.print_exc()returnif __name__ == '__main__':client = Client()if client.connect():client.send2server()客戶端說明:
1 init方法完成套接字的初始化,傳入地址和端口,設置視頻的分辨率
2 connect方法 利用客戶端的socket對象的connect方法 連接服務器
3 send方法 讀取攝像頭拍攝的數據, ( socekt對象只發送二進制的數據 ) 把數據處理成二進制 , struct包的pack方法把里面的參數打包好自動轉成二進制 , 再利用send發送出去
2.服務端
代碼如下(示例):
import socket import struct import threading import cv2 import numpy import osclass Server:def __init__(self):# 設置tcp服務端的socketself.server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)# 設置重復使用self.server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)# 綁定地址和端口self.server.bind(('192.168.29.1', 11000))# 設置被動監聽self.server.listen(128)def run(self):while True:print('等待客戶端連接')# 等待客戶端連接client, addr = self.server.accept()ProcessClient(client).start()class ProcessClient(threading.Thread):def __init__(self, client):super().__init__()self.client = client# 以下內容作用是根據文件夾的圖片序號規定'i'的初值,方便下一次保存圖片時使用self.i=0 path = "F:/sample"for root, dirs, files in os.walk(path, topdown=False):print(root)print(dirs)print(files)file_list = []for file in files:file = int(file.split('.')[0])file_list.append(file)if len(file_list) == 0:self.i = 0else:file_list.sort()self.i = file_list[-1] + 1def run(self):while True:data = self.client.recv(8)if not data:break# 圖片的長度 圖片的寬高length, width, height = struct.unpack('ihh', data)imgg = b'' # 存放最終的圖片數據while length:# 接收圖片temp_size = self.client.recv(length)length -= len(temp_size) # 每次減去收到的數據大小imgg += temp_size # 每次收到的數據存到img里# 把二進制數據還原data = numpy.fromstring(imgg, dtype='uint8')# 還原成矩陣數據image = cv2.imdecode(data, cv2.IMREAD_UNCHANGED)print(image)cv2.imshow('capture', image)# 保存圖片k = cv2.waitKey(1)if k == ord('k'):cv2.imwrite(r"F:\sample\\" + str(self.i) + ".jpg", image) #存儲路徑self.i = self.i + 1print(self.i)# time.sleep(5)if k == ord('q'):breakif __name__ == '__main__':server = Server()server.run()服務端說明:將服務端接受到的視頻數據逆操作,即可得到原來的視頻,然后用cv2.imshow顯示視頻。
三、IP設置方法
2.找到當前使用網絡的ipv4地址,將服務端與客戶端都設置成該地址,例如:本機現在使用的WIFI
那就將ip地址設置成如上ipv4地址(遠程傳輸服務端需要申請公網ip)。
四、效果演示
切記先打開服務端,再打開客戶端。
按’k’截圖保存在本地,按‘q’關閉cv。
總結
以上是生活随笔為你收集整理的计算机视觉——利用openCV与Socket结合进行远程摄像头实时视频传输并保存图片数据的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux——进程系列知识详述(操作系统
- 下一篇: 剑指Offer Ⅱ 001. 整数除法(