I am a beginner in openCV and C++ as well.I am stuck in a particular place while trying to implement face recognition in open cv.
I have the stored training images in a folder called data
the images of first person is stored like 1_john1.pgm
2nd image of first person .................1_john2.pgm and so on.

Next persons first image is again 2_peter1.pgm etc etc

Now I have -

vector<string> personNames;// array of person names (indexed by the person number).

Now after running face recognition algorithm i am getting -


which contains the string with the persons name which has been detected.
SO if john was detected it will return john.
Now I have to display the image of john from the training folder but there it is stored in the format 1_john1.pgm.

ANY one image of john is required to be displayed out of several images stored there.

I am not able to use wildcard in the strcat command properly to pass the name stored in the string to the opencv command for loading image. my unsuccessful efforts of last 25-30 hours of coding is below :-

strcpy (cstr, personNames[nearest-1].c_str());
      IplImage *img1=0, *img2;
     strcat(cstr, "data/%d_%s%d.pgm", 9, personNames[nearest-1].c_str(), 6);
	// img2 = cvLoadImage("data/9_john5.pgm");

The above is the latest bit of code which does not work at all, i have tried many many different techniques but did not succeed.

Now I am able to save the training image list in a text file called train.txt.
here the names are stored as
4 sachin data/4_sachin1.pgm
4 sachin data/4_sachin2.pgm
4 sachin data/4_sachin3.pgm
4 sachin data/4_sachin4.pgm

while the images are stored in the folder data

Let us assume personNames[nearest-1].c_str() has the string "sachin"

Basically I need to search the string 'sachin' in the train.txt file ,search through it till it comes to the entry -4 sachin data/4_sachin1.pgm
Now I have to remove "4 sachin "from the above so that i am only left with string 4_sachin1.pgm.
I need to pass this to the cvLoadimage command so that the image opens.
Will be very very grateful for the help of the experts in this forum to help me with the correct syntax.
Please Help"

Recommended Answers

All 8 Replies

Read training.txt into another vector of strings, call it trainingVec or something.

Return just personNames[nearest-1] (so you have it in a std::string representation.

Step through trainingVec, using the .find() method of each of the strings to see if it contains personNames[nearest-1] If it does, use .find() on that same element of trainingVec to locate the '/' , and using .substr() to grab the portion of the string after '/' .

Then, use the .c_str() method to convert to a C-string for use in the OpenCV function. That way, the mainstay of your manipulations can be done with the std::string .

Probably clear as mud, so take a crack at it, and post back with your revised code.

Thanks for taking time to go through my problem..
I am struggling with the syntax as I am unable to convert c string to string ...
I am posting some of my attempts below which would be hilarious if i was not against such a tight deadline...
My first attempt to convert the Vector to String was I wrote the c string to a file, closed file opened it again and copied the line using fget etc to read as a string....
then use find_first_of to match the entry in the text file.. then I had planned to use get line to read the line ,trim it to get the path to image file..

ifstream infile; 
	string namedata;
	string found;
	char *recog;
string pName;
					ifstream infile; 
					string namedata;
					string found;
					char recog[5] ;

       //if(!infile.eof()!=0) // To get you all the lines.
	    nameFile = fopen("name.txt", "w");
	    fprintf(nameFile, "%s\n",personNames[nearest-1].c_str());
	     nameFile = fopen("name.txt", "a");
	    fgets(recog,20,nameFile); // Saves the line in STRING.
	     fprintf(nameFile, "this is the name %s\n",recog);

       while(!infile.eof()) // To get  all the lines.
	        getline(infile,namedata); // Saves the line in STRING.
			nameFile = fopen("Surf.txt", "a");
					fprintf(nameFile, "%s\n",found);
	        //cout<<data; // Prints our STRING.// just to check the output
		//cout<<personNames[nearest-1].c_str();// just to check the output
   system ("pause");

After this foolishness I tried out this technique Here the Problem was again string to char conversion error

FILE *fpName;
	fopen_s(&fpName, "name.txt", "r+");
	fgets(pName, 256, fpName);

					char storeFoundName[256];
					for(int i=0; i<256; i++)
						storeFoundName[i] = 0;

					char pathName[500];
					for(int i=0; i<500; i++)
						pathName[i] = 0;

	FILE *fpTrain;
	fopen_s(&fpTrain, "train.txt", "r+");

	int foundChar = -1, lnCounter = 0;
	bool nameExist = false;

	// Searching each line of the train.txt till tne input name is found
	while(nameExist == false)
		char storeTrain[600]; // Buffer to store each line of file
		for(int i=0; i<600; i++)
		storeTrain[i] = 0;

	fgets(storeTrain, 600, fpTrain); // Reading each line of the input file
		int j = 0;

	// Searching for the person name in the file and copying it into a new buffer
		for(int i=0; i<300; i++)
			if(storeTrain[i] == pName[j])
				storeFoundName[j] = storeTrain[i];
			if(foundChar == 1)
				foundChar = 0;

		int lnPos = 0, pathPos = 0;
	char isEqual = strcmp(storeFoundName, pName); // Comparing the input person name and the person name from the file
		if(isEqual == 0)
			while(lnPos <= 600)
		if(storeTrain[lnPos] == 'd' && storeTrain[lnPos+1] == 'a' && storeTrain[lnPos+2] == 't' && storeTrain[lnPos+3] == 'a')
					for(int m=lnPos; m<600; m++)
						if(storeTrain[m] != NULL)
						pathName[pathPos] = storeTrain[m];
					nameExist = true;

	int count = 0;
	for(int i=0; i<500; i++)
		if(pathName[i] != NULL)
			//TRACE("%c", pathName[i]);

	img2 = cvLoadImage(pathName);

After This I am presently trying out the technique suggested by you . I found this code on another forum on the same lines as suggested by you and am trying to implement the same

while(getline(in, line))
	for( vector<string>::const_iterator itr = vect1.begin(); itr != vect1.end(); ++itr )
		str = (*itr).substr(pName));
		if( line.find(str) != string::npos )
			vect2.push_back(line);	// 413: common between 413 and 403

ANyway it feels good venting . Hopefully I will be able to implement something tonight
Dont bother implementing the above codes all of them have plenty of errors.

I'm not sure why you're using anything but fstream across the board to do your file reading. See http://www.cplusplus.com/doc/tutorial/files/ for a good tutorial. Do everything C++ style up until the last step, once you have your std::string and have done all of the necessary manipulations, only then use the .c_str() method to finally pass it to the OpenCV function.

This is what I have managed to do till now...mostly through trial and error
I can open the train file and remove the first part of the string till i get the image path for ALL the entries in the train .txt file.

from this -
4 sachin data/4_sachin1.pgm
4 sachin data/4_sachin2.pgm

I am getting This -
But I am not able to search in the text file.I have tried using "find first of" or "find" but they return a numeric value of the position of the string, Also I am unable to print ONLY the first line which matches the search string ,indicated by the position (npos) returned by the above commands.
Can someone help out with the syntax Please?
The entire code is below which can be compiled in devc++.

#include <iostream>
#include <fstream>
#include <cstdlib>
#include <string>
#include <sstream>
#include <vector>
using namespace std;
int main()
// Variable for the dealer number
string dNumber;
string line  ;
vector<string> fields;
string cName =" " ;
string str2= ("sachin");// this name has to come from personNames[nearest-1].c_str() from main program
// std::ifstream dealers("filename.txt");
// ofstream constructor opens file
ifstream dealers ( "train.txt", std::ios::in);

           getline(dealers,cName,' '); 
            istringstream istream(line);
               size_t found; 
               string token ;
         while(      getline(istream ,token, ' '))
               getline(istream,line,'\ ');// space is removedby ''
               //cout <<  token << "" ;
               cout << line<<endl;
                          cout << "\n";


Finally managed to blunder through ,to a partial solution for searching through the text file for the image path,However 2 problems remain
1st - Giving the string stored by this - (personNames[nearest-1].c_str() to char * search ;
and 2nd
If the above is successful i will get a result like this- data/3_sachin5.pgm. this has to be inserfted in the command cvLoadImage("data/3_sachin5.pgm");

cout<<(personNames[nearest-1].c_str())<<"";// this contains the string by which I want to search through the file index.txt
//cout displays the correct name.....

IplImage *img1=0, *img2;
// new code by me 2-08-11 for reading from text files using vectors modified on  5-08-11
	 //char* ConvertToChar(const personNames[nearest-1].c_str() &s, char* pAnsiString, int bufsize);
  //  {
		//int bufsize;
		//string pAnsiString;
		//char * s;
  //  wcstombs(pAnsiString,(LPCTSTR) s, bufsize);
  //  return pAnsiString;
  //  }

/*^^^The code above does not work and I didnt understand it at all
the code below gives me the correct result from the file index.txt when i manually specify a string at char * search*/ 

int offset;
string line   ;
string  cName = "" ;
char* search = "sachin";  // search pattern
ifstream dealers ( "index.txt", std::ios::in);
                 getline(dealers,cName,' '); //get line and ignore/skip delimiter
                 istringstream istream(line);
if ((offset = line.find(search, 0)) != string::npos)
 cout << line <<endl;  //here the cout gives me the correct string --- in the form of data/3_sachin5.pgm or whatever 

    img2 = cvLoadImage("*line");

Now I need to insert the string in the cvload image command in the format as below


Can someone help me with these two operations please??

Only this part Remains----rest completed
Now I need to insert the string in the cvload image command in the format as below


Can someone help me with these two operations please??

So now just use the .c_str() to get back the const char * representation, cvLoadImage(line.c_str());

This did it finally ,thanks to help from friend/s

my_str = new char [line.size() + 1];
							std::copy(line.begin(), line.end(), my_str);
							my_str[line.size()] = '\0';
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, learning, and sharing knowledge.