I'm writing a Qt GUI program in conjuction with OpenCV to create a people tracking application. OpenCV has a lot of functions that take a matrix as input and output, for example a color conversion one:
cvtColor(inputArray src, outputArray dst, int code, int dstCn=0);
Mat is the default matrix class of OpenCV, and assuming I have a Mat object called frame, I would implement the function like this to change its properties:
cvtColor(frame, frame, CV_RGB2HSV,0);
Is there any downside on using the same variable as input and output on any function? or should I create a copy first?
or should I look in every function documentation?
I think it's a personal choice. Here's some personal samples:
Take readonly input, a reference to the output and, after you process the input, push it to the output. Optional error result friendly.
bool function(const type& input, type& output){
output = input;
return true;
}
Take readonly input, assign it to output, change output and return it (C++11 move optimized).
type function(const type& input){
type output = input;
return output;
}
type output = function(input);
Here you force a new copy of the object as the argument and you can use it and return it (C++11 best when you don't want to alter your copy). See also: Want speed, pass by value..
type function(type input){
// modify input
return input;
}
type output = function(input);
Input and output in the same argument. Use with caution. Can return error.
bool function(type& put){
return true;
}
It depends on your design. Don't need errors?... use a movable one. Need errors?... use one that leaves the return value accessible to you. Or, just follow existing practices but know how each can help or penalize your performance like:
// this makes a pointless copy for the input (use const ref here)
bool function(type input, type& output){
output = input;
return true;
}
(Right way is)
bool function(const type& input, type& output){
output = input;
return true;
}
PS: Personal opinion of a self taught C++ dev :)
This is a personal choice. If you don't need the input image later then by all means do it.
I already tried it actually, it works most of times but some other times it works poorly.
it depends on the function you're using.
Related
This is a follow up question from here: C++ - Developing own version of std::count_if?
I have the following function:
// vector for storing the file names that contains sound
std::vector<std::string> FilesContainingSound;
void ContainsSound(const std::unique_ptr<Signal>& s)
{
// Open the Wav file
Wav waveFile = Wav("Samples/" + s->filename_);
// Copy the signal that contains the sufficient energy
std::copy_if(waveFile.Signal().begin(), waveFile.Signal().end(),
FilesContainingSound.begin(), [] (const Signal& s) {
// If the energy bin > threshold then store the
// file name inside FilesContaining
}
}
But to me, I only need to capture the string "filename" inside of the lambda expression, because I'll only be working with this. I just need access to the waveFile.Signal() in order to do the analysis.
Anyone have any suggestions?
EDIT:
std::vector<std::string> FilesContainingSound;
std::copy_if(w.Signal().begin(), w.Signal().end(),
FilesContainingSound.begin(), [&] (const std::unique_ptr<Signal>& file) {
// If the energy bin > threshold then store the
// file name inside FilesContaining
});
You seem to be getting different levels of abstraction confused here. If you're going to work with file names, then you basically want something on this order:
std::vector<std::string> input_files;
std::vector<std::string> files_that_contain_sound;
bool file_contains_sound(std::string const &filename) {
Wav waveFile = Wav("Samples/" + filename);
return binned_energy_greater(waveFile, threshold);
}
std::copy_if(input_files.begin(), input_files.end(),
std::back_inserter(files_that_contain_sound),
file_contains_sound);
For the moment I've put the file_contains_sound in a separate function simply to make its type clear -- since you're dealing with file names, it must take a file name as a string, and return a bool indicating whether that file name is one of the group you want in your result set.
In reality, you almost never really want to implement that as an actual function though--you usually want it to be an object of some class that overloads operator() (and a lambda is an easy way to generate a class like that). The type involved must remain the same though: it still needs to take a file name (string) as a parameter, and return a bool to indicate whether that file name is one you want in your result set. Everything dealing with what's inside the file will happen inside of that function (or something it calls).
Is there an easy way to check if something was serialized in stl::ostream. I am looking for something like:
some preparation
// ... a very complex code that may result in adding or not to the stream,
// that I will prefer not to change
check if the stream has something added
Note that this will need to works recursively. Is using register_callback is a good idea or there is easier way?
First the immediate question: register_callback() is intended to deal with appropriate copying and releasing of resources stored in pword() and will have operations only related to that (i.e., copying, assigning, and releasing plus observing std::locale changes). So, no, that won't help you at all.
What you can do, however, is to create a filtering stream buffer which observes if there was a write to the stream, e.g., something like this:
class changedbuf: std::streambuf {
std::streambuf* d_sbuf;
bool d_changed;
int_type overflow(int_type c) {
if (!traits_type::eq_int_type(c, traits_type::eof())) {
this->d_changed = true;
}
return this->d_sbuf->sputc(c);
}
public:
changedbuf(std::streambuf* sbuf): d_sbuf(d_sbuf), d_changed() {}
bool changed() const { return this->d_changed; }
}
You can use this in place of the std::ostream you already have, e.g.:
void f(std::ostream& out) {
changedbuf changedbuf(out.rdbuf());
std::ostream changedout(&changedbuf);
// use changedout instead of out; if you need to use a global objects, you'd
// replace/restore the used stream buffer using the version of rdbuf() taking
// an argument
if (changedbuf.change()) {
std::cout << "there was a change\n";
}
}
A real implementation would actually provide a buffer and deal with proper flushing (i.e., override sync()) and sequence output (i.e., override xsputn()). However, the above version is sufficient as a proof-of-concept.
Others are likely to suggest the use of std::ostringstream. Depending on the amount of data written, this can easily become a performance hog, especially compared to an advanced version of changedbuf which appropriately deals with buffering.
Are you passing the stream into the complex code, or is it globally visible? Can it be any kind of ostream or can you constrain the type to ofstream or ostringstream?
You may be able to use tellp to determine whether the file position has changed since your preparation code, if your ostream type supports it (such as with most fstreams). Or, if you're passing the stream in, you could pass an empty ostringstream in and check that it's not empty when the string is extracted to be printed out.
It's not entirely obvious which solution, if any, would be appropriate for you without knowing more about the context of your code and the specifics of your problem. The best answer may be to return (or set as a by-reference out-parameter) a flag indicating whether the stream was inserted into.
I do have a function that I have created with a pointer as an argument.
That argument will be used to save at the end an image.
Every time when I would like to call that function with the desired parameter, I want that the saved image file would be with the specified name. I show you how:
void SaveImage(IplImage *img)
{
...
cvSaveImage("C:/img.png", img);
...
}
when calling the function: SaveImage(image1), I want to have an image on my C:/ whose name is image.png
Can you help me with that?
Apparently, you can't answer this question with the only answer that is actually viable, because you get downvoted...
So, I'll rephrase my answer:
You need to pass two variables to SaveImage:
void SaveImage(const char *name, IplImage *img)
{
...
cvSameImage(name, img);
}
Then your calling code will have to produce the correct name, such as:
SaveImage("c:\image.png", image);
SaveImage("c:\other.png", other);
Now, of course, if all you actually want is a unique name, rather than one that reflects the name of the variable in your code, then there are plenty of other possibilities, such as using a formatted string that contains a serial number, a random number, tmpnam() or other similar schemes.
For example
bool read(Input &input);
Input input; //error
bool success = read(input);
will be an error because Input has no default constructor.
Is there any trickery I can use to get the Input object out of the function in this case? I imagine there must be some unique_ptr trickery available to me, but I'm not sure exactly how. Feel free to suggest other methods.
Please suggest with example how the read function could look.
I would rather not create a (meaningless) default constructor for Input just for this purpose, and note that this is just a silly example, so don't attach any special meaning to the words "Input", "read", etc. :)
bool read(unique_ptr<Input> &input) // read asume input is disposable/empty
{ ....
input.reset(new Input( a,d,c ) );
....
}
....
unique_ptr<Input> input; //error ?
bool success = read(input);
if (input)
if (succes)
input->X();
else
input->Y();
unique_ptr<Input> input_ptr = read();
where read() is defined as:
unique_ptr<Input> read()
{
.
.
.
return unique_ptr<Input>(new Input(x,y,z));
}
From the comments, it appears that your problem is to design a function that
can fail (and if so should signal that to caller),
but if not, produces a value of a type without a default cconstructor
The first point is easy: use exceptions.
The second point is also easy: use the function return value feature.
I.e.,
Object foo()
{
if( "didna wrok" )
{
throw std::runtime_error( "foo: I failed, miserably" );
}
return Object( arg1, arg2, arg3 );
}
Now there also many other ways to do this, but the above is the most natural, directly using the language features that are intended to support and fully solve these aspects.
If you are in pre-C+11 world, there is a workaround by use of malloc:
bool read(Input &input); // keep the function read intact
Input* input = static_cast<Input*>(malloc(sizeof(Input))); // bypass constructor
bool success = read(*input);
...
free(input); // don't forget to free input later
My teacher wanted us to learn the ifstream class and how it works. She gave us homework to create a FileStream wrapper class that is templated to work with anything and can take in anything that's in the file.
I have written everything except I can't get it to compile because I don't know how to write the >> operator and keep getting errors for it. This is what I have so far:
template<class A>
ifstream& operator >>(FileStream<A> fs, A& x){
fs>>x;
return fs;
}
In the main she is using to check our work it is called like this:
FileStream<Word> input;
Word temp; //word is a class we created to manipulate strings in certain ways
while(input>> temp){
cout<<temp<<endl;
}
If anyone could help me out I would be most grateful. I've been working on this for 2 days and I can't get it.
template<class T>
FileStream<T>& operator >> (FileStream<T>& fs, T& value) {
value = fs.readValueFromStream();
return fs;
}
Your method should look something like the above. Highlights:
(Note that I've renamed A to T and x to value. T is the usual name for generic template arguments, and value is a bit more descriptive than x.)
Accepts a FileStream<T>& reference. The & ensures that you work with the original stream object and not a copy.
Returns a FileStream<T>& reference, not an ifstream.
Rather than doing fs>>x in the method, which would just be a recursive call to the very method we're in, you need to write code to actually read an item from the stream and put it into value. This should use some method of your FileStream class. I wrote value = fs.readValueFromStream() but this could be anything.
In this way operator >> serves as syntactic sugar. The real work is done by the value = fs.readValueFromStream() line (or whatever code you actually write there).