我是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);
也无济于事。
答案 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 ++相关的知识,你应该自己学习)来成功编译它。
我的结果:
//! 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++