ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question
0

Why do I get inverted colors in my images?

asked 2017-11-17 05:56:23 -0600

VictorLamoine gravatar image

updated 2017-11-17 05:57:18 -0600

I am fetching images from a camera/webcam and publishing it's images using image_transport. When viewed in RViz the images look correct however when recorded with rosbag the compressed image shows inverted colors.

Here is the node to record the images:

#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <opencv2/highgui/highgui.hpp>
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <cv_bridge/cv_bridge.h>
#pragma GCC diagnostic pop

int main(int argc,
         char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;
  image_transport::ImageTransport it(nh);
  image_transport::Publisher pub = it.advertise("camera", 1);

  cv::VideoCapture cap;
  if (!cap.open(0))
    return 1;

  ros::Rate loop_rate(25);
  while (nh.ok())
  {
    cv::Mat frame;
    cap >> frame;
    if (frame.empty())
      break;

    sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();
    pub.publish(msg);
    ros::spinOnce();
    loop_rate.sleep();
  }

  return 0;
}

Minimal example package: https://gitlab.com/InstitutMaupertuis...

RViz

RViz

rqt_bag

rqt_bag

Why are the colors inverted in the compressed image when reading the bag file?

edit retag flag offensive close merge delete

Comments

1

Hello there! Are you sure your format to output these images is "bgr8" and not "rgb8"? This is a typical issue because how openCV handles images, inverting order of input channels of colors. I am not but you can try and give us feedback.

CesarHoyosM gravatar image CesarHoyosM  ( 2017-11-17 06:51:00 -0600 )edit

@CesarHoyosM I think so while not being 100% sure. If I use rgb8 then the colors are inverted in RViz and in the raw image in the bag file, but then the compressed image has the right colors. In short: this inverts the problem

VictorLamoine gravatar image VictorLamoine  ( 2017-11-20 01:41:39 -0600 )edit

1 Answer

Sort by ยป oldest newest most voted
0

answered 2017-11-27 03:32:43 -0600

VictorLamoine gravatar image

I am most probably missing a point, either I am not using image_transport properly or there is a bug in the image_transport package.

The best alternative I have found now is the following one:

#include <ros/ros.h>
#include <opencv2/opencv.hpp>
#pragma GCC diagnostic ignored "-Wunused-parameter"
#include <cv_bridge/cv_bridge.h>
#pragma GCC diagnostic pop

int main(int argc,
         char** argv)
{
  ros::init(argc, argv, "image_publisher");
  ros::NodeHandle nh;

  std::string publish_topic("/webcam");
  ros::Publisher pub = nh.advertise<sensor_msgs::Image>(publish_topic, 5);
  ros::Publisher c_pub = nh.advertise<sensor_msgs::CompressedImage>(publish_topic + "/compressed", 5);

  cv::VideoCapture cap;
  if (!cap.open(0))
    return 1;

  ros::Rate loop_rate(25);
  while (nh.ok())
  {
    cv::Mat frame;
    cap >> frame;
    if (frame.empty())
      continue;

    sensor_msgs::ImagePtr msg = cv_bridge::CvImage(std_msgs::Header(), "bgr8", frame).toImageMsg();
    sensor_msgs::CompressedImagePtr c_msg =
        cv_bridge::CvImage(std_msgs::Header(), "rgb8", frame).toCompressedImageMsg();

    pub.publish(msg);
    c_pub.publish(c_msg);
    ros::spinOnce();
    loop_rate.sleep();
  }

  return 0;
}

I set two publishers: one for the raw image (bgr8 encoding) and one for the compressed image (rgb8 encoding) This way I get both the JPEG compressed images and the raw image with decent performance and the right colors.

edit flag offensive delete link more

Comments

I will not mark this answer as correct as this is only a "good alternative", it does not answer the question.

VictorLamoine gravatar image VictorLamoine  ( 2017-11-27 03:33:53 -0600 )edit

Question Tools

2 followers

Stats

Asked: 2017-11-17 05:56:23 -0600

Seen: 1,173 times

Last updated: Nov 27 '17