Relative Path Using imread (OpenCV) - c++

i have a problem of which i am not sure where it comes from. Please take a look at this function:
http://pastie.org/8200205
imread appears to return empty matrices.
To be clear, my images are in the directory ImageData which is directly where my program lies, and for each object type like apple, i have a directory that is called like the object type and inside are all the apple images (if that's the current object type)
Additionally, i'm working with cmake but i'm pretty sure that i don't have to include directories w/o any code.
So what's the problem here? Is my pathing wrong or does imread not work in subdirectories?
I appreciate any suggestions/solutions :)

Relative paths are relative to the process working directory. This is not necessarily the same as the directory in which the executable resides. So assuming you've got everything else right, then the most likely explanation is that your working directory is not the same as the directory in which the executable resides.
In any case, it sounds as though you want the program to locate the files in a directory relative to the executable. In which case you should not rely on the working directory and instead you will need to form the full path to the files. You'll just need to prepend the directory of the executable.

Related

Program cannot find image directory when run from IDE, but CAN when run from folder?

When I build, it succeeds with no errors. However, when I run from the IDE, I get an error (my image fails to load because it cannot find the directory).
However, if I go into the folder and run the program(.exe) it finds the image directory perfectly.
mTextures.Load(Textures::Background, "../GFX/Background.png");
^the line of code giving the directory.
I assume this is a problem with a setting I didn't enter correctly in my compiler?
I am using Code::Blocks on Windows.
Your debugger's current directory (i.e. the current directory used when you execute the application from within codeblock) is probably incorrect. Check your project settings, and fix the current directory to your target directory (the one which contains the executable itself).
Specific instructions are here.
It's because you're using a relative path in your file name:
"../GFX/Background.png"
the .. is saying "go up one directory form the current directory". If you want to be able to run your program anywhere, use an absolute path, something like:
"/home/me/GFX/Background.png"
Add the full path where the image exist with double slash.
mTextures.Load(Textures::Background, "C:\\Program Files\\..\\..\\GFX\\Background.png");

Files being created in the wrong folder

To give a little context: I'm writing a program that uses text files and BMP files. For the text files I was provided with a class to manage them and I'm using EasyBMP for the BMP manipulation.
The problem I have is the files are being created in the wrong folder unless I provide the full path.
Example:
#include "EasyBMP.h"
int main(){
BMP picture;
picture.SetSize(640,480);
picture.WriteToFile("picture.BMP");
return 0;
}
Expected result: 640x480 BMP file created somewhere in my project folder (C:\Users[user]\Documents\C++\TP 1)
Actual result: 640x480 BMP file created in Eclipse folder (C:\Users[user]\Documents\Eclipse)
The same happens with any other file I write to disk.
It used to work fine on a different project so I'm guessing there's something silly I'm missing somewhere but I haven't been able to find a solution.
EDIT: The exact same code works fine on a different project.
If you don't specify a full pathname, files are stored in the process's current folder. You can change that in Eclipse (tell if which folder to run from when you run the process).
If you always want the files to be stored where your EXE is, or somewhere around the EXE, you can find the folder yourself(the first argument to main is the location of the EXE file).
The program will write the file in the working directory. That's because you used a relative path and relative paths are relative to the working directory.
Either specify a full path in your code, or ensure that the working directory is set to your desired value when running the program.

Different paths used for #include and other files

I'm quite confused about this weird behaviour of my .cpp project. I've got the following folder structure:
include/mylib.h
myproject/src/eval.cpp
myproject/data/file.csv
myproject/Makefile
In eval.cpp I include mylib.h as follows:
#include "../../include/mylib.h"
and compile it through Makefile:
all:
g++ -I include ../include/mylib.h src/eval.cpp -o eval.out
Now in my eval.cpp I'm reading the file.csv from data directory and if I refer to it like this
../data/file.csv
it doesn't find it (gets empty lines all the time), but this
data/file.csv
works fine.
So, to include mylib.h it goes two directories up (from src folder) which seems right. But it doesn't make sense to me that to refer to another file from the same piece of code it assumes we are in project directory. I suppose it is connected with Makefile somehow, but I'm not sure.
Why is it so?
EDIT: After a few thing I tried it seems that the path which is used is not the path from binary location to the data location, but depends on where from I run the binary as well. I.e., if I have binary in bin directory and run it like:
./bin/eval.out
It works with data/file.csv.
This:
cd bin
./eval.out
works with ../data/file.csv.
Now it seems very confusing to me as depending on where I run the program from it will give different output. Can anyone please elaborate on the reasons for this behaviour and if it is normal or I'm making some mistake?
It is so because (as explained here ) the compiler will search for #included files with quotes (not with brackets) with the current working directory being the location of the source file.
Then, when you try to open your .csv file, it's now your program that looks for a file. But your program runs with the current working directory being myproject/ which explains why you must specify data/file.csv as your file path, and not ../data/file.csv. Your program does not run in your src folder, it will run in the directory the binary ends up being invoked from.
You could have noticed that in your Makefile, your -I options specify a different path for your header file than your .cpp file.
EDIT Answer: It's quite simple actually and completely normal. When you invoke your binary, the directory which you're in is the current working directory. That is, if you run it with the command ./myproject/bin/eval.out, the current working directory is . (e.g. /home/the_user/cpp_projects). My post was a bit misleading about that, I corrected it.
Note: You can use the command pwd in a command prompt to know which is the current working directory of this prompt (pwd stands for "print working directory").

Executable using images in different directory

I have the following directory structure
(root)
/ | \
bin resources src
| | |
Debug dot.bmp .cpp
|
.exe
I would like the .exe file to use dot.bmp.
Here's the code from the .cpp file that loads dot.bmp
player_img = il->load_image( "dot.bmp" );
I feel like I need to modify this line of code, but after changing it to:
player_img = il->load_image( "../resources/dot.bmp" );
I still get an error saying that the image couldn't be loaded.
What do I need to change? Is this even possible, or should I just give up and put the image in the same directory as the .exe?
You need to go down one further level in order to get to the root.
../../resources/dot.bmp
Your executable is in bin/Debug but I think you coded under the assumption that it is in bin.
Assuming you are on Windows, the relative path will be relative to the current working directory rather than the directory where the executable resides. Often they are the same thing, but not necessarily.
I would be inclined to use fully-qualified paths and pre-pend the directory where the executable lives. You can obtain this by calling GetModuleFileName passing NULL as the hModule argument. This will return the full path to the executable so you will need to strip off the file name portion.
You will also need to think about deployment. This structure looks like your development structure but you may want a different organisation when you deploy the program. For example, I'd expect the executable to live in the bin directory when deployed.
One final thought. Assuming the images that your program needs is known at compile time it would be much easier to link them into the executable as resources. That way you simply don't have to worry about these issues at all and the executable can stand alone.

std::ifstream::open() not working

I am developing a prototype for a game, and certain gameplay rules are to be defined in an ini file so that the game designers can tweak the game parameters without requiring help from me in addition to a re-compile. This is what I'm doing currently:
std::ifstream stream;
stream.open("rules.ini");
if (!stream.is_open())
{
throw new std::exception("Rule file could not be opened");
}
// read file contents here
stream.close();
However, my stream never opens succesfully. Diving deep into the STL source during debugging reveals that _getstream() (as defined in stream.c) keeps on returning NULL, but I just can't figure out why this is. Help, anyone?
Edit: Rules.ini is in the same directory as the .exe file.
You are assuming that the working directory is the directory that your executable resides in. That is a bad assumption.
Your executable can be run from any working directory, so it's usually a bad idea to hard-code relative paths in your software.
If you want to be able to access files relative to the location of your executable, you should first determine the path of your executable and create a fully qualified path from that.
You can get the name of your executable by examining the argv[0] parameter passed to main(). Alternatively, if you're on Windows, you can get it with GetModuleFileName() by passing NULL as the first parameter.
Is the scope of your open stream correct.
"rules.ini" isn't a full path so it has to be relative so what is it relative to. Or do you need to use full path there.
(wild assumption here) you are using visual studio. During debug, your program is going to search the project directory for "rules.ini"
However, if you try executing your program from "myproject/debug/myexe.exe", it should run fine because it is going to search "/debug" for rules.ini
Like its been mentionned you should specify the full path because relative path tend to lead to errors