OpenCV每日函数 使用OpenCV的Plot2d绘图模块

一、Plot2d类

        模块位于opencv_contrib内。在附属模块中提供了与python/matlab相似的plot绘制折线图的功能。

        此绘图模块允许您轻松绘制一维或二维数据。您可以更改窗口的大小、轴的范围和每个元素的颜色。 您还可以实时显示正在构建的绘图或将绘图保存为图像 (png)。

        虽然功能感觉没有python或者matlab强大,不过用惯了opencv的话,绘制一般的1d、2d图形/图像的要求还是完全可以满足的。

1、函数原型

        数据渲染

virtual void     render (OutputArray _plotResult)=0

        设置网格数量 

virtual void     setGridLinesNumber (int gridLinesNumber)=0

        是否反转方向

virtual void     setInvertOrientation (bool _invertOrientation)=0

       设置坐标系最大最小

virtual void     setMaxX (double _plotMaxX)=0
virtual void     setMaxY (double _plotMaxY)=0
virtual void     setMinX (double _plotMinX)=0
virtual void     setMinY (double _plotMinY)=0

        如果为真,则相邻的绘图点将通过线连接。 在其他情况下,数据将被绘制为一组独立点。 

virtual void     setNeedPlotLine (bool _needPlotLine)=0

        /设置相关颜色、线条粗细、文字大小、颜色等

virtual void     setPlotAxisColor (Scalar _plotAxisColor)=0
virtual void     setPlotBackgroundColor (Scalar _plotBackgroundColor)=0
virtual void     setPlotGridColor (Scalar _plotGridColor)=0
virtual void     setPlotLineColor (Scalar _plotLineColor)=0
virtual void     setPlotLineWidth (int _plotLineWidth)=0
virtual void     setPlotSize (int _plotSizeWidth, int _plotSizeHeight)=0
virtual void     setPlotTextColor (Scalar _plotTextColor)=0

        设置将在绘图左上角打印坐标的点的索引(如果 ShowText 标志为真)。

virtual void     setPointIdxToPrint (int pointIdx)=0
//网格显示标志
virtual void     setShowGrid (bool needShowGrid)=0
//文字显示标志 
virtual void     setShowText (bool needShowText)=0

        创建对象方法:输入是Mat对象,可以是一个或者两个,都是mat结构的。

static Ptr< Plot2d >    create (InputArray data);
static Ptr< Plot2d >    create (InputArray dataX, InputArray dataY);

 二、OpenCV源码

1、源码路径

opencv_contrib\modules\plot\src\plot.cpp

2、部分源码代码

        render方法的源码参考。

//render the plotResult to a Mat
            void render(OutputArray _plotResult) CV_OVERRIDE
            {
                //create the plot result
                _plotResult.create(plotSizeHeight, plotSizeWidth, CV_8UC3);
                plotResult = _plotResult.getMat();
                plotResult.setTo(plotBackgroundColor);

                int NumVecElements = plotDataX.rows;

                Mat InterpXdata = linearInterpolation(plotMinX, plotMaxX, 0, plotSizeWidth, plotDataX);
                Mat InterpYdata = invertOrientation ?
                                  linearInterpolation(plotMaxY, plotMinY, 0, plotSizeHeight, plotDataY) :
                                  linearInterpolation(plotMinY, plotMaxY, 0, plotSizeHeight, plotDataY);

                //Find the zeros in image coordinates
                Mat InterpXdataFindZero = linearInterpolation(plotMinX_plusZero, plotMaxX_plusZero, 0, plotSizeWidth, plotDataX_plusZero);
                Mat InterpYdataFindZero = invertOrientation ?
                                          linearInterpolation(plotMaxY_plusZero, plotMinY_plusZero, 0, plotSizeHeight, plotDataY_plusZero) :
                                          linearInterpolation(plotMinY_plusZero, plotMaxY_plusZero, 0, plotSizeHeight, plotDataY_plusZero);

                int ImageXzero = (int)InterpXdataFindZero.at<double>(NumVecElements,0);
                int ImageYzero = (int)InterpYdataFindZero.at<double>(NumVecElements,0);

                double CurrentX = plotDataX.at<double>(cursorPos,0);
                double CurrentY = plotDataY.at<double>(cursorPos,0);

                drawAxis(ImageXzero,ImageYzero, CurrentX, CurrentY, plotAxisColor, plotGridColor);

                if(needPlotLine)
                {
                    //Draw the plot by connecting lines between the points
                    Point p1;
                    p1.x = (int)InterpXdata.at<double>(0,0);
                    p1.y = (int)InterpYdata.at<double>(0,0);

                    for (int r=1; r<InterpXdata.rows; r++)
                    {
                        Point p2;
                        p2.x = (int)InterpXdata.at<double>(r,0);
                        p2.y = (int)InterpYdata.at<double>(r,0);

                        line(plotResult, p1, p2, plotLineColor, plotLineWidth, 8, 0);

                        p1 = p2;
                    }
                }
                else
                {
                    for (int r=0; r<InterpXdata.rows; r++)
                    {
                        Point p;
                        p.x = (int)InterpXdata.at<double>(r,0);
                        p.y = (int)InterpYdata.at<double>(r,0);

                        circle(plotResult, p, 1, plotLineColor, plotLineWidth, 8, 0);
                    }
                }
            }

三、简单示例 

1、示例1:循环绘制正弦曲线

        参考代码

// Initialize Data
std::vector<double> sine;
for( int t = 0; t < 360; t++ ){
    sine.push_back( std::sin( t * CV_PI / 180.0 ) );
}

// Create Ploter
cv::Mat data( sine );
cv::Ptr<cv::plot::Plot2d> plot = cv::plot::Plot2d::create(data);

while( true )
{
    // Rotation Data
    double value = *sine.begin();
    sine.erase( sine.begin() );
    sine.push_back( value );

    // Render Plot Image
    cv::Mat image;
    plot->render( image );

    // Show Image
    cv::imshow( "sine", image );
    if( cv::waitKey( 33 ) >= 0 ){
        break;
    }
}

        示例图像,因为是while循环,所以会一致绘制。

2、示例2:官方示例

    std::vector<double> data_x;
    std::vector<double> data_y;

    data_x.push_back(0);
    data_y.push_back(0);
    std::cout << "data_x : " << data_x[0] << std::endl;
    std::cout << "data_y : " << data_y[0] << std::endl;


    for(int i =1; i < 1000; i++) {

      data_x.push_back(i*0.01);
      data_y.push_back(std::sin(data_x.back()));
      cv::Mat plot_result;
      cv::Ptr<cv::plot::Plot2d> plot = cv::plot::Plot2d::create(data_x, data_y);
      plot->render(plot_result);

      imshow("The plot rendered with default visualization options", plot_result);

      plot->setShowText(false);
      plot->setShowGrid(false);
      plot->setPlotBackgroundColor(cv::Scalar(255, 200, 200));
      plot->setPlotLineColor(cv::Scalar(255, 0, 0));
      plot->setPlotLineWidth(2);
      plot->setInvertOrientation(true);
      plot->render(plot_result);

      imshow("The plot rendered with some of custom visualization options",
             plot_result);
      cv::waitKey(3);
    }
    cv::waitKey();
    {
      char tmp;
      std::cin >> tmp;
    }

        从平缓的曲线慢慢变成规律的波形。

猜你喜欢

转载自blog.csdn.net/bashendixie5/article/details/127135262
今日推荐