【问题标题】:How to know/set the frequency at which the images are taken (grabbed)?如何知道/设置拍摄(抓取)图像的频率?
【发布时间】:2016-07-20 07:25:47
【问题描述】:

我已经在 ros 论坛上发布了这个问题,但我想再次在这里发布以覆盖更多的受众。

问题是我发现我从两个连续回调之间的时间计算的频率与使用 rostopic hz 计算的频率完全不同......

rostopic hz /pg_15508342/image_raw 我得到:

average rate: 99.681
    min: 0.003s max: 0.017s std dev: 0.00093s window: 797
average rate: 99.683
    min: 0.003s max: 0.017s std dev: 0.00098s window: 896
average rate: 99.682
    min: 0.003s max: 0.017s std dev: 0.00100s window: 997
average rate: 99.682
    min: 0.003s max: 0.017s std dev: 0.00098s window: 1097
average rate: 99.684
    min: 0.002s max: 0.018s std dev: 0.00102s window: 1196
average rate: 99.681
    min: 0.002s max: 0.018s std dev: 0.00106s window: 1296
average rate: 99.676

但是,从这个非常短的代码中,它计算了调用同一主题的回调的频率,

#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 <time.h>
#include <boost/timer.hpp>
#include <boost/thread.hpp>
#include <boost/thread/thread.hpp>
#include <boost/version.hpp>
#include  "boost/bind.hpp"
#include  "boost/bind.hpp"
#include <iostream>

using namespace std;

boost::posix_time::ptime time1; 
boost::posix_time::time_duration timeloop;
double timeloop_sc;

int image_itr(0);

void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
     //---
      if(image_itr == 0)
        time1 = boost::posix_time::microsec_clock::local_time();

      timeloop =  boost::posix_time::microsec_clock::local_time() - time1;
  time1 = boost::posix_time::microsec_clock::local_time();
  timeloop_sc = 1e-3* (double)timeloop.total_milliseconds();
  cout << "itr " << image_itr++ << "   fps: " << 1.0/timeloop_sc << endl;

}

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

  cv::namedWindow("view");
  cv::startWindowThread();
  image_transport::ImageTransport it(nh);
  image_transport::Subscriber sub = it.subscribe("/pg_15508342/image_raw", 1, imageCallback);
  ros::spin();
  cv::destroyWindow("view");
}

我得到这个不一致的结果

itr 2198   fps: 100
itr 2199   fps: 111.111
itr 2200   fps: 90.9091
itr 2201   fps: 111.111
itr 2202   fps: 111.111
itr 2203   fps: 111.111
itr 2204   fps: 100
itr 2205   fps: 111.111
itr 2206   fps: 100
itr 2207   fps: 100
itr 2208   fps: 90.9091
itr 2209   fps: 125
itr 2210   fps: 100.

为什么会有这种价值观差异?

另外,如果我从另一台主机运行相同的代码,但只添加cv::imshowfrom,我会得到一个完全不同的值。更清楚地说,假设我使用local 机器,而我的 ros 节点是在onboard 机器上实现和编译的。我是从local 做的:

ssh onboard@ip
rosrun package node

也许cv::imshowfrom 正在消耗大量带宽....但是代码应该在onboard 机器上而不是在local 机器上运行,因此计算时间应该是相同的。

有关信息,我使用的是 Point Grey 相机,Chameleon 3。至于驱动程序,我使用的是来自 Kumar 机器人驱动程序https://github.com/KumarRobotics/flea3 的 ROS flea3 节点。我在 ubuntu 16、4.6.4-040604-lowlatency 内核上运行它。

【问题讨论】:

  • 所有这些标签与您的问题有什么关系?这不是一个 C++ 问题。这不是 ssh 问题...
  • @AndersLindén 我更新了我的问题

标签: image-processing frame-rate ros


【解决方案1】:

嗯,我认为您对回调调用时间的估计与rostopic hz 所做的不完全一样。为了更接近,请尝试仅计算回调调用之间的延迟而不进行任何进一步处理。这将避免额外的计算时间。

void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
 if(image_itr == 0)
        time1 = boost::posix_time::microsec_clock::local_time();

  timeloop =  boost::posix_time::microsec_clock::local_time() - time1;
  time1 = boost::posix_time::microsec_clock::local_time();
  timeloop_sc = 1e-3* (double)timeloop.total_milliseconds();
  cout << "itr " << image_itr++ << "   fps: " << 1.0/timeloop_sc << endl;
}

另外,将回调队列大小设置为较大的值,从而避免由于队列大小过小而丢弃图像。

image_transport::Subscriber sub = it.subscribe("/pg_15508342/image_raw", 1000, imageCallback);

另外,如果您提及您在 ROS 下使用的相机类型和驱动程序,我认为会有所帮助。

希望有帮助!

【讨论】:

  • 我发现我犯了一个愚蠢的错误。事实上,这 30 fps 是由于命令 waitKey(30) 造成的。我现在完全删除了那部分....但仍然存在不一致的问题。我正在更新我的问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-11
  • 2012-05-23
  • 1970-01-01
  • 1970-01-01
  • 2021-09-05
  • 2015-03-07
相关资源
最近更新 更多