rosserial publish sensor_msgs/Image from windows
rosserial publish sensor_msgs/Image from windows
我正在研究一个带有Windows的项目和Kinect V1传感器的SDK。目标是从Kinect通过ROS发送颜色图像,使用rosserial。
我不知道该如何处理。现在,我正在使用Sensor_msgs/Image消息来发布RGB值。这是我到目前为止的代码:
img.header.stamp = nh->now();
img.header.frame_id = "kinect1_ref";
img.height = height;
img.width = width;
img.encoding = "rgb8";
img.is_bigendian = false;
img.step = width*3;
BYTE* start = (BYTE*) lockedRect.pBits;
img.data = new uint8_t[width*3*height];
long it;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
const BYTE* curr = start + (x + width*y)*4;
for(int n=0; n<3; n++){
it = y*width*3 + x*3 + n;
img.data[it] = (uint8_t) curr[2-n];
}
}
}
pub->publish(&img);
在代码中, img 是传感器_MSGS/image, lockedRect.pbits 是指向Kinect图像的第一个字节的指针。据我所知,来自Kinect的图像是在从头到右顺序存储的ROW WISE,每个像素由4个顺序字节表示,代表一个填充字节,然后r,g和b。p>我实际上可以将其发送给ROS,但是当我尝试使用它来可视化时,我会收到以下错误:
错误加载图像:OGRE异常。流大小与图像中计算出的图像大小不匹配。
我对此非常叠加,考虑到RGB的3个频道,我设置的大小是正确的。从字节转换为 uint8_t 应该很琐碎,因为它们都是无符号的char。
pd:我知道我可以使用OpenNi_Launch从Ubuntu和ROS中可视化Kinect数据,但是由于语音识别引擎,我需要在这种情况下使用Windows。
pd2:通常用于在ROS中发布图像的CV_Bridge不包含在rosserial库中。因此,我必须从头开始构建图像消息(可能还有另一种方式?)
任何帮助都会真正得到认可,谢谢您!
编辑: rosserial为Windows生成的Sensor_msgs/Image Messages的类仅包含此代码:
class Image : public ros::Msg{
public:
std_msgs::Header header;
uint32_t height;
uint32_t width;
char * encoding;
uint8_t is_bigendian;
uint32_t step;
uint8_t data_length;
uint8_t st_data;
uint8_t * data;
virtual void serialize(unsigned char *outbuffer);
virtual void deserialize(unsigned char *inbuffer);}
序列化和估算化的方法都不在这里写,但我实际上不知道它们是如何工作的。
我想知道这是如何为您编译的。img.data
是std::vector<uint8_t>
。话虽如此,请尝试以下操作:
img.header.stamp = nh->now();
img.header.frame_id = "kinect1_ref";
img.height = height;
img.width = width;
img.encoding = "rgb8";
img.is_bigendian = false;
img.step = width * 3;
BYTE* start = (BYTE*) lockedRect.pBits;
img.data.resize(img.step * height);
long it;
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; ++x) {
const BYTE* curr = start + (x + width*y)*4;
for(int n=0; n<3; n++){
it = y*width*3 + x*3 + n;
img.data[it] = (uint8_t) curr[2-n];
}
}
}
pub->publish(&img);
更新:
我找到了有关rosserial_windows
限制中使用的协议的此信息。虽然,您正在指定高度和宽度以及步长,但序列化对这些消息变量不可知。我看来您还必须在data_lendth
中指定数组的长度。但这是问题。由于某种奇怪的原因,最大数组长度仅限于uint8_t
。
任何type t []的数组长度将需要设置变量t_length。这意味着如果不更改协议,您不能超过uint8_t
的限制。
一种解决方案,但痛苦和缓慢的是将图像分开255个字节自定义消息并将其索引。您必须将图像数据放在接收器端,并从数据中创建一个sensor_msgs ::图像并发布。
首先,要归功于Cassinaj,我认为解决方案将是他提出的答案。我将添加我为在同一情况下发现的一些信息。
Rosserial中阵列的限制由uint8_t
给出,在大多数ROS分布中,最多255个字节。但是,该问题已经在此线程中进行了评论,该线程提议将此值增加到uint32_t
。更改是在Jade Devel进行的。因此,如果您从JADE中的Rosserial生成 ROS_LIB 库,则数据的Lenght应该为uint32_t
。现在,这是图像消息的生成代码:
class Image : public ros::Msg
{
public:
std_msgs::Header header;
uint32_t height;
uint32_t width;
const char* encoding;
uint8_t is_bigendian;
uint32_t step;
uint32_t data_length;
uint8_t st_data;
uint8_t * data;
Image():
header(),
height(0),
width(0),
encoding(""),
is_bigendian(0),
step(0),
data_length(0), data(NULL)
{
}
virtual int serialize(unsigned char *outbuffer) const
virtual int deserialize(unsigned char *inbuffer)
我期望现在一切正常,但出现了另一个问题。尽管数组的长度可以是一个高值,但rosserial消息的缓冲区仍然仅限于低值。我想是协议本身受到限制。然后,我无法发送480x640xrgb的整个图像消息,但是在我测试的情况下,我可以发送一部分图像(8x8xrgb)。最终起作用了,我在RVIZ中看到了图像,没有问题。
因此,正如Cassinaj提出的那样,一个解决方案是将所有数据分成部分,然后将它们全部放在接收器侧。尽管听起来确实很痛苦,但这应该可以起作用(如果我将图像分为8x8部分,那将是一个图像的4800条消息!)。
因此,我试图使用win_ros(Windows的ROS),以通过ROS本身从Kinect发送所有数据。可惜的是,Rosserial具有这些限制,因为它确实很容易使用和实施。
如果有人还有其他要添加的东西,或者我缺少一些东西,请告诉我。任何帮助确实得到认可!
- 如何解决"invalid conversion from 'char' to 'const char*'"
- 以线程安全的方式调用"QQuickPaintedItem::updateImage(const QImage&image)"(no QThread)
- std::async from std::async in windows xp
- Inference pytorch C++ with alexnet and cv::imread image
- std::is_reference from std::any
- 如何在QTextEdit中添加URL或IMAGE-URL
- std::time_point from and to std::string
- "No suitable conversion function from 'std::string' to 'const char *' exists"
- std::chrono::time_point from std::string
- Visual accept std::string from std::byte iterator
- JNA 将 HICON 转换为 Java Image
- C++中链表的错误"Abort signal from abort(3) (sigabrt) "
- dopen():不以 root 身份运行时"failed to map segment from shared object"
- C++ 中的"template <typename From, typename Tag> struct Alias;"是什么?
- from std::vector to adept::avector
- qt get child (Callout) from QChart
- 如何在c++中将image.jpg转换为image.ppm
- Webassembly from Javascript
- 运行"OpenPose C++ API Tutorial - Example 3 - Body from image"失败
- rosserial publish sensor_msgs/Image from windows