I'm trying to import facial landmark points from webcam or video
using dlib into a file . I can display all detected landmarks on the terminal
but it is only saving the first and second landmark ponits (x,y) into the
output file , and not saving all the detected landmarks into
the output file
#include <dlib/opencv.h>
#include <opencv2/highgui/highgui.hpp>
#include <dlib/image_processing/frontal_face_detector.h>
#include <dlib/image_processing/render_face_detections.h>
#include <dlib/image_processing.h>
#include <dlib/gui_widgets.h>
using namespace dlib;
using namespace std;
int main()
{
try
{
cv::VideoCapture cap(0);
if (!cap.isOpened())
{
cerr << "Unable to connect to camera" << endl;
return 1;
}
image_window win;
frontal_face_detector detector = get_frontal_face_detector();
shape_predictor pose_model;
deserialize("shape_predictor_68_face_landmarks.dat") >> pose_model;
while(!win.is_closed())
{
// Grab a frame
cv::Mat temp;
cap >> temp;
cv_image<bgr_pixel> cimg(temp);
std::vector<rectangle> faces = detector(cimg);
std::vector<full_object_detection> shapes;
for (unsigned long i = 0; i < faces.size(); ++i)
{
full_object_detection shape = pose_model(cimg, faces[i]);
cout << "number of parts: "<< shape.num_parts() << endl;
cout << "pixel position of first part: " << shape.part(0) << endl;
cout << "pixel position of second part: " << shape.part(1) << endl;
shapes.push_back(pose_model(cimg, faces[i]));
const full_object_detection& d = shapes[0];
ofstream outputfile;
outputfile.open("data1.txt");
outputfile<< shape.part(0).x() << " " << shape.part(0).y() << endl;
outputfile<< shape.part(1).x() << " " << shape.part(1).y() << endl;
}
win.clear_overlay();
win.set_image(cimg);
win.add_overlay(render_face_detections(shapes));
}
}
catch(serialization_error& e)
{
cout << "You need dlib's default face landmarking model file to run this example." << endl;
cout << "You can get it from the following URL: " << endl;
cout << " http://dlib.net/files/shape_predictor_68_face_landmarks.dat.bz2" << endl;
cout << endl << e.what() << endl;
}
catch(exception& e)
{
cout << e.what() << endl;
}
}
Am I wrong or you want to save all landmarks when you have only:
ofstream outputfile;
outputfile.open("data1.txt");
outputfile<< shape.part(0).x() << " " << shape.part(0).y() << endl;
outputfile<< shape.part(1).x() << " " << shape.part(1).y() << endl;
And even not closing the file correctly. Try with for statement.
Related
Im trying to get working the Surface Matching Sample code from surface_matching. Im able to compile the code then when run with ./surface_matching /home/surface_matching/coke.ply /home/surface_matching/01.ply
Im running the same code sample as in the link. Code is the followving
#include "opencv2/surface_matching.hpp"
#include <iostream>
#include "opencv2/surface_matching/ppf_helpers.hpp"
#include "opencv2/core/utility.hpp"
using namespace std;
using namespace cv;
using namespace ppf_match_3d;
static void help(const string& errorMessage)
{
cout << "Program init error : "<< errorMessage << endl;
cout << "\nUsage : ppf_matching [input model file] [input scene file]"<< endl;
cout << "\nPlease start again with new parameters"<< endl;
}
int main(int argc, char** argv)
{
// welcome message
cout << "****************************************************" << endl;
cout << "* Surface Matching demonstration : demonstrates the use of surface matching"
" using point pair features." << endl;
cout << "* The sample loads a model and a scene, where the model lies in a different"
" pose than the training.\n* It then trains the model and searches for it in the"
" input scene. The detected poses are further refined by ICP\n* and printed to the "
" standard output." << endl;
cout << "****************************************************" << endl;
if (argc < 3)
{
help("Not enough input arguments");
exit(1);
}
#if (defined __x86_64__ || defined _M_X64)
cout << "Running on 64 bits" << endl;
#else
cout << "Running on 32 bits" << endl;
#endif
#ifdef _OPENMP
cout << "Running with OpenMP" << endl;
#else
cout << "Running without OpenMP and without TBB" << endl;
#endif
string modelFileName = (string)argv[1];
string sceneFileName = (string)argv[2];
Mat pc = loadPLYSimple(modelFileName.c_str(), 1);
// Now train the model
cout << "Training..." << endl;
int64 tick1 = cv::getTickCount();
ppf_match_3d::PPF3DDetector detector(0.025, 0.05);
detector.trainModel(pc);
int64 tick2 = cv::getTickCount();
cout << endl << "Training complete in "
<< (double)(tick2-tick1)/ cv::getTickFrequency()
<< " sec" << endl << "Loading model..." << endl;
// Read the scene
Mat pcTest = loadPLYSimple(sceneFileName.c_str(), 1);
// Match the model to the scene and get the pose
cout << endl << "Starting matching..." << endl;
vector<Pose3DPtr> results;
tick1 = cv::getTickCount();
// orig detector.match(pcTest, results, 1.0/40.0, 0.05);
detector.match(pcTest, results, 1.0/40.0, 0.05);
tick2 = cv::getTickCount();
cout << endl << "PPF Elapsed Time " <<
(tick2-tick1)/cv::getTickFrequency() << " sec" << endl;
// Get only first N results
int N = 2;
vector<Pose3DPtr> resultsSub(results.begin(),results.begin()+N);
// Create an instance of ICP
ICP icp(100, 0.005f, 2.5f, 8);
int64 t1 = cv::getTickCount();
// Register for all selected poses
cout << endl << "Performing ICP on " << N << " poses..." << endl;
icp.registerModelToScene(pc, pcTest, resultsSub);
int64 t2 = cv::getTickCount();
cout << endl << "ICP Elapsed Time " <<
(t2-t1)/cv::getTickFrequency() << " sec" << endl;
cout << "Poses: " << endl;
// debug first five poses
for (size_t i=0; i<resultsSub.size(); i++)
{
Pose3DPtr result = resultsSub[i];
cout << "Pose Result " << i << endl;
result->printPose();
if (i==0)
{
Mat pct = transformPCPose(pc, result->pose);
writePLY(pct, "para6700PCTrans.ply");
}
}
return 0;
}
It runs but never gets any results. I got this error
$ ./surface_matching /home/admini/surface_matching/coke.ply /home/admini/surface_matching/01.ply
****************************************************
* Surface Matching demonstration : demonstrates the use of surface matching using point pair features.
* The sample loads a model and a scene, where the model lies in a different pose than the training.
* It then trains the model and searches for it in the input scene. The detected poses are further refined by ICP
* and printed to the standard output.
****************************************************
Running on 64 bits
Running without OpenMP and without TBB
Training...
Training complete in 0.100169 sec
Loading model...
Starting matching...
Segmentation fault (core dumped)
Training is complete and starts matching but then Segmentation fault. What can be the problem? Here the object model file:
And the scene file
What can be the problem?
Though this is a fairly simple question, I am having trouble opening the file through the inputFileStream(inputFilePath). Could someone just lead me in the correct direction (I'm not here to be given answers for a school assignment)?
#include <cmath>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
using namespace std;
const string ID_LINE = "James McMillan - CS 1336 050 - Assignment 26";
int main(int argc, char *argv[]) {
cout << ID_LINE << endl << endl;
// guard clause - invalid number of arguments
if (argc != 3) {
cout << "Usage: " << argv[0] << "<input file path> <output file path>" << endl;
return 1;
}
//extract arguments
string programPath = argv[0];
string inputFilePath = argv[1];
string outputFilePath = argv[2];
cout << "Program path: " << programPath << endl;
cout << "Input file path: " << inputFilePath << endl;
cout << "Output file path: " << outputFilePath << endl << endl;
cout << "Creating input file stream..." << endl;
ifstream inputFileStream;
cout << "Created input file stream." << endl;
cout << "Opening input file stream: " << inputFilePath << endl;
inputFileStream.open(inputFilePath);
if (!inputFileStream.is_open()) {
cout << "Unable to open input file stream: " << inputFilePath << endl;
return 1;
}
}
Your solution might come from checking if the file exists, try
//Add this at the top
#include <experimental/filesystem>
//somewhere in the body
const auto has_the_file = std::experimental::filesystem::exists(inputFilePath);
if (!has_the_file)
{
std::cout << "Oh No! Can't find" << inputFilePath << std::endl;
}
Also instead of parsing the arguments, I would manually set the paths to confirm your expectations on how to specify file paths.
I have a problem with file handling. More precisely I've written a code for exercising but after a time it won't make the .txt file.
I don't know if the error is my computer or my code but I hope someone knows the answer.
It's not the final stage but the problem started here.
(This is a simple console application)
#include <iostream>
#include <string>
#include <fstream>
using namespace std;
int Counter()
{
static int taskID;
cout << taskID++ << " - ";
}
int main(int argc, char const *argv[])
{
char inputTask[256];
string outputTask;
string listAllTask = "-l";
string addNewTask = "-a";
string removeTask = "-r";
string completeTask = "-c";
if (argc == 1) {
cout << "CLI Todo application" << endl;
cout << "====================\n" << endl;
cout << "Command line arguments:" << endl;
cout << "-l Lists all the tasks" << endl;
cout << "-a Adds a new task" << endl;
cout << "-r Removes a task" << endl;
cout << "-c Completes an task" << endl;
} else if (argc == 2) {
//create an object to access the file that containing the tasks
fstream todoApp("tasks.txt", ios::ate | ios::in | ios::out);
if (todoApp.is_open()) {
if (string(argv[1]) == listAllTask){
while (!todoApp.eof()) {
todoApp.seekg(0, ios::end);
if (todoApp.tellg() == 0) {
cout << "No todos for today! :)" << endl;
} else {
getline(todoApp, outputTask);
cout << Counter << outputTask << endl;
}
}
} else if (string(argv[1]) == addNewTask) {
cout << "Enter the new todo:" << endl;
todoApp.seekg(0, ios::end);
cin.getline(inputTask, 120);
todoApp << inputTask << endl;
todoApp.close();
cout << "-- your task has been saved --" << endl;
}
} else {
cerr << "Something went wrong, please, try again." << endl;
}
//todoApp.close();
} else {
cout << "Too many arguments!!!" << endl;
}
return 0;
}
I am studying 3d point cloud and I am using opencv surface matchig module But I have an error I cant understand
My code is :
#include "stdafx.h"
#include <iostream>
#include <vector>
#include "opencv2/core/utility.hpp"
#include "opencv2\opencv_modules.hpp"
#include "opencv2\surface_matching.hpp"
#include "opencv2\surface_matching\ppf_helpers.hpp"
using namespace std;
using namespace cv;
using namespace cv::ppf_match_3d;
static void help(const string& errorMessage)
{
cout << "Program init error : " << errorMessage << endl;
cout << "\nUsage : ppf_matching [input model file] [input scene file]" << endl;
cout << "\nPlease start again with new parameters" << endl;
}
int main(int argc, char** argv)
{
// welcome message
cout << "****************************************************" << endl;
cout << "* Surface Matching demonstration : demonstrates the use of surface matching"
" using point pair features." << endl;
cout << "* The sample loads a model and a scene, where the model lies in a different"
" pose than the training.\n* It then trains the model and searches for it in the"
" input scene. The detected poses are further refined by ICP\n* and printed to the "
" standard output." << endl;
cout << "****************************************************" << endl;
/* if (argc < 2)
{
help("Not enough input arguments");
exit(1);
}*/
/*#if (defined __x86_64__ || defined _M_X64)
cout << "Running on 64 bits" << endl;
#else
cout << "Running on 32 bits" << endl;
#endif
#ifdef _OPENMP
cout << "Running with OpenMP" << endl;
#else
cout << "Running without OpenMP and without TBB" << endl;
#endif*/
string modelFileName = "C://opencv_contrib-master//modules//surface_matching//samples//data//parasaurolophus_6700";
string sceneFileName = "C://opencv_contrib-master//modules//surface_matching//samples//data//parasaurolophus_low_normals2";
Mat pc = loadPLYSimple(modelFileName.c_str(), 1);
// Now train the model
cout << "Training..." << endl;
int64 tick1 = cv::getTickCount();
ppf_match_3d::PPF3DDetector detector(0.025, 0.05);
detector.trainModel(pc);
int64 tick2 = cv::getTickCount();
cout << endl << "Training complete in "
<< (double)(tick2 - tick1) / cv::getTickFrequency()
<< " sec" << endl << "Loading model..." << endl;
// Read the scene
Mat pcTest = loadPLYSimple(sceneFileName.c_str(), 1);
// Match the model to the scene and get the pose
cout << endl << "Starting matching..." << endl;
vector<Pose3DPtr> results;
tick1 = cv::getTickCount();
detector.match(pcTest, results, 1.0 / 40.0, 0.05);
tick2 = cv::getTickCount();
cout << endl << "PPF Elapsed Time "
<< (tick2 - tick1) / cv::getTickFrequency() << " sec" << endl;
// Get only first N results
int N = 2;
vector<Pose3DPtr> resultsSub(results.begin(), results.begin() + N);
// Create an instance of ICP
ICP icp(100, 0.005f, 2.5f, 8);
int64 t1 = cv::getTickCount();
// Register for all selected poses
cout << endl << "Performing ICP on " << N << " poses..." << endl;
icp.registerModelToScene(pc, pcTest, resultsSub);
int64 t2 = cv::getTickCount();
cout << endl << "ICP Elapsed Time "
<< (t2 - t1) / cv::getTickFrequency() << " sec" << endl;
cout << "Poses: " << endl;
// debug first five poses
for (size_t i = 0; i<resultsSub.size(); i++)
{
Pose3DPtr result = resultsSub[i];
cout << "Pose Result " << i << endl;
result->printPose();
if (i == 0)
{
Mat pct = transformPCPose(pc, result->pose);
writePLY(pct, "para6700PCTrans.ply");
}
}
return 0;
}
And my error :(when code was these line :
detector.trainModel(pc);
int64 tick2 = cv::getTickCount();
I get this error:
Use debug mode. Change Key type at t_hash_int.cpp source file by these lines
#if (defined x86_64 || defined _M_X64)
typedef uint64_t KeyType;
#else
typedef unsigned int KeyType;
#endif
Build again from the source
Check this issue: https://github.com/opencv/opencv_contrib/issues/170
It seems that you use the release mode to run the program.
I have meet this problem before. When I change to debug mode. Everything works well.
I'm trying to simple load an image (TIFF) and display a pixel value.
If I open the image using ImageJ the values are 32-bit float. But opening the same image using opencv I get really strange float values, e.g. 4.2039e-44.
If I read the value of a specific pixel using "int" the presented value is correct. Below is the code I use to test. And here a link for the image: https://goo.gl/Wmv9xE.
Thanks in advance.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <iostream>
int main(int argc, char **argv) {
std::string imageFile = "image.tiff";
cv::Mat image;
image = cv::imread(imageFile, CV_LOAD_IMAGE_ANYDEPTH); // Read the file
if (!image.data) // Check for invalid input
{
std::cout << "Could not open or find the image: " << imageFile << std::endl;
return -1;
}
std::cout << "Image:" << image.rows << " x " << image.cols << " Channels: " << image.channels() << " Depth: " << image.depth() << std::endl;
std::cout << "Value at 0,0: " << image.at<float>(0,1)<< std::endl; // Strange Value
std::cout << "Value at 0,0: " << image.at<int>(0,1)<< std::endl; // Correct Value
return (EXIT_SUCCESS);
}
* Update *
Trying to move forward with the code, I decided to create a function to convert the data to "int" reading from the file.
As a temporary solution this worked, but I'm still looking for the reason why the data is being loaded wrong.
int main(int argc, char **argv) {
std::string imageFile = "/home/slepicka/XSConfig/image.tiff";
cv::Mat image = openImage(imageFile);
if (!image.data) // Check for invalid input
{
std::cout << "Could not open or find the image: " << imageFile << std::endl;
return -1;
}
std::cout << "Image:" << image.rows << " x " << image.cols << " Channels: " << image.channels() << " Depth: " << image.depth() << " Type: " << image.type() << std::endl;
std::cout << "Value at 0,0: " << image.at<int>(0,1)<< std::endl; // Correct Value
//std::cout << "Data: " << image << std::endl;
return (EXIT_SUCCESS);
}
cv::Mat openImage(std::string filename){
cv::Mat imageLoad = cv::imread(filename, CV_LOAD_IMAGE_ANYDEPTH);
if(imageLoad.type() == CV_32F){
return convertToInt(imageLoad);
}
return imageLoad;
}
cv::Mat convertToInt(cv::Mat source){
int r, c;
cv::Mat converted;
converted.create(source.rows, source.cols, CV_32SC1);
for (r=0; r<source.rows;r++) {
for (c=0; c<source.cols;c++) {
converted.at<int>(r, c) = source.at<int>(r, c);
}
}
return converted;
}