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

问题描述 投票:1回答:1

我从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的操作?

我的方法我试图反转字节数组但它没有用。请参阅下面的代码段:

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;
c++ opencv ros
1个回答
1
投票

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

因为你的字节数组是{b0,g0,r0,a0,b1,g1,r1,a1,...},所以只需将它反转就会产生{aN,rN,gN,bN,...}和你的格式变成了argb。 cv::flip已经解释了这一点。只是说“上面的过程似乎很长”并不足以让你自己做到这一点:它会使你的代码变得复杂,并且会导致opencv人员已经为你提供的复制很糟糕。

如果你真的想自己编写,也许是b = reinterpret_cast<BRGRA*>(&color_data.data().front()),并在重新解释的'结构'上做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() ));

- 编辑

事实上这个答案被接受而没有对建议的代码做出额外的评论,这证明了它很难提供比“糟糕复制”更好的观点:上面的代码片段会将matrix abcd反转为enter image description here,将其颠倒过来。 (只看了'40次,但仍然......)。因此它只适用于单行图像。

© www.soinside.com 2019 - 2024. All rights reserved.