I am new in C++ and working on a project with QT. I created a header file called imageconvert.h which is as follow:
class ImageConvert
{
private:
IplImage *imgHeader;
uchar* newdata;
public:
ImageConvert();
~ImageConvert();
IplImage* QImage2IplImage(QImage *qimg);
QImage* IplImage2QImage(IplImage *iplImg);
};
also I defined those public methods in imageconvert.cpp file.
Now, I want to call QImage2IplImage and IplImage2QImage from other cpp file. So i include imageconvert.h in that CPP file and called those two functions.
it gives the the following errors:
error: 'QImage2IplImage' was not declared in this scope
error: 'IplImage2QImage' was not declared in this scope
Any help would be greatly appreciated.
The functions you've defined are member functions of the ImageConvert class. You need an instance of that class to be able to call them.
Something like:
ImageConvert ic;
ic.QImage2IplImage(your_QImage_object);
If you don't need state to do the conversion, you should make those helper functions static. Then you can call them with:
ImageConvert::QImage2IplImage(your_QImage_object);
without first creating an instance of ImageConvert. But please note that you will not be able to use imgHeader or newData in those static functions - they are member variables, only usable within an instance of that class.
You could also remove these functions from your class and put them in a namespace.
Your question...
How exactly do you call those functions? Given your ImageConverter class, this is how you should be doing it:
// First create a new converter
ImageConverter conv;
IplImage* ipl = conv.QImage2IplImage(qimg);
qimg = conv.IplImage2QImage(ipl);
... And some advice on using classes
Do you by any chance come from a Java or C# background? If so, you should know that in C++ you can also have free functions (that don't belong to any class). You should only use classes when you need to abstract a certain (real world) concept, and not simply as a way to group functions:
// image_converter.h
IplImage* QImage2IplImage(const QImage* qimg);
QImage* IplImage2QImage(const IplImage* iplImg);
// someother.cpp
IplImage* ipl = QImage2IplImage(qimg);
qimg = IplImage2QImage(ipl);
Notice I added const to the function parameters — it's a good thing to be const correct. Additionaly, you can group your functions in a namespace:
// image_converter.h
namespace converter
{
IplImage* QImage2IplImage(const QImage* qimg);
QImage* IplImage2QImage(const IplImage* iplImg);
}
// someother.cpp
IplImage* ipl = converter::QImage2IplImage(qimg);
qimg = converter::IplImage2QImage(ipl);
Related
I am on a micro controller (which means I can only have static memory allocation) and I am trying to work with inheritance.....
Suppose I have a abstract class Image and an abstract class Font. An instance of Font can return an Image based off of the char given in a function like so:
Font* mf;
Image* image = mf->GetImage("a");
Now the real issue is I have no idea what to do for the GetImage Function.
The problem is this: in c++ for you to have a member of an abstract class you have to use it as a pointer. So my dilemma is that I have a Font which wants to create a new Image and then return it.
If it returns a pointer to its newly created Image you are returning a reference to a temporary object:
Image* FontImpl::GetImage(char c){
return &ImageImpl(c); //This object is destroyed once this function exits
}
And then if I return I try to return an actual type like this:
Image FontImpl::GetImage(char c){
return ImageImpl(c); //Cannot cast from ImageImpl to Image
}
So is there an idiom or something for this kind of static memory problem?
Using dynamic allocation would be easiest but if that's not possible, you have to store the instance somewhere outside the function, e.g.:
static ImageImpl image;
Image& FontImpl::GetImage(char c) {
image = ImageImpl(c);
return image;
}
I am using the C++ implementation of OpenCV 2.4.6.1 for Ubuntu 12.10 on a x86_64 architecture. I am working on wrapping this code of the Agast Corner Detector inside a class inheriting from cv::FeatureDetector.
Inspecting the feature2d module header code and observing other implementations, I found I should mandatory implement the detectImpl method:
virtual void detectImpl( const Mat& image, std::vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const = 0;
Usually it is also implementented a method named operator having the following signature:
CV_WRAP_AS(detect) void operator()(const Mat& image, CV_OUT std::vector<KeyPoint>& keypoints) const;
Looking at other implementations I cannot say exactly what each of this methods should do. The second one operator I guess is somehow related to the detect method that is called for detecting keypoints:
cv::Ptr<cv::FeatureDetector> detector = cv::FeatureDetector::create("...");
detector->detect(img, keypoints);
According to your experience what's the difference between this two methods and what should each of them implement?
Related to the detector's instantiation using the factory method cv::FeatureDetector::create I have some clues related to the attribute info of type AlgorithmInfo* usually put as a public attribute of the detector class implementation, and using the CV_INIT_ALGORITHM in the features2d_init source file.
What should I implement in order to be able to instantiate my custom FeatureDetector using the factory method?
Finally after a few days of work I succeeded on my commitment and learned a few lessons about implementing cv::FeatureDetector interface:
Include the wrapping class into the cv namespace.
The only method mandatory to implement is detectImpl using the signature of the method on the OpenCV version you are using.
Implementing the operator method is optional, in other implementations where it is used (e.g. MserFeatureDetector and StarDetector) this method is called from detectImpl through the class instance:
void ...::detectImpl( const Mat& image, std::vector<KeyPoint>& keypoints, const Mat& mask ) const {
...
(*this)(grayImage, keypoints);
...
}
void ...::operator()(const Mat& img, std::vector<KeyPoint>& keypoints) const{
...
}
Be aware that detectImpl is a const method and hence it cannot modify instance parameters so It might turn useful defining the concrete behavior of the detector on a side function as done in other detector implementations (e.g. FastFeatureDetector or StarDetector)
To enable the wrapper to be instantiated using the factory method cv::FeatureDetector::create you should add to your class declaration the public method AlgorithmInfo* info() const; and initialize the class as an algorithm inside OpenCV using the CV_INIT_ALGORITHM as follows:
namespace cv{
CV_INIT_ALGORITHM(AgastFeatureDetector, "Feature2D.AGAST", obj.info()->addParam(obj, "threshold", obj.threshold); obj.info()->addParam(obj, "nonmaxsuppression", obj.nonmaxsuppression); obj.info()->addParam(obj, "type", obj.type));
}
If your class doesn't needs any parameter you can simply substitute all the params part by obj.info()
Remind also to do this outside the source files where you are declaring (.h) or defining (.cpp) your wrapper and include the opencv2/core/internal.hpp library.
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;
}
I am a new settle in Obj-C.
I want to wrap a OpenCV class in Obj-C.
I have a C++ class now, it is like:
class cxx {
private:
IplImage* image;
public:
cxx ();
void modify ();
};
Now I am rewriting in Obj-C, I get confused in the memory type of the pointers.
I put it in a class:
class obj_c:NSObjec {
IplImage* image;
}
- (id) init;
- (void) modify;
But I don't how to deal with the right property of the pointer IplImage*.
If I don't set any property, I can't even access the pointer in the function.
#interface objc_c : NSObject {
IplImage * image;
}
- (id)init;
- (void)modify;
#end
That's how you make a class in objective-c. And in the body of the functions, init and modify, yes, you will be able to access the pointer. You don't have to declare properties unless you want to access an ivar from outside of the class (typically).
Ok I have two classes: Image and Scene. Now in the Image header file, I defined three private variables: xcoord, ycoord, and index (as well as their respective public getter methods).
I have another class named Scene. Scene is not a subclass of Image. Scene has two member variables: int maximum and Image **images. Now in Scene, I have some methods that attempt to access the member variables of the Image class. For example:
int beginX =this->images[i].getXcoord;
int beginY =this->images[i].getYcoord;
However, I get the following errors:
error: request for member ‘getXcoord’ in ‘*(((Image**)((const Scene*)this)->Scene::images) + ((Image**)(((long unsigned int)i) * 8ul)))’, which is of non-class type ‘Image*’
scene.cpp:135: error: request for member ‘getYcoord’ in ‘*(((Image**)((const Scene*)this)->Scene::images) + ((Image**)(((long unsigned int)i) * 8ul)))’, which is of non-class type ‘Image*’
In my scene.cpp file, I have included scene.h which includes image.h, so I'm pretty sure everything is properly linked. Is it apparent what my problem is or will I have to provide more information?
You want to call methods so try:
int beginX = this->images[i]->getXcoord();
int beginY = this->images[i]->getYcoord();
otherwise the compiler is looking for a member variable and not a getter method
If this->images is an Image**, then this->images[i] is an Image*.
Replace the dots with arrows.
The problem is the images array holds pointers to classes
try
int beginX =this->images[i]->getXcoord;
also if getXcoord is a function you need to call it like this
int beginX =this->images[i]->getXcoord();
lastly you dont need this-> its implied so use
int beginX = images[i]->getXcoord();
DC
There are two issues. It should be:
int beginX = this->images[i]->getXcoord();
The error message isn't allowing the '.' operator on the Image* which is not a class-type object.