PC端使用opencv获取webcam,通过socket把Mat图像传输到android手机端
demo效果图:
PC端
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
作者:小菜鸟_yang
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。