PC端使用opencv获取webcam,通过socket把Mat图像传输到android手机端

时间:2021-12-12 10:12:31

demo效果图:

PC端

PC端使用opencv获取webcam,通过socket把Mat图像传输到android手机端

 

 

android端

PC端使用opencv获取webcam,通过socket把Mat图像传输到android手机端

大体流程

android端是服务器端,绑定IP和端口,监听来自PC端的连接, pc端通过socket与服务器andorid端传输图片。

主要代码

android端

private Runnable mythread = new Runnable(){

        @Override
        public void run() {
            // TODO Auto-generated method stub
            try {
            ServerSocket serverSocket =new ServerSocket(3200);
            Log.i("start server", "start server ------port :3200");
            while (true) {
                Socket socket =serverSocket.accept();
                new server(socket ,imageView).start();
            
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

 

 

    public void startserver(View v) {
        
         Thread thread1 = new Thread(mythread, "thread1");
         thread1.start();

    }

 

public class server extends Thread {
    private ImageView imageView;
    private Socket socket;
    public static byte imageByte[];
    private Handler handler;

    class MyHandler extends Handler{ 
         public MyHandler(Looper looper){
             super(looper); 
         }
         public void handleMessage(Message msg){
             super.handleMessage(msg); 
             imageView.setImageBitmap((Bitmap)msg.obj);
    
         }
    }

    public void run() {
        Looper looper = Looper.getMainLooper(); //主线程的Looper对象 
        handler = new MyHandler(looper);
        try {
            int imageSize=230400;//expected image size 640X480X3
            InputStream in = socket.getInputStream();
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte buffer[] = new byte[1024];
            int remainingBytes = imageSize; //
            while (remainingBytes > 0) {
                    int bytesRead = in.read(buffer);
                    if (bytesRead < 0) {
                        throw new IOException("Unexpected end of data");
                    }
                    baos.write(buffer, 0, bytesRead);
                    remainingBytes -= bytesRead;
            }
            in.close();
            imageByte = baos.toByteArray();   
            baos.close();
            socket.close();//关闭socket,一次连接传一幅图像            int nrOfPixels = imageByte.length / 3; // Three bytes per pixel.
            int pixels[] = new int[nrOfPixels];
            for(int i = 0; i < nrOfPixels; i++) {
               int r = imageByte[3*i];
               int g = imageByte[3*i + 1];
               int b = imageByte[3*i + 2];
               if (r < 0) 
                  r = r + 256; //Convert to positive
               if (g < 0) 
                  g = g + 256; //Convert to positive
               if (b < 0) 
                  b = b + 256; //Convert to positive
               pixels[i] = Color.rgb(b,g,r);
            }
         
            Bitmap bitmap = Bitmap.createBitmap(pixels, 320, 240, Bitmap.Config.ARGB_8888);
  
            Message msg = handler.obtainMessage();
            msg.obj = bitmap;
            handler.sendMessage(msg);//图像已经转换好了,发送消息给UI线程更新图像
        
        } catch (Exception e) {
        // TODO: handle exception
        }    

PC端

    VideoCapture cap(0);                        /* open webcam */
    if(!cap.isOpened())  
    {  
        return -1;  
    }  
    Mat frame;
    cap.set(CV_CAP_PROP_FRAME_WIDTH, 320);      /* set width */
    cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);     /* set height */

    try
    {
        boost::asio::io_service io_service;
        tcp::endpoint end_point(boost::asio::ip::address::from_string(argv[1]), 3200);

        tcp::socket socket(io_service);
        
        boost::system::error_code ignored_error;
        
        while (true)
        {
            cap>>frame;
                        
            imshow("client",frame);   
        
            char c=(char)waitKey(100);
            if (c==27)
            {
                break;
            }
    
            frame = (frame.reshape(0,1)); // to make it continuous
            socket.connect(end_point);
            std::string message((char *)frame.data,230400); /* the size of mat data is 320*240*3 */
            socket.write_some(boost::asio::buffer(message), ignored_error);
            cout<<"send image finished"<<endl;
    
            socket.close();
        
        }
    }
    catch (std::exception& e)
    {
        std::cerr << e.what() << std::endl;
    }

 

运行 asio.exe 192.168.1.101