头文件中使用非静态成员函数无效

时间:2017-12-22 14:03:22

标签: c++ opencv

我是C / C ++的新手,有以下问题。作为exectuable的一部分,我想使用OpenCV在图片上绘制一些矩形。为此,我定义了一个单独的头文件,以使.cpp可执行文件尽可能短。它看起来像这样:

typedef struct Rectangle {
    cv::Point startPoint;
    cv::Point endPoint;

};

class drawSpaces {

private:
    Mat img;
    int ix = 1;
    int iy = 1;
    std::list<Rectangle> rectList;

public:
//mouse callback function
    void drawRect(int event, int x, int y, int, void *param) {
        if (event == CV_EVENT_LBUTTONDOWN) {
           //Save first point of rect
            ix = x;
            iy = y;
        } else if (event == CV_EVENT_LBUTTONUP) {
            //Save 2nd point of rect
            cv::rectangle(img, Point(ix, iy), Point(x, y), cv::Scalar(0, 255, 0));
            Rectangle rect;
            rect.startPoint = Point(ix, iy);
            rect.endPoint = Point(x, y);
            rectList.push_back(rect);
            }
        }
    }


    int draw(Mat image) {
        img = image;
        if (img.empty()) {
            cout << "\nerror reading image" << endl;
            return -1;
        }
        namedWindow("Image", 1);
        imshow("Image", img);
        setMouseCallback("Image", drawRect);
        while (waitKey(20) != 27)  // wait until ESC is pressed
        {
            imshow("Image", img);
        }
        //save image with rectangles
        imwrite( "../pics/new_Image.jpg", img );
        return 0;
    }

};

我现在想要在我的main中创建类drawSpaces和Mat图像的对象,并在其上运行绘图以获取新图像。但是,在构建时,我收到错误消息 error: invalid use of non-static member function setMouseCallback("Image", drawRect); 编译器指向drawRect函数。

我已经在这个问题上看了其他答案,大多数人似乎建议将drawRect更改为静态。但是我不希望我的drawRect函数具有静态函数的功能,即能够在没有实际的drawSpaces对象的情况下调用它。

对编码风格的任何帮助表示赞赏!

编辑:使用

setMouseCallback("Image", drawSpaces::drawRect);

也无济于事。

2 个答案:

答案 0 :(得分:2)

环境:g ++ 5.4(c ++ 11)+ OpenCV 3.3

setMouseCallback("Image", callback);的回调函数应始终为静态。所以你应该把功能改为:

static void drawRect(int event, int x, int y, int, void *param)

然后你也应该修改你的类定义(一些与C ++相关的知识,你应该自己学习)来成功编译它。

我的结果:

enter image description here

//! 2017.12.22 23:13:58 CST
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
using namespace cv;

struct Rectangle {
    cv::Point startPoint;
    cv::Point endPoint;

};

class drawSpaces {
private:
    static Mat img;
    static int ix;
    static int iy;
    static std::list<Rectangle> rectList;

public:

    static void drawRect(int event, int x, int y, int, void *param) {
        if (event == CV_EVENT_LBUTTONDOWN) {
           //Save first point of rect
            ix = x;
            iy = y;
        } else if (event == CV_EVENT_LBUTTONUP) {
            //Save 2nd point of rect
            cv::rectangle(img, Point(ix, iy), Point(x, y), cv::Scalar(0, 255, 0), 1, LINE_AA);
            Rectangle rect;
            rect.startPoint = Point(ix, iy);
            rect.endPoint = Point(x, y);
            rectList.push_back(rect);
            }
        }

    int draw(Mat image) {
        img = image;
        if (img.empty()) {
            cout << "\nerror reading image" << endl;
            return -1;
        }
        namedWindow("Image", 1);
        imshow("Image", img);
        setMouseCallback("Image", drawRect);
        while (waitKey(20) != 27) {
            imshow("Image", img);
        }
        //save image with rectangles
        imwrite( "new_Image.jpg", img );
        return 0;
    }

};

int drawSpaces::ix =0;
int drawSpaces::iy =0;
Mat drawSpaces::img = Mat() ;
std::list<Rectangle> drawSpaces::rectList;



int main(){
    Mat img = imread("test.png");
    drawSpaces obj;
    obj.draw(img);

}

答案 1 :(得分:-1)

您正尝试将指向成员函数的指针作为参数传递。非静态成员函数需要调用实例或其他签名。

这已经在这里讨论过了: Passing a member function as an argument in C++