将视频从Python发送到Android

时间:2020-03-23 03:15:23

标签: python android opencv

我正在尝试通过本地网络发送视频,该视频是用Python中的OpenCV捕获并显示在Android应用中的。

我最初的想法是:

Python方面:

  • 从OpenCV获取Mat图像
  • 将Mat转换为.png
  • 通过SocketServer发送.png字节的字节

Android:

  • 使用BufferedInputStream抓取图像
  • 将其转换为位图并在ImageView中显示

这有效,但仅在某些情况下有效。当bufferedInputStream中的第一个字节是.png文件的第一个字节时。因此,像前2个一样,大多数没有损坏,而其余的则是。 我了解BufferedInputStream尝试读取400 000字节,这也导致图像损坏。但这意味着,我需要知道传入图像的确切大小,并且BufferedInputStream并不总是加载全部40万个(有时只有5万个)。所以这对我来说似乎太复杂了。

一旦python服务器开始将数据通过套接字推入套接字,就会出现混乱,并且图像会损坏。

这是Python代码:

import socket
import cv2

HOST = '192.168.1.105'
PORT = 6969

with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
    s.connect((HOST, PORT))

    # Connect to webcam
    stream = cv2.VideoCapture(0)

    while True:
        # grab the Mat image
        _, img = stream.read()

        _, png_img = cv2.imencode('.png', img)

        png_img = png_img.tobytes()

        s.sendall(png_img)

这是一个Android代码:

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.widget.ImageView;

import java.io.BufferedInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Thread server_thread = new Thread(new ServerThread());
        server_thread.start();
    }

    class ServerThread implements Runnable {
        Socket socket;
        ServerSocket serverSocket;
        Handler handler = new Handler();

        InputStream inputStream;
        BufferedInputStream bufferedInputStream;

        // set to random, but my images are always smaller than this
        int my_buffer_size = 400000;
        int read_bytes;
        byte[] received_bytes;

        @Override
        public void run() {
            try {
                serverSocket = new ServerSocket(6969);
                System.out.println("Server Socket is on port 6969");

                // Wait for someone to connect
                socket = serverSocket.accept();

                inputStream = socket.getInputStream();
                bufferedInputStream = new BufferedInputStream(inputStream);

                while (true) {
                    received_bytes = new byte[my_buffer_size];

                    read_bytes = bufferedInputStream.read(received_bytes);
                    System.out.println("Read bytes: " + read_bytes);

                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            ImageView imgView = (ImageView) findViewById(R.id.image);
                            imgView.setImageBitmap(BitmapFactory.decodeByteArray(received_bytes, 0, my_buffer_size));
                        }
                    });
                }
            } catch(IOException e){
                e.printStackTrace();
                System.out.println("ERROR: Run failed.");
            }
        }
    }
}

我不确定,这种“发送.png并将其显示在ImageView中”的方法是否正确。 我很想听听你们,对于这种问题,合适的方法是什么? 如果这行得通,我如何改进它以获取实时视频而不损坏图像?

0 个答案:

没有答案