c++ - How to make cv::setMouseCallback function work -


i've seen few questions same. still unable make code work after reading answers. sorry in advance if repeating posts.

i managed write code :

        #include <opencv2/core/core.hpp>         #include <opencv2/highgui/highgui.hpp>         #include <opencv2/imgproc/imgproc.hpp>          #include <iostream>         #include <string>          bool leftbuttondown = false, leftbuttonup = false;         cv::mat img;         cv::point cor1, cor2;         cv::rect rect;      void mousecall(int event, int x, int y, int, void*) {         if (event == cv::event_lbuttondown)                                                                     //finding first corner         {             leftbuttondown = true; cor1.x = x; cor1.y = y; std::cout << "corner 1: " << cor1 << std::endl;         }         if (event == cv::event_lbuttonup) {             if (abs(x - cor1.x)>20 && abs(y - cor1.y)>5)                                                        //finding second corner , checking whether region small              {                 leftbuttonup = true; cor2.x = x; cor2.y = y; std::cout << "corner 2: " << cor2 << std::endl;             }             else { std::cout << "select more 5 pixels" << std::endl; }         }          if (leftbuttondown == true && leftbuttonup == false)                                                    //when left button clicked , let off          {                                                                                                       //draw rectangle continuously             cv::point pt; pt.x = x; pt.y = y;             cv::mat temp_img = img.clone();             rectangle(temp_img, cor1, pt, cv::scalar(0, 0, 255));                                                         cv::imshow("original", temp_img);         }         else if (event == cv::event_mousemove)                                                                  //tracking mouse movement         {             std::cout << "mouse moving on window - position (" << x << ", " << y << ")" << std::endl;          }         if (leftbuttondown == true && leftbuttonup == true)                                                     //when selection done          {             rect.width = abs(cor1.x - cor2.x);             rect.height = abs(cor1.y - cor2.y);             rect.x = cv::min(cor1.x, cor2.x);             rect.y = cv::min(cor1.y, cor2.y);             cv::mat cuttempimg(img, rect);                                                                      //selecting roi(region of interest) original img              cv::namedwindow("cut temporary image");             cv::imshow("cut temporary image", cuttempimg);                                                      //showing cropped image              leftbuttondown = false;             leftbuttonup = false;         }     } int main(){     img = cv::imread("image.jpg");     cv::namedwindow("original");     cv::imshow("original", img);     cv::setmousecallback("original", mousecall); //setting mouse callback selecting region mouse       while (char(cv::waitkey(1) != 'q')) //waiting 'q' key finish execution      {     }     return 0; } 

and working fine. want make same code, using class.(oop)

but cv::setmousecallback function not letting me that. can 1 me fix this?

my second code :

    #include <opencv2/core/core.hpp>     #include <opencv2/highgui/highgui.hpp>     #include <opencv2/imgproc/imgproc.hpp>      #include <iostream>     #include <string>  class resizeimage {      cv::mat img;     cv::point cor1, cor2;     cv::rect rect;     std::string name;  public:      void setimg(cv::mat img) { this->img = img; };     cv::mat getimg() { return img; };     void setrect();     int getcoordinates1x() { return cor1.x; };     int getcoordinates1y() { return cor1.y; };     int getcoordinates2x() { return cor2.x; };     int getcoordinates2y() { return cor2.y; };     void setcoordinates1(int x, int y) { this->cor1.x = x; this->cor1.y = y; };     void setcoordinates2(int x, int y) { this->cor2.x = x; this->cor2.y = y; };      void mousecall(int event, int x, int y, int flags, void* param);      void showimgoriginal();     void setimgname(std::string name) { this->name = name; };     std::string getimgname() { return name; };  };  void resizeimage :: showimgoriginal()  {     cv::namedwindow(name, cv_window_autosize);     cv::imshow(name, img); };  void resizeimage::setrect() {     rect.width = abs(cor1.x - cor2.x);     rect.height = abs(cor1.y - cor2.y);     rect.x = cv::min(cor1.x, cor2.x);     rect.y = cv::min(cor1.y, cor2.y); }  void resizeimage::mousecall(int event, int x, int y, int flags, void* param) {       if (event == cv::event_lbuttondown)                                                                 //finding first corner     {         leftbuttondown = true; setcoordinates1(x,y); std::cout << "corner 1: " << getcoordinates1x()<<" "<<getcoordinates1y() << std::endl;     }      if (event == cv::event_lbuttonup) {         if (abs(x - cor1.x)>20 && abs(y - cor1.y)>5)                                                //finding second corner , checking whether region small          {             leftbuttonup = true; setcoordinates2(x, y); std::cout << "corner 2: " << getcoordinates2x() << " " << getcoordinates2y() << std::endl;         }         else { std::cout << "select more 5 pixels" << std::endl; }     }        if (leftbuttondown == true && leftbuttonup == false)                                            //when left button down      {         cv::point pt; pt.x = x; pt.y = y;          cv::mat temp_img = img.clone();          rectangle(temp_img, cor1, pt, cv::scalar(0, 0, 255));                                           //drawing rectangle continuously          cv::imshow("original", temp_img);     }     else if (event == cv::event_mousemove)                                                              //tracking mouse movement     {         std::cout << "mouse moving on window - position (" << x << ", " << y << ")" << std::endl;      }     if (leftbuttondown == true && leftbuttonup == true)                                             //when selection done      {         setrect();         cv::mat cuttempimg(img, rect);                                                                          //selecting roi(region of interest) original img          cv::namedwindow("cut temporary image");         cv::imshow("cut temporary image", cuttempimg);                                                              //showing cropped image          leftbuttondown = false;         leftbuttonup = false;     } }  int main(){     cv::mat img = cv::imread("image.jpg");      resizeimage img_;      img_.setimg(img);     img_.setimgname("original");     img_.showimgoriginal();      cv::setmousecallback(img_.getimgname(),img_.mousecall());      while (char(cv::waitkey(1) != 'q')) //waiting 'q' key finish execution      {     }     return 0; } 

code after changes :

//program loading image, , showing user.  //user can use mouse make rectangle , cut loaded image. //command line tracking mouse movements , coordinates of rectangle. //user can end program using 'q'.  #include <opencv2/core/core.hpp> #include <opencv2/highgui/highgui.hpp> #include <opencv2/imgproc/imgproc.hpp>  #include <iostream> #include <string>  bool leftbuttondown = false, leftbuttonup = false;          //flags mouse clicks   class resizeimage {      cv::mat img;            //image process     cv::point cor1, cor2;   //coordinates of selected rectangle     cv::rect rect;          //rectangle     std::string name;       //windows name  public:     //////////////////////////////////////////////////////////////////////////////     resizeimage() { std::cout << "starting..."<<std::endl; };                                   //constructor/destructor     ~resizeimage() { std::cout << "ending..." << std::endl; };     //////////////////////////////////////////////////////////////////////////////     void setimg(cv::mat img) { this->img = img; };     void setimgname(std::string name) { this->name = name; };                                   //set functions     void setrect();                                                  void setcoordinates1(int x, int y) { this->cor1.x = x; this->cor1.y = y; };     void setcoordinates2(int x, int y) { this->cor2.x = x; this->cor2.y = y; };     //////////////////////////////////////////////////////////////////////////////     int getcoordinates1x() { return cor1.x; };                                                  //getfunctions     int getcoordinates1y() { return cor1.y; };     int getcoordinates2x() { return cor2.x; };     int getcoordinates2y() { return cor2.y; };     cv::mat getimg() { return img; };     std::string getimgname() { return name; };     //////////////////////////////////////////////////////////////////////////////     static void mousecall(int event, int x, int y, int flags, void* param);                     //static function     //////////////////////////////////////////////////////////////////////////////     void showimgoriginal();                                                                     //show function (priting image)     //////////////////////////////////////////////////////////////////////////////  };  void resizeimage :: showimgoriginal()  {            //showing image     cv::namedwindow(name, cv_window_autosize);     cv::imshow(name, img); };  void resizeimage::setrect() {                       //calculating selected rectangle     rect.width = abs(cor1.x - cor2.x);     rect.height = abs(cor1.y - cor2.y);     rect.x = cv::min(cor1.x, cor2.x);     rect.y = cv::min(cor1.y, cor2.y); }  void resizeimage::mousecall(int event, int x, int y, int flags, void* param) {       if (event == cv::event_lbuttondown)                                                                                         //finding first corner     {         leftbuttondown = true; ((resizeimage*)param)->cor1.x = x; ((resizeimage*)param)->cor1.y = y;                            //saving coordinates         std::cout << "corner 1: " << ((resizeimage*)param)->cor1.x << " " << ((resizeimage*)param)->cor1.y << std::endl;        //printing coordinates     }      if (event == cv::event_lbuttonup) {         if (abs(x - ((resizeimage*)param)->cor1.x)>20 && abs(y - ((resizeimage*)param)->cor1.y)>10)                             //finding second corner , checking whether region small          {             leftbuttonup = true; ((resizeimage*)param)->cor2.x = x; ((resizeimage*)param)->cor2.y = y;                          //saving coordinates             std::cout << "corner 2: " << ((resizeimage*)param)->cor2.x << " " << ((resizeimage*)param)->cor2.y << std::endl;    //printing coordinates         }         else { std::cout << "select more 10 pixels" << std::endl; }                                                        //warning if region small     }        if (leftbuttondown == true && leftbuttonup == false)                                                                        //when left button down      {         cv::point pt; pt.x = x; pt.y = y;          cv::mat temp_img = ((resizeimage*)param)->img.clone();         rectangle(temp_img, ((resizeimage*)param)->cor1, pt, cv::scalar(0, 0, 255));                                            //drawing rectangle continuously      }     else if (event == cv::event_mousemove)                                                                                      //tracking mouse movement     {         std::cout << "mouse moving on window - position (" << x << ", " << y << ")" << std::endl;      }     if (leftbuttondown == true && leftbuttonup == true)                                                                         //when selection done      {         ((resizeimage*)param)->setrect();         cv::mat cuttempimg(((resizeimage*)param)->img, ((resizeimage*)param)->rect);                                            //selecting roi(region of interest) original img          cv::namedwindow("cut temporary image");         cv::imshow("cut temporary image", cuttempimg);                                                                          //showing cropped image          leftbuttondown = false;         leftbuttonup = false;     } }  int main() {      cv::mat img = cv::imread("image.jpg");      resizeimage img_;      img_.setimg(img);     img_.setimgname("original");     img_.showimgoriginal();      cv::setmousecallback(img_.getimgname(),resizeimage::mousecall,&img_);      while (char(cv::waitkey(1) != 'q')) //waiting 'q' key finish execution      {     }     return 0; } 

if want use class method callback, should indeed declare method static. however, need pass object callback able access non static members of class such cor1 or cor2.

here minimal example of how can achieve this:

class call { public:     call(int i) : a(i){};     int a;      static void mouse(int event, int x, int y, int flags, void* param) {         std::cout << ((call*)param)->a << std::endl;     } };   cv::namedwindow("call");  call call(10); cv::setmousecallback("call", call::mouse, &call);  cv::imshow("call", cv::mat(100, 100, cv_8u, cv::scalar(0))); cv::waitkey(); 

i create call object , use mouse method window callback while still passing object call back.


Comments

Popular posts from this blog

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -