Commit 619dbe05 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Rotated bbox computation based on PCA.

        *  apps/CMakeLists.txt,
        *  apps/myriam/CMakeLists.txt,
        *  apps/myriam/getquad-cli.cpp,
        *  apps/myriam/getquad.hpp,
        *  apps/myriam/getquad.cpp: New.
parent 91659410
......@@ -12,3 +12,4 @@ add_subdirectory(tosgui)
add_subdirectory(saliency)
add_subdirectory(supervised-gui)
add_subdirectory(hierachical_seg-gui)
add_subdirectory(myriam)
add_executable(getquad-cli getquad-cli.cpp getquad.cpp)
target_link_libraries(getquad-cli ${FreeImage_LIBRARIES})
set_property(TARGET getquad-cli APPEND PROPERTY
INCLUDE_DIRECTORIES /lrde-work/groningen/carlinet/src/eigen/)
\ No newline at end of file
#include <mln/core/image/image2d.hpp>
#include <mln/io/imread.hpp>
#include "getquad.hpp"
int main(int argc, char** argv)
{
using namespace mln;
if (argc < 3) {
std::cerr << "Usage: " << argv[0] << " input(binary).tiff output.png\n";
std::exit(1);
}
image2d<bool> f;
io::imread(argv[1], f);
getquad(f, argv[2]);
}
#include "getquad.hpp"
#include <mln/accu/accumulators/covariance.hpp>
#include <mln/colors/literal.hpp>
#include <mln/core/algorithm/fill.hpp>
#include <mln/io/imsave.hpp>
#include <mln/accu/accumulators/infsup.hpp>
#include <mln/draw/range/line2d.hpp>
#include <Eigen/Dense>
pquad_t
getquad(const mln::image2d<bool>& bin,
const char* debug_filename)
{
using namespace mln;
Eigen::Array<double, 2, 2> COV;
Eigen::Array<double, 2, 2> P, Pinv;
// 1. Computee covariance matrix.
{
accu::accumulators::covariance<point2d, double, double> accu;
mln_foreach(auto px, bin.pixels())
if (px.val())
accu.take(px.point());
COV = accu.to_result();
}
// 2. Compute the eigen vectors
{
Eigen::SelfAdjointEigenSolver<Eigen::Matrix2d> eigensolver(COV.matrix());
if (eigensolver.info() != Eigen::Success)
std::abort();
P = eigensolver.eigenvectors();
Pinv = P.matrix().inverse();
// Debug
std::cout << "COV: \n" << COV << std::endl;
std::cout << "Lambdas: \n" << eigensolver.eigenvalues() << std::endl;
std::cout << "P: \n" << P << std::endl;
std::cout << "Pinv: \n" << Pinv << std::endl;
}
// 3. Compute the bbox
point2df pmin, pmax;
{
accu::accumulators::infsup<point2df> accu;
mln_foreach(auto px, bin.pixels())
if (px.val())
{
point2df p;
p[0] = P(0,0) * px.point()[0] + P(1,0) * px.point()[1];
p[1] = P(0,1) * px.point()[0] + P(1,1) * px.point()[1];
accu.take(p);
}
pmin = accu::extractor::inf(accu);
pmax = accu::extractor::sup(accu);
}
pquad_t res;
res.tl[0] = Pinv(0,0) * pmin[0] + Pinv(1,0) * pmin[1];
res.tl[1] = Pinv(0,1) * pmin[0] + Pinv(1,1) * pmin[1];
res.tr[0] = Pinv(0,0) * pmin[0] + Pinv(1,0) * pmax[1];
res.tr[1] = Pinv(0,1) * pmin[0] + Pinv(1,1) * pmax[1];
res.br[0] = Pinv(0,0) * pmax[0] + Pinv(1,0) * pmax[1];
res.br[1] = Pinv(0,1) * pmax[0] + Pinv(1,1) * pmax[1];
res.bl[0] = Pinv(0,0) * pmax[0] + Pinv(1,0) * pmin[1];
res.bl[1] = Pinv(0,1) * pmax[0] + Pinv(1,1) * pmin[1];
std::cout << res.tl << ","
<< res.tr << ","
<< res.br << ","
<< res.bl << std::endl;
if (debug_filename != NULL)
{
accu::accumulators::infsup<point2df> accu;
accu.take(bin.domain().pmin);
accu.take(bin.domain().pmax);
accu.take(res.tl);
accu.take(res.tr);
accu.take(res.bl);
accu.take(res.br);
box2d newdomain = { (point2d) accu::extractor::inf(accu),
(point2d) accu::extractor::sup(accu) };
image2d<rgb8> out(newdomain);
fill(out | where(bin), colors::literal::white);
fill(out | draw::line2d(res.tl, res.tr), colors::literal::red);
fill(out | draw::line2d(res.tr, res.br), colors::literal::red);
fill(out | draw::line2d(res.br, res.bl), colors::literal::red);
fill(out | draw::line2d(res.bl, res.tl), colors::literal::red);
io::imsave(out, debug_filename);
}
return res;
}
#ifndef APPS_SMARTDOC_GETQUAD_HPP
# define APPS_SMARTDOC_GETQUAD_HPP
# include <mln/core/image/image2d.hpp>
struct pquad_t
{
mln::point2df tl, tr, bl, br;
};
/// Return the best fitting quad in a binary image
/// \param[in] f The input image
/// \param[in] debug_filename (optional) Output the detected quad as an image.
/// \return The points in the order (top left, top right, bottom left, bottom right)
pquad_t
getquad(const mln::image2d<bool>& f,
const char* debug_filename = nullptr);
#endif // !APPS_SMARTDOC_GETQUAD_HPP
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment