我试图将图片信息从 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);
}
不幸的是,它变得更糟。我怀疑我试图实现这一目标的方式。或者有更好的方法吗?
答案 0 :(得分:0)
我认为您的问题可能是您的网络无法传输此数量的图像数据,而OOM是由于数据滞留在尚未传输的缓冲区中引起的。
当我想从我的Android设备传输图像时,我遇到了类似的问题。如果您的问题相同,可以通过以下几种方式解决:通过usb网络共享传输数据,它通常比wifi或蜂窝网络快得多,甚至可以传输原始图像流而无需压缩30 fps 640x480。对于Jpeg,我认为你将能够以30 fps的速度传输FullHD。
将手机上的数据保存到ROS Bag http://wiki.ros.org/rosbag,然后处理数据。在这里你错过了实时,但有时它不需要。为了实现这一点,我实际上为android https://github.com/lamerman/ros_android_bag编写了一个应用程序,您也可以直接从Google Play下载https://play.google.com/store/apps/details?id=org.lamerman.rosandroidbag&hl=en
尝试进一步降低带宽(减小图像尺寸,fps)或提高网络质量
关于您第二次尝试传输JPEG而不是RAW数据,请查看此源代码,此处已正确实现https://github.com/rosjava/android_core/blob/kinetic/android_10/src/org/ros/android/view/camera/CompressedImagePublisher.java#L80
通过网络传输的问题对于原始图像肯定是实际的,但如果图像的大小很大且帧速率很高,也可能是压缩的。