部署环境的时候需要在服务器端加载模型本地端传输数据,或者是需要提前加载模型,在获取到数据后以发布订阅的方式传输给加载的模型并得到结果输出。这些过程需要将数据进行传输,redis很好的解决了数据传输和获取的问题。具体以图片传输和声音传输为例。
首先将服务端和本地端的redis安装好
安装redis
sudo apt-get install redis-server #安装redis服务
pip3 install redis #对应的python安装redis
单机连接以及ip添加
-
当运行本机的redis服务
r = redis.Redis(host=‘127.0.0.1’,port=6379,db=0)
报错 Connection refused,首先查看etc/redis/redis.conf文件内是否存在如下中红线部分,如果不存在添加,如果存在不需要处理
之后运行配置文件redis-server /etc/redis.conf这样就能连接到本机 -
在redis.conf中添加本机IP
如果想通过其他服务器连接到本机的redis服务需要在配置文件中添加本机的ip添加方式和上面添加127.0.0.1的方式一致,增加bind 行。在添加完IP后需要重新启动配置文件
redis-server /etc/redis.conf
按照这种方法需要再每次开机启动的时候运行配置文件,有一种更好的方法再bind 后面增加0.0.0,如下配置只需要再配置后运行配置文件下次开机会持久生效。
redis连接、发布和订阅
#方式1:创建连接池连接
pool = redis.ConnectionPool(host=host, port=port, db=db, password=passwd)
con = redis.Redis(connection_pool=pool)
方式2:直接连接
con = redis.Redis(host=host, port=port, db=db, password=passwd)
# 发布者,发送hello world消息到mes频道中 ,函数执行将返回一个整形数据,表示当前有多少客户端在监听此频道
con.publish("mes", "hello world")
# 订阅者:
sub = con.pubsub()
# 阻塞监听:
r = redis.Redis(host='127.0.0.1',port=6379,db=0)
ps = r.pubsub()
ps.subscribe("mes")
for item in ps.listen():
# 阻塞监听,channel为频道名称, data为接收的内容,初次监听时,会有一个测试数据
print(item["channel"], item["data"])
#非阻塞监听:
r = redis.Redis(host='127.0.0.1',port=6379,db=0)
ps = r.pubsub()
ps.subscribe("mes")
while True:
item = sub.get_message()
if item:
# 有监听到数据
print(item["channel"], item["data"])
time.sleep(0.3)
redis传输图片
数据传输端
#coding=utf-8
import redis
import cv2
import scipy.misc
import time
import base64
import _thread
r = redis.Redis(host='127.0.0.1',port=6379,db=0)
class VideoPlayer:
def __init__(self, url):
print('Init...')
self.video_capture = cv2.VideoCapture(url)
self.passFrame = True
_thread.start_new_thread(self.play, ())
def play(self):
print('Play!')
while True:
if self.passFrame:
self.video_capture.read()
# print('??')
continue
def takeSnapshot(self):
self.passFrame = False
ret, frame = self.video_capture.read()
self.passFrame = True
return frame
def release(self):
self.video_capture.release()
player = VideoPlayer(0)
start = time.time()
img = player.takeSnapshot()
img_str = cv2.imencode('.jpg', img)[1].tostring()
charecter = "img"
data = base64.b64encode(img_str) #将图片转换成base64再传输
r.set(charecter + str(0), data)
r.publish(charecter + str(0), charecter + str(0))
# print("step one cost:", time.time() - start)
#传输完图片之后拿到结果
result = r.get("result")
while result is None:
result = r.get("result")
while result is not None:
r.delete("result")
img = player.takeSnapshot()
img_str = cv2.imencode('.jpg', img)[1].tostring()
data = base64.b64encode(img_str)
r.set(charecter + str(0), data)
r.publish(charecter + str(0), charecter + str(0))
print("--------------------------------------",result, "-----------------------------------------------------------")
r.delete("result")
result = r.get("result")
while result is None:
result = r.get("result")
图片接收端
import redis
import time
import scipy.misc
import cv2
import base64
from PIL import Image
import io
import time
import scipy.misc
r = redis.Redis(host='127.0.0.1',port=6379,db=0)
ps = r.pubsub()
charecter = "img"
ps.subscribe(charecter + str(0))
for item in ps.listen():
print("get message")
start = time.time()
if item['type'] == 'message' and item['data'] is not None:
img_base64 = r.get(item['data'])
print(img_base64)
img_data = base64.b64decode(img_base64) #将拿到的base64的图片转换回来
img = Image.open(io.BytesIO(img_data)).convert("RGB")
scipy.misc.imsave('D:/video.png', img)
# frame = cv2.resize(img_data, (0, 0), fx=0.5, fy=0.5)
r.delete(charecter + str(0))
r.set("result", str("ok"))
print("cost time:", time.time() - start)
redis传输音频
获取音频并传输
#coding=utf-8
import pyaudio
import wave
import redis
input_filename = "input.wav" # 麦克风采集的语音输入
input_filepath = "D:/" # 输入文件的path
in_path = input_filepath + input_filename
r = redis.Redis(host='127.0.0.1',port=6379,db=0)
CHUNK = 1350
FORMAT = pyaudio.paInt16
CHANNELS = 1 # 声道数
RATE = 44100 # 采样率
RECORD_SECONDS = 3
WAVE_OUTPUT_FILENAME = in_path
p = pyaudio.PyAudio()
stream = p.open(format=FORMAT,
channels=CHANNELS,
rate=RATE,
input=True,
frames_per_buffer=CHUNK)
print("*"*10, "开始录音:请在5秒内输入语音")
frames = []
print(int(RATE / CHUNK * RECORD_SECONDS))
charecter = "voice"
data = stream.read(CHUNK)
r.set(charecter+str(0), data)
r.publish(charecter + str(0), charecter + str(0))
for i in range(1, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
r.set(charecter + str(i), data)
print("*"*10, "录音结束\n")
'''
stream.stop_stream()
stream.close()
p.terminate()
'''
## 传输声音的同时获取结果
result = r.get("result")
while result is not None:
r.delete("result")
frames = []
data = stream.read(CHUNK)
r.set(charecter+str(0), data)
charecter = "voice"
r.publish(charecter + str(0), charecter + str(0))
for i in range(1, int(RATE / CHUNK * RECORD_SECONDS)):
data = stream.read(CHUNK)
r.set(charecter + str(i), data)
result = r.get("result")
获取声音并以队列的方式拿取
import redis
import pyaudio
import time
import wave
from pyaudio import PyAudio,paInt16
FORMAT = pyaudio.paInt16
import time
input_filename = "input.wav" # 麦克风采集的语音输入
input_filepath = "D:/" # 输入文件的path
in_path = input_filepath + input_filename
r = redis.Redis(host='127.0.0.1',port=6379,db=0)
ps = r.pubsub()
CHUNK = 1350
FORMAT = pyaudio.paInt16
CHANNELS = 1 # 声道数
RATE = 44100 # 采样率
RECORD_SECONDS = 1
WAVE_OUTPUT_FILENAME = in_path
def save_wave_file(filename, data): #save the date to the wav file
wf = wave.open(filename, 'wb') #二进制写入模式
wf.setnchannels(CHANNELS)
wf.setsampwidth(2) #两个字节16位
wf.setframerate(RATE) #帧速率
wf.writeframes(b"".join(data)) #把数据加进去,就会存到硬盘上去wf.writeframes(b"".join(data))
wf.close()
charecter = "voice"
ps.subscribe(charecter + str(0))
voice = 0
lens = int(RATE / CHUNK * RECORD_SECONDS)
print(lens)
k = 0
time.sleep(1)
for item in ps.listen():
if item['type'] == 'message':
start = time.time()
r.ltrim("voice", -lens, -1)
frames = r.lrange("voice", -lens, -1)
save_wave_file(WAVE_OUTPUT_FILENAME, frames)
print("cost time:", time.time() - start)
while frames is not None :
k = k +1
print(k)
frames = r.lrange("voice", -lens, -1)
print(frames)
WAVE_OUTPUT_FILENAME = input_filepath + str(k) + ".wav"
save_wave_file(WAVE_OUTPUT_FILENAME, frames)
info = r.get(charecter + str(0))
while info is None:
info = r.get(charecter + str(0))
r.delete(charecter + str(0))