我想通過套接字將我的移動應用程式中捕獲的影像發送到桌面服務器。我目前實作了一個服務器/客戶端應用程式。我的問題是目前移動應用程式是在每次捕獲后發送幀的服務器。然后,作為客戶端的桌面沒有時間連接到作為移動應用程式的服務器并接收影像,因為套接字隨即關閉。
我想要做的是將桌面端設定為接收影像的服務器,而不是發送并保持套接字打開,因此每次從移動應用程式作為客戶端發送幀時,服務器都會讀取并顯示它。
這是我當前的嘗試,將移動應用程式作為發送影像的服務器:
Java類:
private final OnClickListener mOnClickListener = new OnClickListener() {
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.save_button:
setValue(UVCCamera.CTRL_ZOOM_ABS, 0x80ff);
Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_SHORT).show();
break;
case R.id.button_camera:
if (!Check.isFastClick()) {
return;
}
if (mCameraHandler != null) {
if (mCameraHandler.isOpened()) {
if (checkPermissionWriteExternalStorage()) {
Python py = Python.getInstance();
Bitmap bitmap = Bitmap.createBitmap(mImageView .getWidth(), mImageView .getHeight(), Bitmap.Config.ARGB_8888);
imageString = getStringImage(bitmap);
PyObject pyo = py.getModule("script");
PyObject obj = pyo.callAttr("__main__", imageString);
mCameraHandler.captureStill(MediaMuxerWrapper.getCaptureFile(Environment.DIRECTORY_DCIM, ".png").toString());
}
}
}
break;
}
}
移動應用程式中的服務器:
import numpy as np
import cv2
from PIL import Image
import base64
import io
import socket
import pickle
import struct
import imutils
def main(data):
server_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host_name = socket.gethostname()
host_ip = socket.gethostbyname(host_name)
port = 9999
socket_address = (host_ip, port)
server_socket.bind(socket_address)
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
if client_socket:
decoded_data = base64.b64decode(data)
frame_decoded = np.fromstring(decoded_data, np.uint8)
frame = cv2.imdecode(frame_decoded , cv2.IMREAD_UNCHANGED)
// The image captured is initially received as a string of bytes
a = pickle.dumps(frame)
message = struct.pack("Q",len(a)) a
client_socket.sendall(message)
當前在桌面上的客戶端代碼:
import socket,cv2, pickle,struct
client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
host_ip = '192.168.0.12'
port = 9999
client_socket.connect((host_ip,port))
data = b""
payload_size = struct.calcsize("Q")
while True:
while len(data) < payload_size:
packet = client_socket.recv(4*1024)
if not packet: break
data =packet
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack("Q",packed_msg_size)[0]
while len(data) < msg_size:
data = client_socket.recv(4*1024)
frame_data = data[:msg_size]
data = data[msg_size:]
frame = pickle.loads(frame_data)
cv2.imshow("Image Captured",frame)
key = cv2.waitKey(1) & 0xFF
if key == ord('q'):
break
client_socket.close()
基本上,我想從我目前的方法中改變誰發送和誰接收。我想從移動應用程式作為客戶端發送影像并在桌面作為服務器接收,我嘗試四處搜索,但大多數示例都顯示了如何從服務器發送影像。但是,我需要在服務器端打開套接字,因此每次捕獲都會立即收到影像。
uj5u.com熱心網友回復:
考慮這樣的架構。RequestHandler每次有來自客戶端的新連接時,服務器類都會創建一個新連接。在這里,我只是將套接字存盤在全域串列中,然后進行讀取。我不希望有任何資料,所以讀取會阻塞,但如果連接斷開,讀取將失敗,我們可以回傳。當有新資料時,我們只需掃描等待的套接字串列并將資料發送給所有這些。
import socketserver
open_connections = []
def newFrame(data):
# If there are no open connections, there's nothing to do.
if not open_connections:
return
decoded_data = base64.b64decode(data)
frame_decoded = np.fromstring(decoded_data, np.uint8)
frame = cv2.imdecode(frame_decoded , cv2.IMREAD_UNCHANGED)
# The image captured is initially received as a string of bytes
a = pickle.dumps(frame)
message = struct.pack("Q",len(a)) a
for sock in open_connections:
sock.sendall(message)
class RequestHandler(socketserver.BaseRequestHandler):
# Called for each new connection.
def handle(self):
open_connections.append( self.request )
# We don't ever expect data, but if this returns then the
# connection has been lost.
self.request.read(10)
open_connections.remove( sock )
if __name__ == '__main__':
print( "Listening on 9999..." )
socketserver.TCPServer.allow_reuse_address = True
tcpserver = socketserver.ThreadingTCPServer(('localhost', 9999), RequestHandler)
tcpserver.serve_forever()
uj5u.com熱心網友回復:
我設法設定了一個作業客戶端代碼,將影像發送到服務器,而服務器則等待發送影像。
發送影像的客戶端:
import numpy as np
import cv2
from PIL import Image
import base64
import io
import socket
import pickle
import struct
import io
def main(data):
decoded_data = base64.b64decode(data)
np_data = np.fromstring(decoded_data, np.uint8)
img = cv2.imdecode(np_data, cv2.IMREAD_UNCHANGED)
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('192.168.0.14', 9999))
connection = client_socket.makefile('wb')
result, frame = cv2.imencode('.png', img)
data = pickle.dumps(frame, 0)
size = len(data)
client_socket.sendall(struct.pack(">L", size) data)
服務器接收影像:
import socket
import sys
import cv2
import pickle
import numpy as np
import struct ## new
HOST='192.168.0.14'
PORT=9999
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
print('Socket created')
s.bind((HOST,PORT))
print('Socket bind complete')
s.listen(10)
print('Socket now listening')
conn,addr=s.accept()
data = b""
payload_size = struct.calcsize(">L")
print("payload_size: {}".format(payload_size))
while True:
while len(data) < payload_size:
print("Recv: {}".format(len(data)))
data = conn.recv(4096)
print("Done Recv: {}".format(len(data)))
packed_msg_size = data[:payload_size]
data = data[payload_size:]
msg_size = struct.unpack(">L", packed_msg_size)[0]
print("msg_size: {}".format(msg_size))
while len(data) < msg_size:
data = conn.recv(4096)
frame_data = data[:msg_size]
data = data[msg_size:]
frame=pickle.loads(frame_data, fix_imports=True, encoding="bytes")
frame = cv2.imdecode(frame, cv2.IMREAD_COLOR)
filename = '/home/server/Desktop/frames_savedsaved/Image.jpg'
cv2.imwrite(filename, frame)
cv2.imshow('ImageWindow',frame)
cv2.waitKey(1)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/371396.html
