OpenCV Creating Video From Text File - c++

I am trying to build an application, which get data from webcam or external device, saves Video Frames into text file, then read frames from created text file.
I don't know whether it is a good idea to save to text file, I'm open suggestions.
So far I've done to saving to a text file.
My problem is reading from text file. Basically I read text line by line, but I don't know how to convert this text into Mat object.
So far my code is:
ifstream read_storage(new_vid_frm_path);
if(!read_storage.is_open()) {
perror("\n\n\n\t\t\t(-)FAIL : Can't Open SavedVideoFrames.txt\n\n\n\t\t\t");
return -1;
}
VideoWriter *vid = new VideoWriter(new_vid_frm_path,CV_FOURCC('P', 'I', 'M', '1'),30,Size(vc.get(CV_CAP_PROP_FRAME_WIDTH),vc.get(CV_CAP_PROP_FRAME_HEIGHT)));
Mat line;
vector<Mat> vid_frms;
while ( getline (read_storage,line) ) {
cout << line << '\n';
}
read_storage.close();
if(vid_frms.size() == 0){
printf("\n\n\n\t\t\t(-)FAIL: Error In Frame\n\n\n\t\t\t");
return -1;
}
for(size_t i = 0; i<vid_frms.size(); i++)
(*vid).write(vid_frms[i]);
printf("\n\n\n\t\t\t(+)SUCCESS: Video Processing Complete \n\n\n\t\t\t ");
Do you have ay suggestions how can I cast or convert this line string to Mat obejct?
while ( getline (read_storage,line) ) {
cout << line << '\n';
}
Thanks.
By the way, I looked at this solution, but I couldn't understand.
Convert a string of bytes to cv::mat
I couldn't find the byte type in c++ and I think there might be a direct conversion between String to Mat object.

You can save anything (just about) in OpenCV to a .xml or .yml text file and then read it back in using the OpenCV XML/YAML FileStorage methods.
I highly recomend this over using native C++ methods for file stuff.
It's specifically designed to handle all this legwork for you.

Related

Train_hog.cpp OpenCV 3.1 Example - Cannot pass the proper path parameters

This post describes a very similar problem to mine however I am new here and was told to post a new question. Would very much appreciated anyone's help.
#Franksye I am stuck with the same problem. I am passing the path in this line
{#pd|C:/Cars/|pos_dir}{#p|Pos.lst|pos.lst}{#nd|C:/Cars/|neg_dir} {#n|Neg.lst|neg.lst}");
In the text file Pos.lst I wrote for example image0000.png, image0001.png underneath each other.
However when I run the debugger after build it gives me the below error
The program '[0x3CF0] opencv.exe' has exited with code -1 (0xffffffff).
When creating Brake points i realized that it is exiting on the load_images function when executing file.open((prefix + filename).c_str());
void load_images(const string & prefix, const string & filename, vector< Mat > & img_lst)
{
string line;
ifstream file;
file.open((prefix + filename).c_str());
if (!file.is_open())
{
cerr << "Unable to open the list of images from " << filename << " filename." << endl;
exit(-1);
}
bool end_of_parsing = false;
while (!end_of_parsing)
{
getline(file, line);
if (line.empty()) // no more file to read
{
end_of_parsing = true;
break;
}
Mat img = imread((prefix + line).c_str()); // load the image
if (img.empty()) // invalid image, just skip it.
continue;
#ifdef _DEBUG
imshow("image", img);
waitKey(10);
#endif
img_lst.push_back(img.clone());
}
}
I believe that I am doing something wrong when passing the path of the directory since the load_images function is not able to open the file of the images.
Can someone point me in the right direction or tell me what it is that I am doing wrong please.
Thank you in advance.
Solved it! Such a stupid mistake thanks to Windows.
pos.lst and neg.lst where actually pos.lst.txt and neg.lst.txt because of file extension being hidden. Thanks to This post managed to solve my problem.
Had to switch to Windows because i needed to use Visual Studio will revert back to Ubuntu once this project is over!

Vector mat in txt

I ve got a vector Mat file and I want to store it in txt file. Every mat file has size 1x4500 and I ve got in total 5000 vectors. I tried to store in txtfile with the above code:
void writeMatToFile(cv::Mat& m, const char* filename){
ofstream fout(filename);
for(int i=0; i<m.rows; i++){
for(int j=0; j<m.cols; j++){
fout<<m.at<float>(i,j)<<"\t";
}
fout<<endl;
}
fout.close();
}
In main:
string file = "output.txt";
writeMatToFile(image,file.c_str());
However, I got unhandled exception errors.
Write your data in binary mode using your own format. Something like : mat_count|shape1|data1(row_first)|shape2...
std::fstream will do the harder job for you in text mode or binary mode. You should try both to see the final size.
If your Mat data is something like uint8, uint16, the binary mode will be much better. The problem with text-mode is that you need a separator for each single data which add additional bytes to your file. However text-mode can compress data : "1.5" 3 vs 8 bytes (double).
Last thing, if you want absolutely a file in text-mode, you can zip it at the end of your process and see the ratio.

video is not being written to file

I am using opencv to capture a video directly from webcam and saving it to a avi file. I have used the following code:
#include "StdAfx.h"
using namespace std;
using namespace cv;
int _tmain()
{
VideoCapture src;
src.open(1);
if(!src.isOpened())
{
cout<<"could not open camera\n";
return -1;
}
else
{
cout<<"camera opened\n";
}
int ex=static_cast<int>(src.get(CV_CAP_PROP_FOURCC));
Size s(Size((int)src.get(CV_CAP_PROP_FRAME_WIDTH),(int)src.get((CV_CAP_PROP_FRAME_HEIGHT))));
VideoWriter out;
out.open("out.avi",ex,20,s);
while(1)
{
Mat im;
src>>im;
imshow("vid",im);
out<<im;
char c;
c=cvWaitKey(50);
if(c==27)
break;
}
system("pause");
}
all the headers are included in stdafx.h.
But actually I am getting a avi file of size 0bite. How to fix this thing? I need to record the webcam video without displaying.
Note: I'm new in openCV and I am using Visual Studio 2010
to run the application without display the webcam just delete
imshow("vid",im);
and out.avi size is 0 because you open it when the application is running (when you open the video stream and write on it ) , to open the video which you recorded , just close the application to end the write on the video and then open it .
Actually there is no logical error in your program. The only problem is the FOUR_CC Codec you are using to write the video.
When I ran your code, I faced the exact problem as yours. When I added the error checking to the out.open() function, I found the problem.
Most probably, the FOUR_CC codec of the camera is not supported by the avi container.
As you are using Windows, a good option is to use CV_FOURCC_PROMPT in the 2nd argument of out.open.
This will open a pop up list box containing different FOUR_CC codecs available. If you don't know which one to choose, just select Full Frames (Uncompressed). It is the most compatible option but will increase the size of the output video file.
The final code should look like this:
if(!out.open("out.avi",CV_FOURCC_PROMPT,20,s))
{
cout<<"Writer Not Opened"<<endl;
return -1;
}

ifstream breaks after reading a file 3 times

Im picking up values from a .txt file using ifstream. i am also using windows library to read all files in a folder, that is loop over until the end of folder is reached. In this loop I am reading values from a txt file and adding it to a matrix using push_back.
Here is the section of code under question:
Mat trainme(0, dictionarySize, CV_32FC1);
Mat labels(0, 1, CV_32FC1); //1d matrix with 32fc1 is requirement of normalbayesclassifier class
hTrain = FindFirstFile(full_path, &TrainData);
if (hTrain != INVALID_HANDLE_VALUE)
{
ifstream file("c:\\222\\labels.txt");
string line;
do {
strcpy(loc,DirSpec);
Mat img = imread(strcat(loc,TrainData.cFileName), 0);
cout<<"Processing file: "<<TrainData.cFileName<<endl;
if (!img.data){
cout << "Image data not loaded properly: " <<TrainData.cFileName<< endl;
cin.get();
}
vector<KeyPoint> keypoints;
features->detect(img, keypoints);
if(keypoints.empty()) cout<<"Cannot find keypoints in image: "<<TrainData.cFileName<<endl;
Mat bowDescriptor;
bowDE.compute(img, keypoints, bowDescriptor);
trainme.push_back(bowDescriptor);
getline(file, line);
labels.push_back(line);
strcpy(loc,"");
} while( FindNextFile(hTrain,&TrainData));
}
The problem arises at the line labels.push_back(line); after 3 loops. I mean the file is read 3 times and after that the error: Access violation writing location. And points to this line in memcpy.asm:
mov [edi],al ;U - put byte in destination
I cannot figure out why it fails. I thought it may be a problem transferring string format so I used float value = atof(line) but that gave an error that it cannot convert from string format and it can only take the old c style string.
Here is what is contained in the labels.txt
1
2
2
2
1
2
2
2
Thank you for looking.
Update: I tried moving the file reading out of the main loop and used while(file.good()) But I still get the same error at the same spot. I have no idea why.
string line;
ifstream file("c:\\222\\labels.txt");
if (file.is_open())
{
while (file.good() )
{
getline (file,line);
labels.push_back(line);
}
file.close();
}
Alrighty, I managed to get it solved... =/
The problem was here: labels.push_back(line);
I think adding std::string to Mat using push_back is not possible.
I solved it by converting the string to float using atof.
getline (file,line);
float label = atof(line.c_str());
labels.push_back(label);

How can I read from an XML-string in OpenCV?

I know how to load/save a cv::Mat instance into a XML-file (See this question).
But what I really need, is to parse a std::string (or char *) that contains the XML, and get the cv::Mat. Say I get the XML out of a database, and not from a file.
Is that possible?
You can do it since OpenCV 2.4.1.
Here is a code sample from release notes:
//==== storing data ====
FileStorage fs(".xml", FileStorage::WRITE + FileStorage::MEMORY);
fs << "date" << date_string << "mymatrix" << mymatrix;
string buf = fs.releaseAndGetString();
//==== reading it back ====
FileStorage fs(buf, FileStorage::READ + FileStorage::MEMORY);
fs["date"] >> date_string;
fs["mymatrix"] >> mymatrix;