执行'cv :: flip(img,img,1)'的其他方法

时间:2017-12-19 10:14:35

标签: c++ opencv ros

我正在接收来自传感器的原始数据形式的图像。以下字段是已知的:

  • 宽度:1920
  • 身高:1080
  • 编码:BGRA8
  • Bytes Per Pixel:4
  • 图像数据:具有8294400个元素的1-D字节数组// 1920 * 1080 * 4 = 8294400

我需要在ROS中可视化这个图像,因此我正在编写ROS支持的图像,如下所示:

std::basic_string<char> color_pixels = color_frame.data();

//Step 1: Create OpenCV image
cv::Mat image(cv::Size(color_frame.width(), color_frame.height()), CV_8UC4, const_cast<char*>(color_pixels.data()), cv::Mat::AUTO_STEP);

//Step 2: Convert OpenCV image to CvBridge image
cv_bridge::CvImage cv_image;
cv_image.header.frame_id = frame_id;
cv_image.encoding = "bgra8";
cv_image.image = image;

//Step 3: Convert CvBridge image to ROS image
sensor_msgs::Image ros_image;
cv_image.toImageMsg(ros_image);

看起来很好。但是,在可视化期间,我注意到图像被翻转。因此,为了恢复它,我必须在步骤2之前使用cv::flip

cv::flip(image, image, 1);

由于我拥有所有原始值并且上述过程似乎很长,所以我决定直接撰写sensor_msgs::Image。但是,我无法执行cv::flip操作。

以下是我的疑问:

  1. 为什么需要flip?原始数据是否被错误捕获?
  2. 是否可以直接在字节数组中执行类似于cv::flip的操作?
  3. 我的方法 我试图反转字节数组,但它不起作用。请参阅下面的代码段:

    std::basic_string<char> color_pixels = color_data.data();
    std::vector<unsigned char> color_values(color_pixels.begin(), color_pixels.end());
    std::reverse(color_values.begin(), color_values.end());
    
    sensor_msgs::Image ros_image;
    //width, height, encoding etc. are set but not shown here
    ros_image.data = color_values;
    

1 个答案:

答案 0 :(得分:1)

可能您可以将相机设置为翻转图像。这是指定这个的适当位置。 (有时,我们的相机颠倒安装)

因为你的字节数组是{b0,g0,r0,a0,b1,g1,r1,a1,...},只需将它反转就会产生{aN,rN,gN,bN,...} ,您的格式变为argb。 cv::flip已经解释了此。只是说&#34;上述过程似乎很长没有足够的理由自己这样做:它会使你的代码复杂化,并导致opencv人员已经为你提供的复制很差。

如果确实想自己写一下,可能b = reinterpret_cast<BRGRA*>(&color_data.data().front()),并在重新解释的&#39;结构上执行reverse

struct BRGRA { char b, g, r, a };
std::reverse(
  reinterpret_cast<BRGRA*>( &data.front() ),
  reinterpret_cast<BRGRA*>( &data.back() ) + 1,
  reinterpret_cast<BRGRA*>( &data.front() ));

- 编辑

这个答案被接受而没有对建议的代码进行额外评论,这一事实证明了提供比较差的复制更难以解决的问题:上面的代码片段会反转{{3}进入matrix abcd,将其颠倒过来。 (仅查看​​&#39; 40次,但仍然......)。所以它只适用于单行图像。