Я использую ROS и OpenCV в среде C ++, чтобы получить видео (оттенки серого) с узла ROS, преобразовать данные через cv_bridge (чтобы проработать его через OpenCV), извлечь некоторые данные и опубликовать их по теме как сообщения ROS.
Моя проблема в том, что я не знаю, как отправить массив frame
к main
функция для того, чтобы разработать это! Я не могу уточнить из этого, потому что мне нужно различать разные данные разных кадров.
Это мой код:
#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>
#include <vector>
#include "rd_ctrl/proc_data.h"#include <cv.h>
using namespace std;
namespace enc = sensor_msgs::image_encodings;rd_ctrl::proc_data points;
ros::Publisher data_pub_;
static const char 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_)
{
image_pub_ = it_.advertise("out", 1);
image_sub_ = it_.subscribe("/vrep/visionSensorData", 1, &ImageConverter::imageCb, this);cv::namedWindow(WINDOW);
}
~ImageConverter()
{
cv::destroyWindow(WINDOW);
}
void imageCb(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_ptr;
try
{
cv_ptr = cv_bridge::toCvCopy(msg, enc::BGR8);
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
CvMat frame= cv_ptr->image; //definition of "frame"cvSmooth(&frame, &frame, CV_MEDIAN);
cvThreshold(&frame, &frame,200, 255,CV_THRESH_BINARY);
cv::imshow(WINDOW, cv_ptr->image);
cv::waitKey(3);
image_pub_.publish(cv_ptr->toImageMsg());
}
};int main(int argc, char** argv)
{
ros::init(argc, argv, "image_proc");
ImageConverter ic;
ros::NodeHandle n;
//....elaboration of "frame" and production of the data "points"
data_pub_.publish(points);
data_pub_ = n.advertise<rd_ctrl::proc_data>("/data_im", 1);
ros::spin();
return 0;
}
Я надеюсь, что вопрос достаточно ясен. Не могли бы вы мне помочь?
Теперь, если я вас правильно понимаю, вы хотите позвонить imageCb
и кадр, который он создает, передается обратно main
, Если это действительно так, то вы можете изменить imageCb
следующее:
void imageCb(const sensor_msgs::ImageConstPtr& msg, cv::Mat frame )
Вам нужно будет создать рамку в main
и передать imageCb
:
cv::Mat frame ;
ic.imageCb( ..., frame ) ;
Это будет использовать конструктор копирования, он будет просто копировать заголовок и использовать указатель на фактические данные, поэтому это не будет очень дорогим.
Этот предыдущий нить имеет гораздо более подробную разработку конструктора копирования cv :: Mat.
Других решений пока нет …