如何在课堂上使用cv::setMouseCallback
How to use cv::setMouseCallback in class?
我想在设置类中使用cv::setMouseCallback来选择图片的一个区域。这是我的代码:
void Settings::on_buttonXML_clicked(){
cv::VideoCapture webcam;
webcam.open(INDEX);
webcam.read(src);
color = Scalar(0,0,255);
coor_num = 0;
xmlPath="C:/myregion.xml";
cv::namedWindow("imageWindow", CV_WINDOW_AUTOSIZE );
cv::imshow("imageWindow", src);
cv::setMouseCallback( "imageWindow", onMouse, 0 );
cv::waitKey(0);
}
void Settings::onMouse(int event, int x, int y, int, void* ) {
if (event == CV_EVENT_LBUTTONUP) {
Point2f p(x, y);
coor.push_back(p);
line(src,p,p,color);
if(coor.size()>1)
line(src, p, coor[coor.size()-2], color);
imshow("imageWindow", src);
}
else if (event == CV_EVENT_RBUTTONUP && coor.size()>2){
line(src, coor[0], coor[coor.size()-1], color);
getPointsInContour(coor);
imshow("imageWindow", src);
waitKey(2000);
exit(0);
}
}
void Settings::savePointsAsXML(vector<Point2f> & contour){
TiXmlDocument doc;
TiXmlDeclaration decl("1.0", "", "");
doc.InsertEndChild(decl);
for(int i = 0; i < contour.size(); i++)
{
TiXmlElement point("point");
point.SetAttribute("x",contour[i].x);
point.SetAttribute("y",contour[i].y);
doc.InsertEndChild(point);
}
if(doc.SaveFile(xmlPath.c_str()))
cout << "file saved succesfully.n";
else
cout << "file not saved, something went wrong!n";
}
void Settings::getPointsInContour(vector<Point2f> & contour){
vector<Point2f> insideContour;
for(int j = 0; j < src.rows; j++){
for(int i = 0; i < src.cols; i++){
Point2f p(i,j);
if(cv::pointPolygonTest(contour,p,false) >= 0) // yes inside
insideContour.push_back(p);
}
}
cout << "# points inside contour: " << insideContour.size() << endl;
savePointsAsXML(insideContour);
}
我得到了大量未定义的参考设置:coor,设置:src,设置:color。我很难理解什么是静态的才能工作。这是我的标题:
class Settings
{
private:
static void onMouse(int event, int x, int y, int, void* );
static void savePointsAsXML(std::vector<cv::Point2f> & contour);
static void getPointsInContour(std::vector<cv::Point2f> & contour);
static cv::Scalar color;
static std::vector<cv::Point2f> coor;
static int coor_num;
static std::string xmlPath;
static cv::Mat src;
我的代码中缺少什么?
由于OpenCV有一个类似C的接口,它不接受成员函数作为回调,但您可以使用标准方法来克服这一点,并将类实例作为userdata
参数传递,然后将其强制转换回实例并调用成员方法。以下是一个片段:
void Settings::on_buttonXML_clicked(){
cv::VideoCapture webcam;
webcam.open(INDEX);
webcam.read(src);
color = Scalar(0,0,255);
coor_num = 0;
xmlPath="C:/myregion.xml";
cv::namedWindow("imageWindow", CV_WINDOW_AUTOSIZE );
cv::imshow("imageWindow", src);
cv::setMouseCallback( "imageWindow", onMouse, this ); // Pass the class instance pointer here
cv::waitKey(0);
}
// In you header make a static and a member version of onMouse
void onMouse(int event, int x, int y);
static void onMouse(int event, int x, int y, int, void* userdata);
// Implement it to call the member function
void Settings::onMouse(int event, int x, int y, int, void* userdata)
{
// Check for null pointer in userdata and handle the error
...
Settings* settings = reinterpret_cast<Settings*>(userdata);
settings->onMouse(event, x, y);
}
希望这能解释这个想法,我是在线写的,所以我很抱歉有任何拼写错误。
您还可以使用指向对象的全局指针,并从非成员回调函数调用成员函数。
Class SomeClass
{
...
public:
void callback(int event, int x, int y);
...
};
SomeClass* g_ptr;
void onMouse(int event, int x, int y, void*)
{
g_ptr->callback(event, x, y);
}
void func(void)
{
SomeClass obj;
g_ptr = &obj; // Make the global variable point to your object
cv::namedWindow("winname");
cv::setMouseCallback("winname", onMouse, 0);
...
}
它可能对某些人有用。我的版本没有使用全局指针,但有朋友函数:
class App
{
public:
App();
~App();
void setWin(const std::string& _winname);
...
private:
void on_mouse_internal(int ev, int x, int y);
std::string winname;
friend void on_mouse(int ev, int x, int y, int, void* obj);
...
};
void on_mouse(int ev, int x, int y, int, void* obj)
{
App* app = static_cast<App*>(obj);
if (app)
app->on_mouse_internal(ev, x, y);
}
App::App()
{
...
}
App::~App()
{
...
}
void App::setWin(const std::string& _winname)
{
cv::namedWindow(_winname);
this->winname = _winname;
cv::setMouseCallback(winname, on_mouse, this);
}
void App::on_mouse_internal(int ev, int x, int y)
{
std::cout << "X:" << x << ";Y:" << y << std::endl;
// here you can specify class members
}
...
相关文章:
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 概念中的cv限定符需要表达式参数列表
- 将CHW格式的浮点向量转换为cv::Mat
- 错误的cv::face FacemarkLBF实例化
- 如何检查给定的参数是否为 cv::noArray()?
- 开放 CV 中的动态内存分配,用于视频处理
- 如何在 opencv 中使用 cv::VideoCapture::waitAny()
- 错误:未定义对cv::cudacodec::createVideoReader的引用
- OpenCV 3.4.1 error readNetFromTensorflow 无法在 cv::d nn::ReadProtoFromBinaryFile 中打开 .pb
- C++:从GPU内存(cudaMemcpy2D)获取BGR图像(cv::Mat)
- 选择基于另一个垫子的非零像素的cv::Mat的一部分?
- 将 cv::mat 转换为 QImage
- Inference pytorch C++ with alexnet and cv::imread image
- OpenCV 3.4.3 中对 'cv::String::d eallocate()' 错误的未定义引用
- cv::Normalise() 中的 L2_NORM 和 NORM_MINMAX 实现有什么区别?
- 将 cv::Mat 转换为 std::vector 的通用函数
- OpenCV undefined reference to 'cv::imread(cv::String const&, int)'
- 如何在课堂上使用cv::setMouseCallback
- 如何使 cv::setMouseCallback 函数工作
- 如何使用cv::setMouseCallback