1

我正在尝试创建光分布图。我想确切地做这个问题的第一步:Statistical analysis on Bell shape (Gaussian) curve

现在我有一个值数组。我希望数组元素的索引号位于绘图的 x 轴上,并且存储在索引处的实际值位于 y 轴上。我正在尝试使用 OpenCV 来做到这一点,但 OpenCV 的直方图函数似乎只绘制值的频率,没有别的。

4

1 回答 1

1

我发现 cvplot 很有用,虽然非常有限:http ://code.google.com/p/cvplot/

此外,嵌入 python 并从 C++ 提供 matplotlib 命令也相当容易。我用它来生成漂亮的图形,你肯定不会从 cvplot 得到。这是一个又快又脏的类,后面是一个例子,但没有doco(当然matplotlib有一堆doco):

// Interface to Python's Matplotlib
#include <Python.h>     
using namespace std;

class PyPlot
{
private:
    // Singleton Constructor
    PyPlot() : locked(false)
    {
        Py_SetProgramName("argv[0]");  /* optional but recommended */
        Py_Initialize();

        PyRun_SimpleString(
            "import numpy as np\n"
            "import matplotlib.pyplot as plt\n"
            "import matplotlib.text as text\n"
            "import matplotlib as mpl\n"
            );
    }

    ~PyPlot()
    {
        Py_Finalize();
    }


    // prevent copies of singleton
    PyPlot(PyPlot const&);    // No  implemention
    void operator=(PyPlot const&); // No implemention


    string to_string(double dval)
    {  
        return std::to_string(long double(dval));
    }

    string to_string(int ival)
    {      
        return std::to_string(long long(ival));
    }


public:
    // get singleton instance
    static PyPlot& getInstance()
    {
        static PyPlot    instance; // Guaranteed to be destroyed.
        // Instantiated on first use.
        return instance;
    }

    // prevent reentry to Matplotlib's show()
    bool locked;


    inline void print_time()
    {
        PyRun_SimpleString("from time import time,ctime\n"
                     "print 'Today is',ctime(time())\n");
    }

    inline void exec(string command)
    {
        PyRun_SimpleString(command.c_str());
    }

    inline void show()
    {
        locked = true;
        exec("plt.show()\n");
        locked = false;
    }

    inline void title(string s, string args = "")
    {
        string command = "plt.title(r'" + s + "'";
        if(args.length() != 0)
            command += ", " + args;
        command += ")\n";
        exec(command);
    }

    inline void xlabel(string s, string args = "")
    {
        string command = "plt.xlabel(r'" + s + "'";
        if(args.length() != 0)
            command += ", " + args;
        command += ")\n";
        exec(command);
    }

    inline void ylabel(string s, string args = "")
    {
        string command = "plt.ylabel(r'" + s + "'";
        if(args.length() != 0)
            command += ", " + args;
        command += ")\n";
        exec(command);
    }

    inline void legend(string args = "")
    {
        string command = "plt.legend(";
        if(args.length() != 0)
            command += args;
        command += ")\n";
        exec(command);
    }

    template <typename T>
    inline void define_vector(string name, vector<T> values)
    {
           string command = name + " = [";

           vector<T>::iterator it;
           for(it = values.begin(); it != values.end(); it++)
           {
               command += to_string(*it);

               if(it + 1 != values.end())
                   command += ", ";
           }
           command += "]\n";
           exec(command);
    }

    template <typename T>
    inline void plot(vector<T> x, vector<T> y, string args = "")
    {
        define_vector("x", x);
        define_vector("y", y);

        string command = "plt.plot(x, y";
        if(args.length() != 0)
            command += ", " + args;
        command += ")\n";
        exec(command);
    }

    template <typename T>
    inline void plot(vector<T> y, string args = "")
    {
        define_vector("y", y);
        vector<int> x;
        for(unsigned int i = 0; i < y.size(); i ++)
            x.push_back(i);

        define_vector("x", x);

        string command = "plt.plot(x, y";
        if(args.length() != 0)
            command += ", " + args;
        command += ")\n";
        exec(command);
    }

    inline void example()
    {
        double xa[] = {0.5,   0.7,   0.9 ,   1.3 ,   1.7 ,   1.8};
        vector<double> x;
        x.assign(xa, xa + 6);

        double ya[] = {0.1 ,   0.2 ,   0.75 ,   1.5 ,   2.1 ,   2.4};
        vector<double> y;
        y.assign(ya, ya + 6);

        plot(x, y);
        plot(x, y, "'go', markersize=20");

        exec(
            "plt.xticks( np.arange(0,3) )\n"
            "plt.yticks( np.arange(0,2.5,0.2) )\n"
            );
        xlabel("x axis");
        ylabel("y axis");
        title("My Plot Example");
        show();
    }
};

#endif

然后像这样使用它:

PyPlot &plt = PyPlot::getInstance();

std::vector<int> values;

plt.exec("mpl.rcParams['font.family']='Times New Roman'\n"
         "mpl.rcParams['lines.linewidth'] = 2\n"
            "mpl.rcParams['axes.linewidth'] = 3\n"
            "mpl.rc('xtick', labelsize=12)\n"
            "mpl.rc('ytick', labelsize=12)\n"
            "ax = plt.gca()\n"
            "ax.set_ylim(0, 100)\n"
            );

plt.plot(values, "'go-', label='values'");
plt.ylabel("Value", "fontsize=14");
plt.xlabel("Index", "fontsize=14");
plt.show();

这具有创建直方图所需的 matplotlib 命令:http: //matplotlib.org/examples/api/histogram_demo.html

当然,您需要安装 Python。Python 2.7.3 / Win 7/ VS2010/ OpenCV 2.4.4 一切正常

于 2013-06-11T23:15:44.183 回答