试图找到一种在OpenCV/BOOST中记录图形数据的方法 [英] Trying to find a way to LOG Graphical data in OpenCV/BOOST

查看:68
本文介绍了试图找到一种在OpenCV/BOOST中记录图形数据的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,:我正在使用OpenCV C ++进行图像处理.在C ++程序中加载Mat图像后,我使用GNUPLOT绘制了图像图.

To begin with: I am working on Image Processing using OpenCV C++. After loading a Mat image in a C++ program, I plotted a graph of the image using GNUPLOT.

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

Now, The Requirement is to log the graphical data of the Mat image.

为此,我通过包含所有BOOST库创建了BOOST C ++记录器. BOOST也是用于测试和记录数据的出色库,但是Log的问题在于它只能记录文本消息.如我错了请纠正我.

To do this, I created a BOOST C++ Logger by including all BOOST Libraries. BOOST is an excellent library for Testing and logging data as well but, the problem with the it's Log is that it could log only text messages. Correct me if I'm wrong.

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

Below is my CODE for plotting graph using GNUPlot in OpenCV:

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;

这是我的 BOOST日志代码:

namespace logging = boost::log;
void PlainGetEdgeVector::init()
{

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

}

BOOST_LOG_TRIVIAL(info) << "This is my first Log line";

好消息是,我的BOOST Logger成功记录了短信.如果它也可以记录我的图形数据,那就太好了.

The good news is, my BOOST Logger successfully logs the text message. It would be great if it could log my graphical data as well.

有什么建议吗?如果有人知道如何使用BOOST实现相同的功能,我将不胜感激,或者如果有其他选择,也很高兴知道这一点.

Any suggestions? If anyone knows how to implement the same using BOOST, I would be very grateful or if there are any alternatives, good to know that as well.

推荐答案

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

The solution to your problem greatly depends on the nature of the data how do you want to use the logged data.

出于调试目的,将二进制数据转换为文本通常更为方便.即使有大量数据,这种方法也很有用,因为与用于处理任意二进制数据相比,用于文本处理的工具通常要多得多.例如,您可以使用常规的合并/比较工具将来自应用程序不同运行的两个日志进行比较,以查看差异.文本日志也更容易使用grepawk之类的工具进行过滤,这些工具易于使用,而二进制数据则可能需要您为其编写解析器.

For debugging purposes it is often more convenient to convert your binary data to text. Even with large amounts of data this approach can be useful because there are generally many more tools for text processing than for working with arbitrary binary data. For instance, you could compare two logs from different runs of your application with conventional merge/compare tools to see the difference. Text logs are also easier to filter with tools like grep or awk, which are readily available, as opposed to binary data for which you will likely have to write a parser.

有很多方法可以将二进制数据转换为文本.最直接的方法是使用

There are many ways to convert binary data to text. The most direct approach is to use the dump manipulator, which will efficiently produce textual view of a raw binary data. It suits graphical data as well because it tends to be relatively large in amounts and it is often easy enough to compare in text representation (e.g. when a color sample fits a byte).

std::vector< std::uint8_t > image;
// Outputs hex dump of the image
BOOST_LOG_TRIVIAL(info) << logging::dump(image.data(), image.size());

一种更结构化的输出二进制数据的方式是使用其他库,例如

A more structured way to output binary data is to use other libraries, such as iterator_range from Boost.Range. This can be useful if your graphical data is composed of something more complex than raw bytes.

std::vector< double > image;
// Outputs all elements of the image vector
BOOST_LOG_TRIVIAL(info) << boost::make_iterator_range(image);

您还可以编写自己的操纵器,以所需的方式格式化数据,例如按行划分输出.

You can also write your own manipulator that will format the data the way you want, e.g. split the output by rows.

如果打算通过更专业的软件(例如图像查看器或编辑器)处理记录的数据,则可能需要以二进制形式保存数据.这可以通过Boost.Log来完成,但是将需要更多的精力,因为库提供的接收器是面向文本的,并且您不能按原样将二进制数据保存到文本文件中.您将必须编写一个 sink后端,它将以所需的格式写入二进制数据(例如,如果您打算使用图像编辑器,则可能要以该编辑器支持的格式写入文件).有一个教程

If you intend to process the logged data by a more specialized piece of software, like an image viewer or editor, you might want to save the data in binary form. This can be done with Boost.Log, but it will require more effort because the sinks provided by the library are text-oriented and you cannot save a binary data into a text file as is. You will have to write a sink backend that will write binary data in the format you want (e.g. if you plan to use an image editor you might want to write files in the format supported by that editor). There is a tutorial here, which shows the interface you have to implement and a sample implementation. The important bit is the consume function of the backend, which will receive a log record view with your data.

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
        }
    }
};

为了将图像二进制数据传递到接收器,您需要将其作为属性附加到日志记录.有多种方法可以执行此操作,但是假设您不打算根据图像过滤日志记录,最简单的方法是使用

In order to pass your image binary data to your sink you will need to attach it to the log record as an attribute. There are multiple ways to do that, but assuming you don't intend to filter log records based on the image, the easiest way to do this is to use the add_value manipulator.

std::vector< double > image;
BOOST_LOG_TRIVIAL(info) << logging::add_value(a_image, image) << "Catch my image";

注意事项:为了避免复制可能较大的图像数据,我们传递了一个轻量级的iterator_range作为属性值.这仅适用于同步日志记录,因为在处理日志记录时image向量需要保持活动状态.对于异步日志记录,您将必须按值传递图像或使用引用计数.

Caveat: In order to avoid copying the potentially large image data, we're passing a lightweight iterator_range as the attribute value. This will only work with synchronous logging because the image vector needs to stay alive while the log record is being processed. For async logging you will have to pass the image by value or use reference counting.

如果您确实想对图像数据应用过滤器,则可以使用

If you do want to apply filters to the image data then you can use scoped attributes or add the attribute to a logger.

请注意,通过添加用于写入二进制数据的新接收器,您并不排除还会与其他接收器一起编写文本日志,以便文本接收器可以处理捕获我的图像"消息.通过使用其他属性,例如日志记录

Note that by adding your new sink for writing binary data you do not preclude also writing textual logs with other sinks, so that "Catch my image" message can be processed by a text sink. By using other attributes, like log record counters you can associate log records in different files produced by different sinks.

这篇关于试图找到一种在OpenCV/BOOST中记录图形数据的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆