OpenCV 2.3 with VS 2008 - Mouse Events - c++

Obligatory - I'm a newbie. Have a job that involves programming and I'm teaching myself as I go. Needless to say as a teacher I get things wrong frequently and thoroughly.
Where I'm at right now: I've created the class "Graph", it (surprisingly enough) makes graphs. But now I want to make it so that on a mouse click I modify the graph. But I can't seem to get a mouse handler to be a member function of the class.
cv::setMouseCallback(windowName, onMouse, 0); // Set mouse handler to be onMouse
Doesn't work with
cv::setMouseCallback(windowName, Graph::onMouse, 0);
It gives me lack of parameter errors. According to this I can't make it a member function. After following the answer given, it compiles but my this pointer is nulled. Ugh.
OnMouse looks like this:
void onMouse(int event, int x, int y,int, void*)
{
if (event == CV_EVENT_LBUTTONDOWN)
{
cvMoveWindow("Window", 500, 500); //Just to see if stuff happened
}
return;
}
I don't care about moving the window, I want to modify the graph itself - which is stored as a cv::Mat variable in a Graph object. And I can't figure out how to do it.
Any help would be appreciated, and I really hope this wasn't just gibberish.

Yes callback functions in C++ are a joy, aren't they? You actually have to give OpenCV a function (not a class method) as you've already found out. However, you can hack around this awfulness using the following technique:
class MyClass
{
public:
void realOnMouse(int event, int x, int y, int flags)
{
// Do your real processing here, "this" works fine.
}
};
// This is a function, not a class method
void wrappedOnMouse(int event, int x, int y, int flags, void* ptr)
{
MyClass* mcPtr = (MyClass*)ptr;
if(mcPtr != NULL)
mcPtr->realOnMouse(event, x, y, flags);
}
int main(int argv, char** argc)
{
// OpenCV setup stuff...
MyClass processor;
cv::setMouseCallback(windowName, wrappedOnMouse, (void*)&processor);
// Main program logic
return 0;
}
That last parameter on setMouseCallback is quite useful for overcoming some of the problems you usually encounter like this.

You can also use the onMouse method as a static method.
class Graph
{
public:
static void onMouse(int event, int x, int y, void* param)
{
//Your code here
}
//Everything else you may need
}
Now you should be able to call the onMouse method with:
cv::setMouseCallback(windowName, onMouse, (void*) param);
The param can be NULL or whatever you want to pass as parameter to the method, but you'll need to make a type-cast to the desired type.
Hope this was useful.
Bye.

Related

C++ Object Oriented Design frustration.

After working within a group project to build pretty much a copy of IRC, and manning the GUI battle station, I realise I have written code for much more than the GUI (user commands, font commands, chat filter, etc).
This being my first attempt at OOP at all, i am now stuck with a huge GUI class which i would love to split into smaller classes.
However, now I am faced with a situation like the following:
Class A {
public:
int printStuff();
int doThings();
}
A::printStuff() {
return doThings;
}
A::doThings() {
return 2;
}
A situation where the classes still need to interact.
Keep in mind, the class system is a lot more complex than this, and there are interactions between all 5 of my proposed subclasses.
but class A should only be printing things, not doing things; as such, i would love to have it like this:
Class A {
public:
int printStuff();
}
Class B {
public:
int doThings();
}
What are the best/most elegant ways to go about doing so?
Heres the actual chunk from the header, if it helps; I've commented in the functions/variables each method requires- and also outlined my proposed subclasses:
// ncurses (GUI, screens)
void setup(); // initScreen(); initWindows();
void initScreen(); // ncurses.h
void initWindows(); // screen vars, ncruses.h, dummy text
void resize(); // screen vars, ncruses.h, showScreen();
void Routine();
// message factory (GUI, controll, vars)
string mRequested(); // _messageQueue
void mRecieved(string message); // command(), printchat(), _chatlog, _user
bool command(string message, int out_in); // _user, _messageQueue, mRecieved -- quit(not made), removeUser
int checkVulgar(string *message); // _user
string upperCase(string message);
// GUI (windows, vars)
void printAscii(WINDOW *scr, char *gaphics[], int sizey, int sizex, int starty, int startx); // ncurses.h, windows
void printServers(WINDOW *scr, int a); // ncurses.h, windows
void printMessage(string message, int message_lines, int *h_index, int *attempt, int *message_len, int prev_len, int endline); // ncurses.h, windows
void printUsers(WINDOW *scr); // _users, ncurses.h, windows
void printTimeout();
void printChat(); // printMessage(), fontcommands, _chatlog, ncurses.h, windows //
void showScreen(int a, int b); // printAscii,servers,users,chat , ncurses.h, windows
// control (GUI, _users)
void updateUsers(vector<User> users); // _users, printUsers();
void removeUser(string user); // _users, printUsers();
// Boundary (ncurses, GUI, messageFactory, vars)
void userInput();
void userInputB(); // _user, resize(), printchat(), mRecieved(), checkvulgar(), quit(), command(), _messageQueue
int selectServer(); // showScreen()
What are the best/most elegant ways to go about doing so?
Sit down on a sofa for a few days and come up with a robust and elegant design.
Then implement that design.
The mistake you made was not designing before you began coding. Now it's already time to refactor.
Figure out what classes should do what, try and make some CRC cards. They are a great help to figure out what the class diagram should look like.
After reworking the class design and starting from scratch, I've managed to separate and reuse most of my earlier code.
For anyone wondering, the mainApp now talks directly to the MessageFactory; MF contains an object of both GUI and Windows (ncurses in previous image).
This is really how it should have been from the beginning, and poor planning (due to not knowing anything about command line GUI, and the excitement of adding new features) has caused me a great deal of grief.
Plan properly, or suffer.

Linking pointers to pointers between classes (communicating classes)

I've tried to solve my problem for 2 days now and failed miserably. Internet does not help.
What I'm trying to do is to communicate two classes which reside within another class.
This is my first "big" project so I assume my design is terrible for you guys.
Also, my program is split between a lot of files which may be confusing.
Lets hit it! For the sake readability, I've changed every member to public.
This is my MainOGLController class which is the main class that controls everything my program does:
class MainOGLController
{ // I deleted constructor/destructor from this quote
public:
DisplayController* Display;
StellarManager* Manager; // it will need to use something from Display
void RenderScene();
bool CreateNewDisplay(int, char*[]); // argc argv
}
Ok, this is how i create instance of this class in file with main():
#include "MainOGLController.h"
MainOGLController Controller;
int main(int argc, char* argv[])
{
if ( Controller.CreateNewDisplay(argc, argv) ) return 1; // if it fails then exit;
// some opengl code here
return 0;
}
Now you are probably wondering how does the CreateNewDisplay method look like:
bool MainOGLController::CreateNewDisplay(int argc, char* argv[])
{
Display = new DisplayController(argc, argv);
Manager = new StellarManager(&Display); // me trying to make reference to Display
// to be able to use it within Manager
//ogl code
else return 0;
}
OK, so I'm creating Manager there and now we should see how i created the StellarManager class:
class StellarManager
{
std::vector<Stellar*> VectorManager; // objects from this vector will need to use
// ptrDisplay to access Display
DisplayController* ptrDisplay;
StellarManager(DisplayController&);
void addEntity();
};
Now for the constructor:
StellarManager::StellarManager(DisplayController& _p) // me trying to do anything
{
*ptrDisplay = _p;
}
So at this point I should have instance of MainOGLController, and within it, a pointer to DisplayController and StellarController, where StellarController should have its own pointer to the same DisplayController.
Now somewhere withing working piece of code I'm calling the addEntity method:
void StellarManager::addEntity()
{
VectorManager.push_back(new Stellar(&ptrDisplay); // sending ptrDisplay so that the
// Stellar object can use it
}
Stellar class is defined like this:
class Stellar
{
public:
DisplayController* ptrDisplay;
Stellar(DisplayController**);
void Draw(); // finally, heres where i want to use this Display pointer
};
Stellar constructor:
Stellar::Stellar(DisplayController** _p)
{
*ptrDisplay = **_p;
}
OKAY! Thats the final piece. All i want to do now is simply call method Draw which belongs to Stellar class and use Display which is located in MainOGLController.
Manager->VectorManager[0].Draw();
Oh and the Draw looks just like this:
void Stellar::Draw(int _mode)
{
GLMatrixStack* mvm = &(ptrDisplay->modelViewMatrix);
mvm->Scale(2, 0.5, 0.5); // Scale is a method from GLMatrixStack
}
Thats all folks, if theres any better way of doing this, im all ears.
What I did does not work, I'm able to use the *ptrDisplay from Stellar class but nothing happens so I guess I'm not using its reference but a copy.
Sorry, I know this is a lot of code and it may be very confusing. I just dont know what to do now...
It looks like the problem is here:
Stellar::Stellar(DisplayController** _p)
{
*ptrDisplay = **_p;
}
You're dereferencing a pointer (ptrDisplay) that was never initialized. This results in undefined behavior. I think this captures what you wanted to do:
Stellar::Stellar(DisplayController* _p) : ptrDisplay(_p)
{
}
It's not necessary to pass a pointer-to-pointer-to-DisplayController; all your Stellar class needs is a pointer to a DisplayController. Moreover, it sounds like you don't want to dereference _p and copy it, so simply copying the pointer (via ptrDisplay(_p)) will result in ptrDisplay pointing to the same object as _p.

Setting espeak_SetSynthCallback to member function in C++

My application makes heavy use of text-to-speech (through libespeak). It is written in C++/Qt5 with a QML-based frontend.
I have no formal C++ training (I have a Java background though) and as such I'm not entirely sure how to properly implement some of the more esoteric features.
libespeak supports a callback feature, which is called every time speech is synthesized.
The callback function takes three arguments, which I would like to use to visualize the speech. The code below works in the sense that the callback function is called correctly, but not useful since I can't access other member functions or variables.
itemvoice.h
#include "espeak/speak_lib.h"
int callback(short *wav, int numsamples, espeak_EVENT *events);
class ItemVoice : public Item
{
public:
explicit ItemVoice(QQuickItem *parent = 0);
};
itemvoice.cpp
#include "itemvoice.h"
extern int callback(short *wav, int numsamples, espeak_EVENT *events)
{
// do stuff
}
ItemVoice::ItemVoice(QQuickItem *parent):Item(parent)
{
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,500,NULL,0);
espeak_SetSynthCallback(callback);
}
I would like to make the callback function a member of the ItemVoice class. However if I try (and set the callback function with espeak_SetSynthCallback(ItemVoice::callback), the code won't compile anymore because of arguments which cannot be converted.
UPDATE: The suggestion below works. However, I have now run into another problem.
This is what the class looks like now:
itemvoice.h
#include "espeak/speak_lib.h"
int staticCallback(short *wav, int numsamples, espeak_EVENT *events);
class ItemVoice : public Item
{
Q_OBJECT
public:
explicit ItemVoice(QQuickItem *parent = 0);
void startSpeaking();
void stopSpeaking();
signals:
void updateGUI();
}
itemvoice.cpp
#include "itemvoice.h"
ItemVoice::ItemVoice(QQuickItem *parent):Item(parent)
{
espeak_Initialize(AUDIO_OUTPUT_PLAYBACK,500,NULL,0);
espeak_SetSynthCallback(staticCallback);
}
int staticCallback(short *wav, int numsamples, espeak_EVENT *events)
{
espeak_EVENT_TYPE type=events->type;
if(type==2) // start sentence
(static_cast<ItemVoice*>(events[0].user_data))->startSpeaking();
else if(type==6) // stop sentence
(static_cast<ItemVoice*>(events[0].user_data))->stopSpeaking();
}
void ItemVoice::startSpeaking()
{
//do stuff
updateGUI();
}
void ItemVoice::stopSpeaking()
{
// do stuff
updateGUI();
}
This works correctly. startSpeaking() is called when synthesis begins, and stopSpeaking() when it stops. The problem is that I need to send a Qt signal to update the GUI (updateGUI), and about a second after it's sent, my application crashes with a segmentation fault, even if the signal is not connected anywhere. It works perfectly otherwise.
Any idea?
Thanks for reading!
There is no direct way to do what you want. In your case you are lucky because there is void* user_data field in espeak_EVENT. You can set it to this when you call espeak_Synth():
void ItemVoice::synthSpeech() {
espeak_Synth(...., this);
}
So in the callback (which is still a global function, or a static function in ItemVoice) you can do roughly this:
int staticCallback(short *wav, int numsamples, espeak_EVENT *events) {
if (numsamples > 0)
return (static_cast<ItemVoice*>(events[0].user_data))->nonStaticCallback(wav, numsamples, events);
}

Creating a signal from within a class to call an external function?

I was wandering if you could offer any guidance. I am currently writing a sprite class for a simple game engine. Previous engines I have used allow functionality to "Connect" an external function to a signal, emitted when an animation finishes.
E.g.
create the sprite object
create the external function
connect the external function to the sprites completion signal
When the signal is emitted the external function is called.
This function does not necessarily share any data with the sprite, its purely game logic timing functionality. E.g player scores a goal, "Congrats" sprite animation is triggered, then the on completion function will add an amount to the players score.
I have looked into it and it looks like I need to use a callback function/ function ptr but I don't have any experience using them as of yet.
Any help would be greatly appreciated.
In c++ a function pointer can be used like this:
#include <iostream>
//defining a type that is a 'function that returns void and takes an int'
typedef void FnPtr( int i );
//this is a 'function that returns void and takes an int'
void AFunction( int i )
{
std::cout << "AFunction Called!";
}
//a function that accepts a pointer to a 'function that returns void and takes an int'
void AFunctionThatTakesAFnPtrAsAnArg( FnPtr* fn )
{
//store the pointer to use "later".
FnPtr* local = fn;
.
.
.
//use it.
local( 3 );
}
int main( int, char** )
{
AFunctionThatTakesAFnPtrAsAnArg( AFunction );
}
Note the function can be global, or a static class member. If you want to call into a function in an object instance then see this - particularly my answer! :-)
What is a C++ delegate?
EDIT: To better fit questions asked in comments:
#include <iostream>
typedef void FnPtr();
void AFunction()
{
std::cout << "Animation done";
}
class Sprite
{
public:
void SetFnPointer( FnPtr* fn )
{
m_Fn = fn;
}
void DoAnimation()
{
m_Fn();
}
private:
FnPtr* m_Fn;
};
int main( int, char** )
{
Sprite s;
s.SetFnPointer( AFunction );
s.DoAnimation();
}
Take a look at http://www.boost.org/doc/libs/1_49_0/doc/html/signals.html
or http://libsigc.sourceforge.net/
The boost::signals library is really easy to use:
boost::signal<void(float)> update_sig;
Then somewhere in your game logic (some_client_class):
update_sig.connect( boost::bind(&some_client_class::callback, this, _1) );
And finally in your core update (main run loop of your game for example):
float delta = cur_time - last_update_time;
update_sig(delta); // executes all connected slots
Good luck :)

OpenCV trackbar callback in C++ class

I have a question about how to define the callback for trackbars in OpenCV when working with classes in C++.
When I define my trackbar let's say in the constructor method of my .cpp class how can I define the callback?
I have been trying to work with function pointers but it doesn't work out. I guess I must be doing something very wrong :-)
This is my header file:
class SliderwithImage {
public:
SliderwithImage(void);
~SliderwithImage(void);
void sliderCallBack(int pos);
};
This is the implementation file:
#include "SliderwithImage.h"
void SliderwithImage::sliderCallBack(int pos) {
}
SliderwithImage::SliderwithImage(void) {
const char* windowName = "window";
int lowvalue =1;
namedWindow(windowName, CV_GUI_EXPANDED);
createTrackbar("mytrackbar", windowName, &lowvalue, 255, sliderCallBack);
}
SliderwithImage::~SliderwithImage(void) {
}
Obviously the createTrackbar method does not recognize sliderCallBack... I guess it's a problem of scope. But I am not sure how to solve this?
Any help would be appreciated.
Thank you very much.
The callback function must be static or global, but you can pass it a reference to an object you want to operate on (see this post on the OpenCV Users mailing list).
The createTrackbar method has a userdata parameter which is passed to the calling function. In C there is an undocumented cvCreateTrackbar2 method, defined in highgui_c.h, which has the same functionality:
CVAPI(int) cvCreateTrackbar2( const char* trackbar_name, const char* window_name,
int* value, int count, CvTrackbarCallback2 on_change,
void* userdata CV_DEFAULT(0));
These methods let you create a class with a static callback function that takes a pointer to an object of that class. You can create the trackbar like so:
cv:createTrackbar("Label", "Window" &variable, MAX_VAL, &MyClass::func, this);
The callback would look something like this:
void MyClass:func(int newValue, void * object) {
MyClass* myClass = (MyClass*) object;
// ...do stuff.
}
Note that you don't need to explicitly update the variable yourself as long as you provided a pointer to it when creating the trackbar (as above), but if you need to process it first I suggest you set it explicitly in the callback function.
You have to implement the callback function either as a global function or a static member function. To make it more OOP look, you might prefer to implement it as a static member function:)
I am using a different solution to obtain the slider value in a class variable (in my case to obtain chosen rotation angle of a live video stream). The int* value in the createTrackbar function is a public class variable which is then used within a loop (while the video is acquired, but this might messily work repeatedly redrawing a single image).
Not the best solution but it works for me.
cv::createTrackbar("Rotation Angle(deg)", "Preview", &rotationAngle,
alpha_slider_max, NULL);
for(;;)
{
int rotAngle = this -> rotationAngle;
cv::Mat frame;
cv::Mat rot_frame;
this -> capture >> frame;
rot_frame = rotateVideo (frame, rotAngle);
imshow("Preview", rot_frame);
if(cv::waitKey(30) >= 0) break;
}