I am trying to create a json file from c++. The used code is the following:
Mat projected = eigenfacesExtraction(fileName);
ofstream myfile;
myfile.open ("detection.json");
myfile << "{\n";
myfile << "\t \"meta\":{\n";
myfile << "\t \"duration\":\""<<duration<<"\",\n";
myfile << "\t \"fileName\":\""<<fileName<<"\"\n";
myfile << "},\n";
myfile << "\t \"num_of_people\":\""<< faces.size()<<"\",\n";
myfile << "\t \"faces\":[\n";
myfile << "\t \"projected\":[" << projected.size <<"] ,\n";
for(int i=0; i<faces.size(); i++){
if(!faces.empty()){
if(i!= faces.size()-1){
myfile << "\t \"coord\":\" \t[" << faces[i].x << ", "<<faces[i].y<< ", "<< faces[i].width << ", "<<faces[i].height<<"],\n";
myfile << "\t \"descr\":\" \t[" << projected.at<double>(0,1) << ", "<<projected.at<double>(0,2)<< ", "<< projected.at<double>(0,3) << ", "<<projected.at<double>(0,4)<<"],\n";
}
else myfile << "\t \"coord\":\" \t[" << faces[i].x << ", "<<faces[i].y<< ", "<< faces[i].width << ", "<<faces[i].height<<"]\n";
myfile << "\t \"descr\":\" \t[" << projected.at<double>(0,1) << ", "<<projected.at<double>(0,2)<< ", "<< projected.at<double>(0,3)<< ", "<<projected.at<double>(0,4)<<"],\n";
}
}
myfile << "]\n";
myfile << "}";
myfile.close();
cout<< "Detection process exits...."<<endl;
//imwrite( "/opencvAssets/results/"+fileName, image );
imwrite("outputCapture.jpeg", image);
//waitKey(0);
//imshow("cropped image", croppedFaceImage);
My program works fine, json file is stored properly also cout prints the message, but I am receiving the following message "Segmentation fault (core dumped)". When I comment out iwrite command neither json nor cout work and I am receiving again the same message. What is the matter here?? The eigenFacesExtraction function (which may cause the problems) is the following:
Mat Detection::eigenfacesExtraction(string fileName){
Ptr<FaceRecognizer> model = createEigenFaceRecognizer();
model->load("eigenfaces.yml"); // Load eigenfaces parameters
Mat eigenvalues = model->getMat("eigenvalues"); // Eigen values of PCA
Mat convMat = model->getMat("eigenvectors"); //Convariance matrix which contains eigenvectors
Mat mean = model->getMat("mean"); // Mean value
convMat.convertTo(convMat, CV_32F);
mean.convertTo(mean, CV_32F);
string path = fileName;
Mat sample ,pca_ed_sample, resizedSample;
sample = imread(path, CV_LOAD_IMAGE_GRAYSCALE);
sample.convertTo(sample, CV_32F);
resize(sample,resizedSample,Size(60,60),0,0,INTER_LINEAR);
Mat nu = resizedSample.reshape(1,3600).t();
pca_ed_sample = (nu-mean)*(convMat);
return pca_ed_sample;
}
Segmentation fault occurs when we try to change only readable memory or when we try to access the memory out of your program boundaries. Place it in a debugger and trace it thoroughly. For more information chech this stackoverflow question
What is a segmentation fault?
Related
In my application the JPEG image arrives as a char* array. I need to convert this to an OpenCV cv::Mat object. To test behavior I create another cv::Mat from cv::imread.
The Mat create from imread works fine when I try to convert it from BGR to RGB format. But the Mat created from the raw char array Seg faults when trying to convert it.
Code is attached below:
//read_image -> get the char* array
//convert_image -> convert char* array to Mat object
//mat_process -> convert the Matrix to the RGB format of the correct size
//When the Matrix is created from cv::imread and I call mat_process it returns correctly
//When the Matrix is created from read_image -> convert_image, it seg faults on mat_process
typedef cv::Point3_<float> Pixel;
char* read_image(string image_name){
cout << "Reading image " << endl;
std::ifstream file(image_name, ios::binary);
file.seekg(0, std::ios::end);
size_t filesize = (int)file.tellg();
file.seekg(0);
char* output = new char[filesize];
file.read(output, filesize);
cout << "IMAGE SIZE IS " << filesize << endl;
return output;
}
cv::Mat convert_image(char* img){
cv::Mat* raw_data= new cv::Mat(1080,1920,CV_8UC3,img,cv::Mat::AUTO_STEP);
cout << " Got raw data " << raw_data->cols << " rows " << raw_data->rows << endl;
//Mat decoded_mat = imdecode(raw_data,IMREAD_UNCHANGED);
//cout << "Decoded the matrix " << decoded_mat.cols << " rows are " << decoded_mat.rows << endl;
//return decoded_mat;
return *raw_data;
}
auto mat_process(cv::Mat src, uint width, uint height) -> cv::Mat{
// convert to float; BGR -> RGB
cv::Mat dst;
cout << "Creating dst" << endl;
src.convertTo(dst, CV_32FC3); **// SEGMENTATION FAULT OCCURS HERE WITH RAW CHAR ARRAY**
cout << "Creating dst2" << endl;
cv::cvtColor(dst, dst, cv::COLOR_BGR2RGB);
cout << "Creating dst3" << endl;
// normalize to -1 & 1
Pixel* pixel = dst.ptr<Pixel>(0,0);
cout << "Creating dst4" << endl;
const Pixel* endPixel = pixel + dst.cols * dst.rows;
cout << "Creating dst5" << endl;
for (; pixel != endPixel; pixel++)
normalize(*pixel);
// resize image as model input
cout << "Creating dst6" << endl;
cv::resize(dst, dst, cv::Size(width, height));
cout << "Creating dst7" << endl;
return dst;
}
char * img1 = read_image(imgf1);
cv::Mat img1_mat = convert_image(img1);
cv::Mat img1_comp = imread(imgf1);
cout << " Start process " <<endl;
cv::Mat conv1 = mat_process(img1_comp,320,320); //This code executes fine
cout << " Done 1 " << endl;
cv::Mat conv2 = mat_process(img1_mat,320,320); //Segmentation Fault appears here
cout << " Done process " <<endl;
I am displaying and manipulating a video with open CV as so
// looping through list of videos
for (unsigned int i = 0; i < img_loc.size(); i++)
{
string fileLoc = root_dir + "\\" + img_loc[i];
string name = img_loc[i].substr(0,img_loc[i].find("."));
cv::VideoCapture cap(fileLoc);
image_window win;
int cnt = 0;
while (!win.is_closed())
{
cv::Mat temp;
cap >> temp;
if (temp.empty())
{
break;
}
cout << "frame number ---- " << cap.get(CV_CAP_PROP_POS_FRAMES) << endl;
cv_image<bgr_pixel> cimg(temp);
// some image manipulations
win.clear_overlay();
win.set_image(cimg);
cout << cnt << endl;
// save some details
cnt++;
cout << "after cnt++ ------------ " << cnt << endl;
}
cout << endl << "finished with " << img_loc[i] << ", proceed to the next video?" << endl;
cin.get();
}
which works fine for the first for all frames except the very last. I know there are exactly 200 frames but cnt only ever reaches 198 and the frames only ever go up to 199. The final frame isn't entirely necessary but it means there's some extra data handling that I'd rather avoid. Any ideas?
I have been working on head pose estimation on depth data. And I have read G Fanelli's paper-"Real Time Head Pose Estimation from Consumer Depth Cameras" "Real Time Head Pose Estimation with Random Regression Forests". I test the data and the code Fanelli published on the website(http://www.vision.ee.ethz.ch/~gfanelli/head_pose/head_forest.html). However when I run the code, there is a problem. The error information is "usage: ./head_pose_estimation config_file depth_image". I think it is about file reading but I don't how to fix it.
and the code is like this:
int main(int argc, char* argv[])
{
if( argc != 3 )
{
cout << "usage: ./head_pose_estimation config_file depth_image" << endl;
exit(-1);
}
loadConfig(argv[1]);
CRForestEstimator estimator;
if( !estimator.loadForest(g_treepath.c_str(), g_ntrees) ){
cerr << "could not read forest!" << endl;
exit(-1);
}
string depth_fname(argv[2]);
//read calibration file (should be in the same directory as the depth image!)
string cal_filename = depth_fname.substr(0,depth_fname.find_last_of("/")+1);
cal_filename += "depth.cal";
ifstream is(cal_filename.c_str());
if (!is){
cerr << "depth.cal file not found in the same folder as the depth image! " << endl;
return -1;
}
//read intrinsics only
float depth_intrinsic[9]; for(int i =0; i<9; ++i) is >> depth_intrinsic[i];
is.close();
Mat depthImg;
//read depth image (compressed!)
if (!loadDepthImageCompressed( depthImg, depth_fname.c_str() ))
return -1;
Mat img3D;
img3D.create( depthImg.rows, depthImg.cols, CV_32FC3 );
//get 3D from depth
for(int y = 0; y < img3D.rows; y++)
{
Vec3f* img3Di = img3D.ptr<Vec3f>(y);
const int16_t* depthImgi = depthImg.ptr<int16_t>(y);
for(int x = 0; x < img3D.cols; x++){
float d = (float)depthImgi[x];
if ( d < g_max_z && d > 0 ){
img3Di[x][0] = d * (float(x) - depth_intrinsic[2])/depth_intrinsic[0];
img3Di[x][1] = d * (float(y) - depth_intrinsic[5])/depth_intrinsic[4];
img3Di[x][2] = d;
}
else{
img3Di[x] = 0;
}
}
}
g_means.clear();
g_votes.clear();
g_clusters.clear();
string pose_filename(depth_fname.substr(0,depth_fname.find_last_of('_')));
pose_filename += "_pose.bin";
cv::Vec<float,POSE_SIZE> gt;
bool have_gt = false;
//try to read in the ground truth from a binary file
FILE* pFile = fopen(pose_filename.c_str(), "rb");
if(pFile){
have_gt = true;
have_gt &= ( fread( >[0], sizeof(float),POSE_SIZE, pFile) == POSE_SIZE );
fclose(pFile);
}
//do the actual estimate
estimator.estimate( img3D,
g_means,
g_clusters,
g_votes,
g_stride,
g_maxv,
g_prob_th,
g_larger_radius_ratio,
g_smaller_radius_ratio,
false,
g_th
);
cout << "Heads found : " << g_means.size() << endl;
//assuming there's only one head in the image!
if(g_means.size()>0){
cout << "Estimated: " << g_means[0][0] << " " << g_means[0][1] << " " << g_means[0][2] << " " << g_means[0][3] << " " << g_means[0][4] << " " << g_means[0][5] <<endl;
float pt2d_est[2];
float pt2d_gt[2];
if(have_gt){
cout << "Ground T.: " << gt[0] << " " << gt[1] << " " << gt[2] << " " << gt[3] << " " << gt[4] << " " << gt[5] <<endl;
cv::Vec<float,POSE_SIZE> err = (gt-g_means[0]);
//multiply(err,err,err);
for(int n=0;n<POSE_SIZE;++n)
err[n] = err[n]*err[n];
float h_err = sqrt(err[0]+err[1]+err[2]);
float a_err = sqrt(err[3]+err[4]+err[5]);
cout << "Head error : " << h_err << " mm " << endl;
cout << "Angle error : " << a_err <<" degrees " << endl;
pt2d_gt[0] = depth_intrinsic[0]*gt[0]/gt[2] + depth_intrinsic[2];
pt2d_gt[1] = depth_intrinsic[4]*gt[1]/gt[2] + depth_intrinsic[5];
}
pt2d_est[0] = depth_intrinsic[0]*g_means[0][0]/g_means[0][2] + depth_intrinsic[2];
pt2d_est[1] = depth_intrinsic[4]*g_means[0][1]/g_means[0][2] + depth_intrinsic[5];
}
return 0;
}
can anyone could tell me how to fix the problem?Thanks so much!
You should always read the readme.txt (here attached in head_pose_estimation.tgz) before testing an application:
To run the example code, type ./head_pose_estimation config.txt
data/frame_XXXX_depth.bin. The config.txt file contains all parameters
needed for the head pose estimation, e.g., the path to the forest, the
stride, and z threshold used to segment the person from the
background.
I'm having a problem with OpenCV and the Assertion failed error. It seems to be having a problem reading the image so the function imread() fails silently and then in resize() function it crashes because the input image is empty.
I've checked the path and it's ok, in fact if I print the path that I'm trying to read and do open path in a terminal image opens just fine. Also, if I take this path that I printed and put it in a string variable code works. So the problem seems to be with ss object. I just don't know what.
Here's my code:
int main(int argc, char** argv ){
cout << "Prueba OpenCV \n";
char* path;
Mat input;
if(argc >= 2 )
{
path = argv[1];
for(int j=0; j< numFiles; j++){
cout << "Character "<< OCR::strCharacters[1] << " file: " << j << "\n";
stringstream ss(stringstream::in | stringstream::out);
ss << path << OCR::strCharacters[1] << "/" << j << ".jpg" << "\n";
cout << "Character file: " << ss.str() << "\n";
Mat img=imread(ss.str(), 0);
/*if (img.cols == 0) {
cout << "Error reading file " << ss << endl;
return -1;
}*/
Mat lowData;
resize(img, lowData, Size(5, 5) );
}
}
}
run this with:
./PruebaOpenCV samples/
I found this link in stack that had a similar problem but the answer just was a piece of code to know if the image is properly read (commented code above). I know mine isn't but path is ok.
I have have the following problem:
When I drag and drop a file to my tool (exe) when ifstream fails to open the file.
If I give it manually though the console it works!
I don't get where the diffenence is, because I am cutting the path and passing just the filename.
Have a look at the code:
int main(int argc, char* argv[]) {
if (argc < 2) {
cout
<< "ERROR: Wrong amount of arguments! Give at least one argument ...\n"
<< endl;
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
exit(1);
return 0;
}
vector<string> files;
for (int g = 1; g < argc; g++) {
string s = argv[g];
cout<<"parameter at: " << g << " = " << argv[g] << "\n" << endl;
string filename = "";
int pos = s.find_last_of("\\", s.size());
if (pos != -1) {
filename.append(s.substr(pos + 1));
// cout<<" cutted path: " << s.substr(0,s.size()-filename.size()) << endl;
// cout << "argv[1] " << argv[1] << endl;
cout << "\n filename: " << filename << "\t pos: " << pos << endl;
files.push_back(filename);
}
files.push_back(s);
}
for (unsigned int k = 0; k < files.size(); k++)
{
cout << "files.at( " << k << " ): " << files.at(k).c_str() << endl;
Converter a(files.at(k).c_str());
a.getCommandsFromCSV();
a.saveConvertedFile();
}
cout << "\n" << "Programm finished...\n\n" << endl;
cin.ignore();
return 0;
}
It fails already on the constructor:
Converter::Converter(const char* file) {
filename = file;
myfile.open(filename.c_str(), ios_base::in);
cout << (myfile ? "open successful on constructor " : "some error on constructor");
cin.ignore();
trace_raw = "";
}
You have any idea why?
UPDATE:
The file as parameter works now. The solution was to leave the full path.
Anyway I have the same error on a hard coded file. I thought it may be the same that's why I added .\ at the beginning of the file name... without success.
The code:
void GenericCommandConverter::getATCommandsFromCSV() {
cout << "\t| +++++++++++getATCommandsFromCSV() started+++++++++++++ |"
<< endl;
/*
* CSV file name is hardcoded
*/
string filename_csv = ".\\test.csv";
string commands = "";
int pos_start = 0;
int pos_end = 0; // "|"
int substrLength = 0;
int separator_count = 0;
char c;
vector<string> lines;
vector<string> commandList;
vector<vector<string> > linesSeparated;
ifstream csvFile;
csvFile.open(filename_csv.c_str(), ios_base::in);
cout << (myfile ? "open successful on getATCommandsFromCSV " : "some error on getATCommandsFromCSV ");
cin.ignore();
...
UPDATE2:
The solution was: on dropping a file to the exe, the "root" folder changes to the one where the dropped file comes from. Giving the hardcoded file the path from the *.exe solved it!
I am guessing your current directory is wrong. Don't cut the path off. Anyway you should do error checking / debugging to see why it couldn't open the file. Diligent debugging is essential for solving problems without having to make blind guesses.