Android摄像头图像实时传输到ROS有OOM麻烦吗?

时间:2017-05-22 11:04:01

标签: android opencv ros

我试图将图片信息从 Android相机 传输到 ROS -时间。但是,我遇到了一个OOM问题。我是 Android-ROS 的新手,几乎没有处理此类问题的经验。

这里有我的演示的一些信息:(如果你们需要更多,请评论)

1

RewriteRule . ../assets/file.php [NC]

2.Dependencies Opencv-for-Android(3.2.0)

3. ROS 消息类型:android_cv_bridge

我尝试在 onPreviewFrame() 功能中发布图片消息。像这样的代码:

public class MainActivity extends RosActivity implements NodeMain, SurfaceHolder.Callback, Camera.PreviewCallback

imagePublisher 在此处初始化:

@Override
public void onPreviewFrame(byte[] data, Camera camera) {
    Camera.Size size = camera.getParameters().getPreviewSize();
    YuvImage yuvImage = new YuvImage(data, ImageFormat.NV21, size.width, size.height, null);
    Bitmap bmp = null;

    if(yuvImage != null){
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        yuvImage.compressToJpeg(new Rect(0, 0, size.width, size.height), 80, baos);
        bmp = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size());

        try{
            baos.flush();
            baos.close();
        }
        catch(IOException e){
            e.printStackTrace();
        }

        image = imagePublisher.newMessage();
        Time curTime = connectedNode.getCurrentTime();

        image.setEncoding("rgba8");
        image.getHeader().setStamp(curTime);
        image.getHeader().setFrameId("camera");

        curTime = null;

        if(isOpenCVInit){
            Mat mat_image = new Mat(bmp.getHeight(), bmp.getWidth(), CvType.CV_8UC4, new Scalar(0));
            Bitmap copyBmp = bmp.copy(Bitmap.Config.ARGB_8888, true);

            // bitmap to mat
            Utils.bitmapToMat(copyBmp, mat_image);
            // mat to cvImage
            CvImage cvImage = new CvImage(image.getHeader(), "rgba8", mat_image);

            try {
                imagePublisher.publish(cvImage.toImageMsg(image));
            } catch (IOException e) {
                e.printStackTrace();
            }

            mat_image.release();
            mat_image = null;

            if(!bmp.isRecycled()) {
                bmp.recycle();
                bmp = null;
            }
            if(!copyBmp.isRecycled()) {
                copyBmp.recycle();
                copyBmp = null;
            }
            cvImage =null;
            image = null;
        }
    }

    yuvImage = null;
    System.gc();
}

好吧,我尽力避免 OOM 问题。我还尝试不应用 OpenCV ,只是处理 位图 ,如下所示:

@Override
public void onStart(ConnectedNode connectedNode) {
    this.connectedNode = connectedNode;
    imagePublisher = connectedNode.newPublisher(topic_name, sensor_msgs.Image._TYPE);
}

不幸的是,它变得更糟。我怀疑我试图实现这一目标的方式。或者有更好的方法吗?

1 个答案:

答案 0 :(得分:0)

我认为您的问题可能是您的网络无法传输此数量的图像数据,而OOM是由于数据滞留在尚未传输的缓冲区中引起的。

当我想从我的Android设备传输图像时,我遇到了类似的问题。如果您的问题相同,可以通过以下几种方式解决:

关于您第二次尝试传输JPEG而不是RAW数据,请查看此源代码,此处已正确实现https://github.com/rosjava/android_core/blob/kinetic/android_10/src/org/ros/android/view/camera/CompressedImagePublisher.java#L80

通过网络传输的问题对于原始图像肯定是实际的,但如果图像的大小很大且帧速率很高,也可能是压缩的。