Error viewing image on Rqt after converting to HSV color space by OpenCV
I have a custom robot modeled in a urdf file where I have attached a camera to simulate it in gazebo. I followed the Ros wiki tutorial for converting Ros Noetic images to OpenCV.
http://wiki.ros.org/cv_bridge/Tutorials/UsingCvBridgeToConvertBetweenROSImagesAndOpenCVImages
By the help of this tutorial I was able to convert between Ros and OpenCV images. I was able to draw a small circle on the camera feed and view the image in rqt through the new image topic using OpenCV. But now I want to convert the rgb image from gazebo into HSV color space based on specific ranges. I am able to view the modified HSV image through the OpenCV image window but I cannot access the image through rqt. I have checked by the echoing to the resulting topic /imageconverter/outputvideo and all the data is being published.
But when I open rqt and select the same topic, I get the following error and a grey blank screen.
ImageView.callback_image() while trying to convert image from 'bgr8' to 'rgb8' an exception was thrown (Image is wrongly formed: step < width * byte_depth * num_channels or 800 != 800 * 1 * 3)
When i try to access the compressed topic, /imageconverter/outputvideo/compressed, I get the following error and similar blank grey screen
[ERROR] [1682104858.931709014, 22.482000000]: OpenCV(4.2.0) ../modules/imgcodecs/src/loadsave.cpp:730: error: (-215:Assertion failed) !buf.empty() in function 'imdecode_'
I can access and draw shapes the image and access it through rqt without any problem. But converting them to HSV space is a problem, although I can view the modified HSV image in the OpenCV window. I have checked the image size being through OpenCV size function and image width is 800 and height is 1080. Kindly suggest any changes I can do to be able to view the HSV image through rqt.
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
static const std::string OPENCV_WINDOW = "Image window";
class ImageConverter
{
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
image_transport::Publisher image_pub_;
public:
ImageConverter()
: it_(nh_)
{
// Subscrive to input video feed and publish output video feed
image_sub_ = it_.subscribe("/weedingrobot/camera_front/image_raw", 1,
&ImageConverter::imageCb, this);
image_pub_ = it_.advertise("/image_converter/output_video", 1);
cv::namedWindow(OPENCV_WINDOW);
}
~ImageConverter()
{
cv::destroyWindow(OPENCV_WINDOW);
}
void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
ROS_INFO_STREAM("Width " << cv_ptr->image.cols);
ROS_INFO_STREAM("Height " << cv_ptr->image.rows);
cv::Mat hsv;
cv::Mat mask;
// Draw an example circle on the video stream
if (cv_ptr->image.rows > 60 && cv_ptr->image.cols > 60)
cv::circle(cv_ptr->image, cv::Point(50, 50), 10, CV_RGB(255,0,0));
int hmin=49, smin=57, vmin=0;
int hmax=82, smax=255, vmax=255;
cv::Scalar lower(hmin, smin, vmin);
cv::Scalar upper(hmax, smax, vmax);
cv::cvtColor(cv_ptr->image, hsv, cv::COLOR_BGR2HSV);
cv::inRange(hsv,lower, upper,cv_ptr->image);
// Update GUI Window
cv::imshow(OPENCV_WINDOW, cv_ptr->image);
cv::waitKey(3);
// Output modified video stream
image_pub_.publish(cv_ptr->toImageMsg()); }
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "image_converter");
ImageConverter ic;
ros::spin();
return 0;
}
Asked by ahasan1102 on 2023-04-21 14:34:39 UTC
Answers
The ROS Image
message supports a specific list of formats (which it calls "encodings"), and HSV is not one of them.
See the comment next to "encoding" field on this documentation page:
http://docs.ros.org/en/api/sensor_msgs/html/msg/Image.html
Asked by Mike Scheutzow on 2023-04-22 14:48:39 UTC
Comments