I attempted to publish and display an image from a video using cv2 and ros2. Although the code compiled successfully, running it consistently resulted in a memory allocation failure. Could someone clarify the reason for this failure? Interestingly, when I comment out the section of code responsible for displaying an image, the publishing process works correctly, allowing me to observe the output in rviz. Conversely, if I comment out the code responsible for publishing the image and retain the code for displaying a frame, it successfully creates a window and displays frames without any issues.
Ubuntu 22.04 ROS2 Humble OpenCV 4.8 built from source with cuda support
void Video::loadVideo(const std::string &video_path)
{
cv::VideoCapture cap(video_path);
if (!cap.isOpened())
{
RCLCPP_ERROR(this->get_logger(), "Failed to open the video file: ");
return;
}
cv::Mat frame(cv::Size(1280, 720), CV_8UC3);
while (rclcpp::ok())
{
cap >> frame;
if (frame.empty())
break;
sensor_msgs::msg::Image::SharedPtr msg =
cv_bridge::CvImage(std_msgs::msg::Header(), "bgr8", frame).toImageMsg();
_img_pub->publish(*msg.get());
// cv::imshow("Frame", frame);
// cv::waitKey(1);
// char c = (char)cv::waitKey(25);
// if (c == 27)
// break;
}
}
when I uncomment
cv::imshow("Frame", frame);
cv::waitKey(1);
I get something like:
what(): OpenCV(4.8.0-dev) /home/oskar/opencv/opencv/modules/core/src/alloc.cpp:73: error: (-4:Insufficient memory) Failed to allocate 62285023075440 bytes in function 'OutOfMemoryError'
Thanks in advance
Solution:
cv::VideoCapture cap(video_path); -> cv::VideoCapture cap(video_path, cv::CAP_FFMPEG);
cv::Mat frame_for_imshow = frame.clone();
before the SharedPtr creation, and use frame_for_imshow in the imshow? $\endgroup$