引言:近几年来,谈起发展最火热的几个关键词必然是人工智能、大数据以及物联网的万物互联、边缘计算等等了。而今天,咱们就将利用Python实现物联网下的数据传输功能。主要的内容包括:本地视频传输到服务器、视频传输到手机实时显示、以及文本传输等方式
物联网是新一代信息技术的重要组成部分,也是"信息化"时代的重要发展阶段。顾名思义,物联网就是物物相连的互联网。这有两层意思:其一,物联网的核心和基础仍然是互联网,是在互联网基础上的延伸和扩展的网络;其二,其用户端延伸和扩展到了任何物品与物品之间,进行信息交换和通讯,也就是物物相息。物联网经过智能感知、识别技术与普适计算等通讯感知技术,普遍应用于网络的融合中,也所以被称为继计算机、互联网以后世界信息产业发展的第三次浪潮。而物联网最为核心的功能即是数据传输功能,利用互联网实现数据在任何能够接受数据的设备平台上达到传输效果,其中设备能够包括:本地PC、服务器、树莓派、手机、手环等等。html
首先咱们使用的Python版本是3.6.5所用到的模块以下:python
1.Opencv模块:在这里咱们用来读取视频流数据,以及图片或者是视频的编码解码和数据视频的显示;flask
2.Numpy模块:在这里用来和图片解码结合使用进行数据运算;bash
3.Socket模块:Socket又称"套接字",应用程序一般经过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间能够通信。服务器
4.Flask框架:Flask是一个Python编写的Web 微框架,让咱们能够使用Python语言快速实现一个网站或Web服务。网络
客户端经过opencv读取本地摄像头数据,而后编码成数据流格式,利用socket实现向服务端的发送,客户端代码以下:多线程
#客户端代码 import socket import threading import cv2 import numpy as np #接受服务器返回的数据的函数 def recvlink(client): while True: msg=client.recv(1024) print('Ubuntu say: '+msg.decode('utf-8')) def main(): #建立ipv4的socket对象,使用TCP协议(SOCK_STREAM) client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #设置服务器ip地址,注意应该是服务器的公网ip host='ip地址' #设置要发送到的服务器端口,须要在云服务器管理界面打开对应端口的防火墙 port=端口 #创建TCP协议链接,这时候服务器就会监听到到链接请求,并开始等待接受client发送的数据 client.connect((host,port)) #创建链接后,服务器端会返回链接成功消息 start_msg=client.recv(1024) print(start_msg.decode('utf-8')) #开启一个线程用来接受服务器发来的消息 t=threading.Thread(target=recvlink,args=(client,)) t.start() cap = cv2.VideoCapture(0) quality = 25 # 图像的质量 encode_param = [int(cv2.IMWRITE_JPEG_QUALITY), quality] while (cap.isOpened()): ret, frame = cap.read() if ret == True: img_encode = cv2.imencode(".jpg", frame, encode_param)[1] data_encode = np.array(img_encode) str_encode = data_encode.tostring() print(str_encode) print(len(str_encode)) #输入要发送的信息 sendmsg="kehu" #向服务器发送消息 client.send(str_encode) if sendmsg=='quit': break #结束时关闭客户端 client.close() if __name__ == '__main__': main()
服务器端经过设置bufSize防止出现粘包,利用socket接收数据流,而后解码成为图片,并实时显示:app
#服务器端 import socket import threading import numpy as np import cv2 #接受客户端消息函数 def recv_msg(clientsocket): global temp while True: # 接受客户端消息,设置一次最多接受1024字节的数据 recv_msg = clientsocket.recv(10240) # 把接收到的东西解码 msg = np.fromstring(recv_msg, np.uint8) img_decode = cv2.imdecode(msg, cv2.IMREAD_COLOR) try: s=img_decode.shape img_decode=img_decode temp=img_decode except: img_decode=temp pass cv2.imshow('SERVER', img_decode) if cv2.waitKey(1) & 0xFF == ord('q'): break def main(): #建立服务器端socket对象 ipv4 + TCP协议,和客户端同样 socket_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM) # 注意注意注意,咱们要绑定监听的地址和端口。服务器可能有多块网卡,能够绑定到某一块网卡的IP地址上,也能够用0.0.0.0绑定到全部的网络地址 # 还能够用127.0.0.1绑定到本机地址。127.0.0.1是一个特殊的IP地址,表示本机地址,若是绑定到这个地址,客户端必须同时在本机运行才能链接,也就是说,外部的计算机没法链接进来。 # 这个程序中host使用'0.0.0.0'或服务器内网ip地址均可以,我这里就使用了内网ip地址 #host='0.0.0.0' host='' #设置被监听的端口号,小于1024的端口号不能使用,由于他们是Internet标准服务的端口号 port= #绑定地址 socket_server.bind((host,port)) #设置最大监听数,也就是最多能够同时响应几个客户端请求,通常配合多线程使用 socket_server.listen(5) #等待客户端链接,一旦有了链接就马上向下执行,不然等待 #accept()函数会返回一个元组,第一个元素是客户端socket对象,第二个元素是客户端地址(ip地址+端口号) clientsocket,addr=socket_server.accept() # 有了客户端链接后以后才能执行如下代码,咱们先向客户端发送链接成功消息 clientsocket.send('你如今已经链接上了服务器啦,咱们来聊天吧!'.encode('utf-8')) # 和客户端同样开启一个线程接受客户端的信息 t=threading.Thread(target=recv_msg,args=(clientsocket,)) t.start() ''' # 发送消息 while True: reply="cer" clientsocket.send(reply.encode('utf-8')) clientsocket.close() ''' if __name__=='__main__': main()
能够利用opencv读取视频或是摄像头,进行编解码后传输。代码以下:框架
from flask import Flask, render_template, Response import cv2 import time class VideoCamera(object): def __init__(self): # 经过opencv获取实时视频流 self.video = cv2.VideoCapture(0) def __del__(self): self.video.release() def get_frame(self): try: image=cv2.imread("1.jpg") ceshi = image.shape global temp temp=image # 由于opencv读取的图片并不是jpeg格式,所以要用motion JPEG模式须要先将图片转码成jpg格式图片 ret, jpeg = cv2.imencode('.jpg', image) except: image = temp # 由于opencv读取的图片并不是jpeg格式,所以要用motion JPEG模式须要先将图片转码成jpg格式图片 ret, jpeg = cv2.imencode('.jpg', image) return jpeg.tobytes() app = Flask(__name__) @app.route('/') # 主页 def index(): # jinja2模板,具体格式保存在index.html文件中 return render_template('index.html') def gen(camera): while True: #time.sleep(0.5) frame = camera.get_frame() # 使用generator函数输出视频流, 每次请求输出的content类型是image/jpeg yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n\r\n') @app.route('/video_feed') # 这个地址返回视频流响应 def video_feed(): return Response(gen(VideoCamera()), mimetype='multipart/x-mixed-replace; boundary=frame')
因为手机端不方便运行Python程序,咱们能够利用flask搭建视频传输网页,再利用opencv保存图片更新图片,以及flask更新图片实现视频传输效果。socket
#!/usr/bin/env python from importlib import import_module import os from flask import Flask, render_template, Response # import camera driver if os.environ.get('CAMERA'): Camera = import_module('camera_' + os.environ['CAMERA']).Camera else: from camera import Camera # Raspberry Pi camera module (requires picamera package) # from camera_pi import Camera app = Flask(__name__) @app.route('/') def index(): """Video streaming home page.""" return render_template('index.html') def gen(camera): """Video streaming generator function.""" while True: frame = camera.get_frame() yield (b'--frame\r\n' b'Content-Type: image/jpeg\r\n\r\n' + frame + b'\r\n') @app.route('/video_feed') def video_feed(): """Video streaming route. Put this in the src attribute of an img tag.""" return Response(gen(Camera()), mimetype='multipart/x-mixed-replace; boundary=frame') if __name__ == '__main__': app.run(host='0.0.0.0', threaded=True)