paella/src/Skeleton/main.cpp

158 lines
5.6 KiB
C++

////////////////////////////////////////////////////////////////////////////////
//
// Paella
// Copyright (C) 2015 - Thomas FORGIONE, Emilie JALRAS, Marion LENFANT, Thierry MALON, Amandine PAILLOUX
// Authors :
// Thomas FORGIONE
// Emilie JALRAS
// Marion LENFANT
// Thierry MALON
// Amandine PAILLOUX
//
// This file is part of the project Paella
// This software is provided 'as-is', without any express or implied warranty.
// In no event will the authors be held liable for any damages arising from the use of this software.
//
// Permission is granted to anyone to use this software for any purpose,
// including commercial applications, and to alter it and redistribute it freely,
// subject to the following restrictions:
//
// 1. The origin of this software must not be misrepresented;
// you must not claim that you wrote the original software.
// If you use this software in a product, an acknowledgment
// in the product documentation would be appreciated but is not required.
//
// 2. Altered source versions must be plainly marked as such,
// and must not be misrepresented as being the original software.
//
// 3. This notice may not be removed or altered from any source distribution.
////////////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
#include <boost/program_options.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include "Skeleton/Skeleton.hpp"
#include "DetectionAndMatching/DetectionAndMatching.hpp"
// std::pair<bool, bool>
// first is true if program should continue
// second is true if there was an error
std::pair<bool, bool> parseArgs(int argc, char *argv[],
std::string& img1, std::string& img2,
std::string& mask1, std::string& mask2,
std::string& skl1, std::string& skl2,
std::string& output)
{
namespace po = boost::program_options;
try
{
po::options_description desc("Allowed options");
desc.add_options()
("help,h", "produce help message")
("img1", po::value<std::string>(), "first image (for the keypoints detection)")
("img2", po::value<std::string>(), "second image (for the keypoints detection)")
("mask1", po::value<std::string>(), "binary mask of the first image (to remove useless keypoints)")
("mask2", po::value<std::string>(), "binary mask of the second image")
("skl1", po::value<std::string>(), "first skeleton, and its branches")
("skl2", po::value<std::string>(), "second skeleton")
("output,o", po::value<std::string>(), "output file")
;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help"))
{
std::cout << desc << "\n";
return std::make_pair(false, true);
}
// Process parameters
if (vm.count("img1")) { img1 = vm["img1"].as<std::string>(); }
if (vm.count("img2")) { img2 = vm["img2"].as<std::string>(); }
if (vm.count("mask1")) { mask1 = vm["mask1"].as<std::string>(); }
if (vm.count("mask2")) { mask2 = vm["mask2"].as<std::string>(); }
if (vm.count("skl1")) { skl1 = vm["skl1"].as<std::string>(); }
if (vm.count("skl2")) { skl2 = vm["skl2"].as<std::string>(); }
}
catch (std::exception const& e)
{
std::cerr << "Unable to parse : "<< e.what() << std::endl;
return std::make_pair(false,false);
}
return std::make_pair(true,true);
}
int main(int argc, char *argv[])
{
std::string img1Name;
std::string img2Name;
std::string mask1Name;
std::string mask2Name;
std::string skl1Name;
std::string skl2Name;
std::string output;
auto pair = parseArgs(argc, argv, img1Name, img2Name, mask1Name, mask2Name, skl1Name, skl2Name, output);
if (!pair.second)
{
std::cerr << "Aborting" << std::endl;
return -1;
}
if (!pair.first)
{
return 0;
}
// Init skeletons and images
Skeleton skl1, skl2;
if(!skl1.loadFromFile(skl1Name))
{
std::cerr << "Unable to load skl file " << skl1Name << std::endl;
return -1;
}
if (!skl2.loadFromFile(skl2Name))
{
std::cerr << "Unable to load skl file " << skl2Name << std::endl;
return -1;
}
cv::Mat img1, img2, mask1, mask2;
img1 = cv::imread(img1Name, CV_LOAD_IMAGE_GRAYSCALE);
img2 = cv::imread(img2Name, CV_LOAD_IMAGE_GRAYSCALE);
mask1 = cv::imread(mask1Name, CV_LOAD_IMAGE_GRAYSCALE);
mask2 = cv::imread(mask2Name, CV_LOAD_IMAGE_GRAYSCALE);
if (img1.data == nullptr) { std::cerr << "Unable to load image " << img1Name << std::endl; return -1; }
if (img2.data == nullptr) { std::cerr << "Unable to load image " << img2Name << std::endl; return -1; }
if (mask1.data == nullptr) { std::cerr << "Unable to load image " << mask1Name << std::endl; return -1; }
if (mask2.data == nullptr) { std::cerr << "Unable to load image " << mask2Name << std::endl; return -1; }
std::ofstream file{output};
// Compute the keypoints
auto keypoints = detectAndMatch(img1, img2, mask1, mask2);
// Match the branches of skeletons
auto matching = branchesMatching(keypoints, skl1, skl2);
// Write to file
for (auto const& pair : matching)
file << "m " << pair.first << " " << pair.second << "\n";
return 0;
}