我正在尝试将图像信息从 Android相机实时传输到 ROS 。但是,我遇到了OOM问题。我是的Android-ROS 的新手,几乎没有处理此类问题的经验。
这是我的演示的一些信息:(如果你们需要更多,请发表评论)
1。
public class MainActivity extends RosActivity implements NodeMain, SurfaceHolder.Callback, Camera.PreviewCallback
2.依赖关系 Android(3.2.0)Opencv-ojitrstrong。
3. ROS 消息类型:android_cv_bridge。
我正在尝试在onPreviewFrame()函数的中发布图像消息。像这样的代码:
@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();
}
imagePublisher 在此处初始化:
@Override
public void onStart(ConnectedNode connectedNode) {
this.connectedNode = connectedNode;
imagePublisher = connectedNode.newPublisher(topic_name, sensor_msgs.Image._TYPE);
}
好吧,我尽力避免了 OOM 问题。我还曾尝试不应用 OpenCV ,而只是像这样处理位图:
ChannelBufferOutputStream cbos = new ChannelBufferOutputStream(MessageBuffers.dynamicBuffer());
bmp.compress(Bitmap.CompressFormat.JPEG, 80, baos);
cbos.buffer().writeBytes(baos.toByteArray());
image.setData(cbos.buffer().copy());
cbos.buffer().clear();
imagePublisher.publish(image);
不幸的是,情况变得越来越糟。我怀疑我要达到这个目标的方式。还是有更好的方法?
最佳答案
我认为您的问题可能是您的网络无法传输此数量的图像数据,而OOM是由滞留在尚未传输的缓冲区中的数据引起的。
当我想从我的android设备传输图像时,我遇到了类似的问题。如果您的问题相同,则可以通过多种方式解决:
关于您第二次尝试传输JPEG而不是RAW数据的尝试,请查看此源代码,此处已正确实现https://github.com/rosjava/android_core/blob/kinetic/android_10/src/org/ros/android/view/camera/CompressedImagePublisher.java#L80
通过网络传输的问题对于原始图像肯定是实际的,但是如果图像的尺寸很大且帧速率很高,则压缩的图像也可能存在。
关于android - 将Android相机图像实时传输到ROS有OOM麻烦吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/44111249/