试图找到在OpenCV/BOOST中记录图形数据的方法 强:我是用OpenCV C++进行图像处理的。在C++程序中加载了一个MAT图像之后,用GnUpTrave.//i绘制了一幅图像的图形。p>

试图找到在OpenCV/BOOST中记录图形数据的方法 强:我是用OpenCV C++进行图像处理的。在C++程序中加载了一个MAT图像之后,用GnUpTrave.//i绘制了一幅图像的图形。p>,c++,opencv,logging,boost,boost-log,C++,Opencv,Logging,Boost,Boost Log,现在,要求是记录Mat图像的图形数据 强>为执行此< >,我通过包含所有升压库创建了一个Boost C++日志器。BOOST也是一个优秀的测试和记录数据的库,但它的日志的问题是它只能记录文本消息。如果我错了,请纠正我 下面是我在OpenCV中使用GNUPlot绘制图形的代码: try { Gnuplot g1("lines"); std::vector<double> rowVector; std::vector<double> rowVec

现在,要求是记录Mat图像的图形数据

<>强>为执行此< <强> >,我通过包含所有升压库创建了一个Boost C++日志器。BOOST也是一个优秀的测试和记录数据的库,但它的日志的问题是它只能记录文本消息。如果我错了,请纠正我

下面是我在OpenCV中使用GNUPlot绘制图形的代码:

try
{
    Gnuplot g1("lines"); 

    std::vector<double> rowVector;
    std::vector<double> rowVectorExp;

    for (int i = 0; i < 50; i++)  
    {
        rowVector.push_back((double)i); 
        rowVectorExp.push_back((double)exp((float)i/10.0));

    }
    cout << "*** user-defined lists of doubles" << endl;
    g1 << "set term png";
    g1 << "set output \"test.png\"";

    //type of plot pattern
    g1.set_grid().set_style("lines"); 

    g1.plot_xy(rowVector, rowVectorExp, "user-defined points 2d");

    waitKey(0);
}
catch (GnuplotException ge)
{
    cout << ge.what() << endl;
}

cout << endl << "*** end of gnuplot example" << endl;
namespace logging = boost::log;
void PlainGetEdgeVector::init()
{

 logging::add_file_log("sample%3N.log");

}

BOOST_LOG_TRIVIAL(info) << "This is my first Log line";
试试看
{
Gnuplot g1(“行”);
std::向量行向量;
std::vector rowVectorExp;
对于(int i=0;i<50;i++)
{
rowVector.push_back((双)i);
rowVectorExp.push_back((double)exp((float)i/10.0));
}

cout问题的解决方案在很大程度上取决于数据的性质—您希望如何使用记录的数据

1.重新考虑将二进制数据转换为文本 出于调试目的,将二进制数据转换为文本通常更为方便。即使有大量数据,这种方法也很有用,因为文本处理的工具通常比处理任意二进制数据的工具多得多。例如,您可以使用使用常规的合并/比较工具查看差异。文本日志也更容易使用
grep
awk
等工具进行过滤,这些工具随时可用,而二进制数据可能需要编写解析器

将二进制数据转换为文本的方法有很多种。最直接的方法是使用操纵器,它将有效地生成原始二进制数据的文本视图。它也适合图形数据,因为图形数据的数量往往相对较大,并且在文本表示法中通常很容易进行比较(例如,当颜色样本适合一个字节时)

您还可以编写自己的操纵器,以您想要的方式格式化数据,例如按行分割输出

2.对于二进制数据,请使用属性和自定义接收器后端 如果您打算使用更专业的软件(如图像查看器或编辑器)处理记录的数据,您可能希望以二进制形式保存数据。这可以通过Boost.Log完成,但需要付出更多的努力,因为库提供的接收器是面向文本的,您无法将二进制数据按原样保存到文本文件中您必须编写一个接收器后端,该后端将以您想要的格式写入二进制数据(例如,如果您计划使用图像编辑器,您可能希望以该编辑器支持的格式写入文件)。有一个教程,其中显示了您必须实现的界面和一个示例实现。重要的一点是后端的
消费
功能,它将接收包含您的数据的日志记录视图

typedef boost::iterator_range< const double* > image_data;
BOOST_LOG_ATTRIBUTE_KEYWORD(a_image, "Image", image_data)

class image_writer_backend :
    public sinks::basic_sink_backend< sinks::synchronized_feeding >
{
public:
    void consume(logging::record_view const& rec)
    {
        // Extract the image data from the log record
        if (auto image = rec[a_image])
        {
            image_data const& im = image.get();

            // Write the image data to a file
        }
    }
};
警告:为了避免复制可能较大的映像数据,我们将传递一个轻量级的
迭代器\u range
作为属性值。这只适用于同步日志记录,因为在处理日志记录时,
映像
向量需要保持活动状态。对于异步日志记录,必须通过v传递映像值或使用引用计数

如果确实要对图像数据应用过滤器,则可以使用该属性或将其添加到

请注意,通过添加用于写入二进制数据的新接收器,您并不排除与其他接收器一起写入文本日志,以便文本接收器可以处理“捕获我的图像”消息。通过使用其他属性(如日志记录),您可以将不同接收器生成的不同文件中的日志记录关联起来

std::vector< double > image;
// Outputs all elements of the image vector
BOOST_LOG_TRIVIAL(info) << boost::make_iterator_range(image);
typedef boost::iterator_range< const double* > image_data;
BOOST_LOG_ATTRIBUTE_KEYWORD(a_image, "Image", image_data)

class image_writer_backend :
    public sinks::basic_sink_backend< sinks::synchronized_feeding >
{
public:
    void consume(logging::record_view const& rec)
    {
        // Extract the image data from the log record
        if (auto image = rec[a_image])
        {
            image_data const& im = image.get();

            // Write the image data to a file
        }
    }
};
std::vector< double > image;
BOOST_LOG_TRIVIAL(info) << logging::add_value(a_image, image) << "Catch my image";