我是 C/C++ 的新手,遇到以下问题。作为可执行文件的一部分,我想使用 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 图像,然后在其上运行绘制以获得新图像。但是,在构建时,我收到错误消息
错误:无效使用非静态成员函数 setMouseCallback("Image", drawRect);
编译器指向 drawRect 函数。
我看过这个问题的其他答案,大多数人似乎建议将 drawRect 更改为静态。但我不希望我的 drawRect 函数具有静态函数的功能,即能够在不存在实际 drawSpaces 对象的情况下被调用。
感谢任何帮助,包括编码风格方面的帮助!
编辑:使用
setMouseCallback("Image", drawSpaces::drawRect);
也没有帮助。
最佳答案
环境:g++5.4(c++11) + OpenCV 3.3
setMouseCallback("Image", callback);
的回调函数应该始终是静态的。因此,您应该将函数更改为:
static void drawRect(int event, int x, int y, int, void *param)
然后你也应该修改你的类定义(一些C++相关的知识,你应该自己学习)才能编译成功。
我的结果:
//! 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);
}
关于c++ - 头文件中非静态成员函数的使用无效,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47942815/