OpenCV中文网站

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
热搜: 安装 配置
查看: 1149|回复: 3

udp传输及解码问题

[复制链接]
发表于 2017-6-4 11:47:12 | 显示全部楼层 |阅读模式
我现在一边在linux上用opencv抓取摄像头图像,encode之后用udp分包发送到另一端android端。然后在android端重新整合数据包并解码显示在imageview里。现在卡在了安卓端解码显示的部分,求教如何整理数据包并解码(android端是纯java开发,不是C++和jni调用的方式,因为android也不太熟)代码如下,linux上c++图像抓取代码,encode成.jpg格式:
  1. try {
  2.         UDPSocket sock;
  3.         int jpegqual =  ENCODE_QUALITY; // Compression Parameter

  4.         Mat frame, send;
  5.         vector < uchar > encoded;
  6.         VideoCapture cap(0); // Grab the camera
  7.         namedWindow("send", CV_WINDOW_AUTOSIZE);
  8.         if (!cap.isOpened()) {
  9.             cerr << "OpenCV Failed to open camera";
  10.             exit(1);
  11.         }

  12.         clock_t last_cycle = clock();
  13.         while (1) {
  14.             cap >> frame;
  15.             if(frame.size().width==0)continue;//simple integrity check; skip erroneous data...
  16.             resize(frame, send, Size(FRAME_WIDTH, FRAME_HEIGHT), 0, 0, INTER_LINEAR);
  17.             vector < int > compression_params;
  18.             compression_params.push_back(CV_IMWRITE_JPEG_QUALITY);
  19.             compression_params.push_back(jpegqual);

  20.             imencode(".jpg", send, encoded, compression_params);
  21.             imshow("send", send);
  22.             int total_pack = 1 + (encoded.size() - 1) / PACK_SIZE;

  23.             int ibuf[1];
  24.             ibuf[0] = total_pack;
  25.             sock.sendTo(ibuf, sizeof(int), servAddress, servPort);

  26.             for (int i = 0; i < total_pack; i++)
  27.                 sock.sendTo( &  [i * PACK_SIZE], PACK_SIZE, servAddress, servPort);

  28.             waitKey(FRAME_INTERVAL);

  29.             clock_t next_cycle = clock();
  30.             double duration = (next_cycle - last_cycle) / (double) CLOCKS_PER_SEC;
  31.             cout << "\teffective FPS:" << (1 / duration) << " \tkbps:" << (PACK_SIZE * total_pack / duration / 1024 * 8) << endl;

  32.             cout << next_cycle - last_cycle;
  33.             last_cycle = next_cycle;
  34.         }
  35.         // Destructor closes the socket

  36.     } catch (SocketException & e) {
  37.         cerr << e.what() << endl;
  38.         exit(1);
  39.     }
复制代码
android上图像接收代码,用了asynctask方法。在doinbackground方法里接收数据包并重新整合,转换成string形式后publish到onprogressupdated方法里转换回byte然后放入mat解码并转换位bitmap显示。

  1. AsyncTask<Void, String, Void> camera = new AsyncTask<Void, String, Void>() {
  2.             @Override
  3.             protected Void doInBackground(Void... params) {
  4.                 try {

  5.                     DatagramSocket sock = new DatagramSocket(10003);
  6.                     String sendStr = "I'm the client.";
  7.                     byte[] sendbuf;
  8.                     sendbuf = sendStr.getBytes();
  9.                     InetAddress addr = InetAddress.getByName(message);
  10.                     DatagramPacket sendPacket = new DatagramPacket(sendbuf, sendbuf.length, addr, 10000); // vehicle side port set to 10000

  11.                     sock.send(sendPacket);

  12.                     //DatagramSocket server = new DatagramSocket(10003);
  13.                     //server.setBroadcast(true);
  14.                     byte[] buffer = new byte[65540];
  15.                     DatagramPacket recvPacket = new DatagramPacket(buffer, buffer.length);

  16.                     while(true) {

  17.                         do {
  18.                             sock.receive(recvPacket);
  19.                         } while (recvPacket.getLength() > 4);  // int size 4

  20.                         byte[] longbuf = new byte[PACK_SIZE * total_pack];
  21.                         for (int i = 0; i < total_pack; i++) {
  22.                             sock.receive(recvPacket);
  23.                             System.arraycopy(buffer, 0, longbuf, i*PACK_SIZE, recvPacket.getLength());
  24.                         }
  25.                         String pic = new String(longbuf);
  26.                         //publishProgress("mark place success");
  27.                         publishProgress(pic);

  28.                     }

  29.                 } catch (IOException e) {
  30.                     e.printStackTrace();
  31.                 }

  32.                 return null;
  33.             }

  34.             @Override
  35.             protected void onProgressUpdate(String... values) {
复制代码
现在的问题是在上述imdecode那个地方程序会跑崩,直接闪退。抛出CvException。不知道是数据包整合的不对还是解码的api使用有问题。求大神指教。

这个接收端其实原来室友一个C++版本的,也就是说一段linux抓摄像头,一段linux上接受并解码。然后安卓端这个是我自己“翻译”过来的。如果需要C++原版,请参考如下部分。
  1. do {
  2.                 recvMsgSize = sock.recvFrom(buffer, BUF_LEN, sourceAddress, sourcePort);
  3.             } while (recvMsgSize > sizeof(int));
  4.             int total_pack = ((int * ) buffer)[0];

  5.             cout << "expecting length of packs:" << total_pack << endl;
  6.             char * longbuf = new char[PACK_SIZE * total_pack];
  7.             for (int i = 0; i < total_pack; i++) {
  8.                 recvMsgSize = sock.recvFrom(buffer, BUF_LEN, sourceAddress, sourcePort);
  9.                 if (recvMsgSize != PACK_SIZE) {
  10.                     cerr << "Received unexpected size pack:" << recvMsgSize << endl;
  11.                     continue;
  12.                 }
  13.                 memcpy( & longbuf[i * PACK_SIZE], buffer, PACK_SIZE);
  14.             }

  15.             cout << "Received packet from " << sourceAddress << ":" << sourcePort << endl;

  16.             Mat rawData = Mat(1, PACK_SIZE * total_pack, CV_8UC1, longbuf);
  17.             Mat frame = imdecode(rawData, CV_LOAD_IMAGE_COLOR);
  18.             if (frame.size().width == 0) {
  19.                 cerr << "decode failure!" << endl;
  20.                 continue;
  21.             }
  22.             imshow("recv", frame);
  23.             free(longbuf);
复制代码


回复

使用道具 举报

 楼主| 发表于 2017-6-4 11:52:15 | 显示全部楼层
哦,android端少了一部分代码没复制上去。onprogressupdated如下
  1. @Override
  2.             protected void onProgressUpdate(String... values) {

  3.                 try {
  4.                     Toast.makeText(ConnectToTCP.this, values[0], Toast.LENGTH_SHORT).show();

  5.                     byte[] longbuf = values[0].getBytes();

  6.                     Mat RawData = new Mat(1, PACK_SIZE*total_pack, CV_8UC1);
  7.                     RawData.put(0, 0, longbuf);
  8.                     Mat frame = Imgcodecs.imdecode(RawData, Imgcodecs.CV_LOAD_IMAGE_COLOR);  ///崩溃点!!
  9.                     Bitmap img = Bitmap.createBitmap(frame.cols(), frame.rows(), Bitmap.Config.ARGB_8888);
  10.                     Utils.matToBitmap(frame, img);
  11.                     imageView.setImageBitmap(img);
  12.                 } catch (CvException e) {
  13.                     e.printStackTrace();
  14.                 }
  15.                
  16.                 super.onProgressUpdate(values);
  17.             }
复制代码
回复 支持 反对

使用道具 举报

发表于 2017-6-8 10:24:39 | 显示全部楼层
给整个项目给共享共享 我也是用android开发的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2017-6-13 02:10:04 | 显示全部楼层
小蜗牛AG 发表于 2017-6-8 10:24
给整个项目给共享共享 我也是用android开发的

怎么共享?我qq:869210704
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|OpenCV中文网站  

GMT+8, 2019-9-21 04:56 , Processed in 0.052443 second(s), 16 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表