Commit 2b073932 authored by Edwin Carlinet's avatar Edwin Carlinet
Browse files

Smartdoc. Superimpose now uses the original video and draws the contour

of the document.

   *  apps/smartdoc/main2.cpp,
   *  apps/smartdoc/smartdoc.cpp,
   *  apps/smartdoc/smartdoc.hpp: New superimpose method.
parent 4d613b52
...@@ -191,8 +191,9 @@ private: ...@@ -191,8 +191,9 @@ private:
struct middle_filter_result struct middle_filter_result
{ {
mln::image2d<mln::rgb8> input;
mln::image2d<mln::uint16> depth; mln::image2d<mln::uint16> depth;
std::array<process_result_t, NQUAD> res; std::array<process_result_t, NQUAD> res;
}; };
...@@ -208,6 +209,9 @@ public: ...@@ -208,6 +209,9 @@ public:
// Process // Process
middle_filter_result* mdr = new middle_filter_result; middle_filter_result* mdr = new middle_filter_result;
mdr->input = std::move(*input);
delete input;
// if (VIDEO_OUTPUT) { // if (VIDEO_OUTPUT) {
// mln::box2d d; // mln::box2d d;
// d.pmin = {0,0}; // d.pmin = {0,0};
...@@ -221,12 +225,12 @@ public: ...@@ -221,12 +225,12 @@ public:
if (APP_METHOD == MTOS_METHOD) if (APP_METHOD == MTOS_METHOD)
{ {
tree = compute_ctos(*input, &(mdr->depth)); tree = compute_ctos(mdr->input, &(mdr->depth));
} }
else else
{ {
//std::array<process_result_t, NQUAD> resL, resB; //std::array<process_result_t, NQUAD> resL, resB;
//image2d< lab<float> > f = transform(*input, [](rgb8 x) { return rgb2lab(x); }); //image2d< lab<float> > f = transform(mdr->input, [](rgb8 x) { return rgb2lab(x); });
image2d<uint8> f; image2d<uint8> f;
property_map<tree_t, unsigned> vmap; property_map<tree_t, unsigned> vmap;
...@@ -238,7 +242,7 @@ public: ...@@ -238,7 +242,7 @@ public:
// 1st try on LAB_B // 1st try on LAB_B
{ {
f = transform(*input, [](rgb8 x) -> uint8 { f = transform(mdr->input, [](rgb8 x) -> uint8 {
lab<float> v = rgb2lab(x); lab<float> v = rgb2lab(x);
return (v[2] + 110) * 256 / 220; return (v[2] + 110) * 256 / 220;
}); });
...@@ -257,13 +261,12 @@ public: ...@@ -257,13 +261,12 @@ public:
APP_METHOD = ON_LAB_B; APP_METHOD = ON_LAB_B;
mdr->res = resB; mdr->res = resB;
my_mutex.unlock(); my_mutex.unlock();
delete input;
return mdr; return mdr;
} }
// 2nd try on LAB_L // 2nd try on LAB_L
{ {
f = transform(*input, [](rgb8 x) -> uint8 { f = transform(mdr->input, [](rgb8 x) -> uint8 {
lab<float> v = rgb2lab(x); lab<float> v = rgb2lab(x);
return v[0] * 256 / 100; return v[0] * 256 / 100;
}); });
...@@ -279,7 +282,6 @@ public: ...@@ -279,7 +282,6 @@ public:
APP_METHOD = ON_LAB_B; APP_METHOD = ON_LAB_B;
mdr->res = resB; mdr->res = resB;
my_mutex.unlock(); my_mutex.unlock();
delete input;
return mdr; return mdr;
} }
else if (resL[0].energy > 0.8) else if (resL[0].energy > 0.8)
...@@ -288,12 +290,11 @@ public: ...@@ -288,12 +290,11 @@ public:
APP_METHOD = ON_LAB_L; APP_METHOD = ON_LAB_L;
mdr->res = resL; mdr->res = resL;
my_mutex.unlock(); my_mutex.unlock();
delete input;
return mdr; return mdr;
} }
// 3. Backup // 3. Backup
{ {
f = transform(*input, [](rgb8 x) -> uint8 { f = transform(mdr->input, [](rgb8 x) -> uint8 {
lab<float> v = rgb2lab(x); lab<float> v = rgb2lab(x);
return (v[2] + 110) * 256 / 220; return (v[2] + 110) * 256 / 220;
}); });
...@@ -311,7 +312,6 @@ public: ...@@ -311,7 +312,6 @@ public:
std::cout << "==> Using the BACKUP method." << std::endl; std::cout << "==> Using the BACKUP method." << std::endl;
APP_METHOD = BACKUP_METHOD; APP_METHOD = BACKUP_METHOD;
my_mutex.unlock(); my_mutex.unlock();
delete input;
return mdr; return mdr;
} }
} }
...@@ -320,21 +320,21 @@ public: ...@@ -320,21 +320,21 @@ public:
my_mutex.unlock(); my_mutex.unlock();
if (APP_METHOD == ON_LAB_B) if (APP_METHOD == ON_LAB_B)
{ {
f = transform(*input, [](rgb8 x) -> uint8 { f = transform(mdr->input, [](rgb8 x) -> uint8 {
lab<float> v = rgb2lab(x); lab<float> v = rgb2lab(x);
return (v[2] + 110) * 256 / 220; return (v[2] + 110) * 256 / 220;
}); });
} }
else if (APP_METHOD == ON_LAB_L) else if (APP_METHOD == ON_LAB_L)
{ {
f = transform(*input, [](rgb8 x) -> uint8 { f = transform(mdr->input, [](rgb8 x) -> uint8 {
lab<float> v = rgb2lab(x); lab<float> v = rgb2lab(x);
return v[0] * 256 / 100; return v[0] * 256 / 100;
}); });
} }
else if (APP_METHOD == BACKUP_METHOD) else if (APP_METHOD == BACKUP_METHOD)
{ {
f = transform(*input, [](rgb8 x) -> uint8 { f = transform(mdr->input, [](rgb8 x) -> uint8 {
lab<float> v = rgb2lab(x); lab<float> v = rgb2lab(x);
return (v[2] + 110) * 256 / 220; return (v[2] + 110) * 256 / 220;
}); });
...@@ -352,7 +352,6 @@ public: ...@@ -352,7 +352,6 @@ public:
} }
mdr->res = process(tree, mdr->depth); mdr->res = process(tree, mdr->depth);
delete input;
return mdr; return mdr;
} }
...@@ -374,8 +373,11 @@ public: ...@@ -374,8 +373,11 @@ public:
&pFrame_outYUV, NULL, &Ctx_Enc); &pFrame_outYUV, NULL, &Ctx_Enc);
// Because the output image is in K0 + border // Because the output image is in K0 + border
short w = (Ctx_Dec->width + 2) * 2 - 1; // short w = (Ctx_Dec->width + 2) * 2 - 1;
short h = (Ctx_Dec->height + 2) * 2 - 1; // short h = (Ctx_Dec->height + 2) * 2 - 1;
short w = Ctx_Dec->width;
short h = Ctx_Dec->height;
pFrame_outRGB = avcodec_alloc_frame(); pFrame_outRGB = avcodec_alloc_frame();
av_image_alloc(pFrame_outRGB->data, av_image_alloc(pFrame_outRGB->data,
...@@ -393,7 +395,7 @@ public: ...@@ -393,7 +395,7 @@ public:
Ctx_Enc->pix_fmt, Ctx_Enc->pix_fmt,
SWS_BILINEAR, 0, 0, 0); SWS_BILINEAR, 0, 0, 0);
m_output.resize(mln::box2d{{0,0}, {h,w}}); m_output.resize(mln::box2d{{0,0}, {h,w}}, 5);
} }
m_filename = filename; m_filename = filename;
m_nbframe = 0; m_nbframe = 0;
...@@ -462,8 +464,9 @@ public: ...@@ -462,8 +464,9 @@ public:
{ {
// Copy the image to the output buffer. // Copy the image to the output buffer.
{ {
draw_quad_superimpose(quad, mdr->depth, m_output); //draw_quad_superimpose(quad, mdr->depth, m_output);
m_output = mdr->input;
draw_quad_superimpose(quad, m_output);
char* ptrin = (char*) &(m_output.at(0,0)); char* ptrin = (char*) &(m_output.at(0,0));
char* ptrout = (char*) pFrame_outRGB->data[0]; char* ptrout = (char*) pFrame_outRGB->data[0];
......
...@@ -6,9 +6,14 @@ ...@@ -6,9 +6,14 @@
#include <mln/accu/accumulators/max.hpp> #include <mln/accu/accumulators/max.hpp>
#include <mln/core/algorithm/transform.hpp> #include <mln/core/algorithm/transform.hpp>
#include <mln/core/algorithm/accumulate.hpp> #include <mln/core/algorithm/accumulate.hpp>
#include <mln/core/algorithm/fill.hpp>
#include <mln/morpho/component_tree/io.hpp> #include <mln/morpho/component_tree/io.hpp>
#include <mln/morpho/extinction.hpp> #include <mln/morpho/extinction.hpp>
#include <apps/tos/croutines.hpp> #include <apps/tos/croutines.hpp>
#include <mln/core/se/ball.hpp>
#include <mln/morpho/structural/gradient.hpp>
#include <mln/colors/literal.hpp>
static constexpr int EXTINCTION_THRESHOLD = 0.05; static constexpr int EXTINCTION_THRESHOLD = 0.05;
static constexpr int MINIMUM_ABSOLUTE_SIZE = 300000; // 500 * 500; // 400*400*4 static constexpr int MINIMUM_ABSOLUTE_SIZE = 300000; // 500 * 500; // 400*400*4
...@@ -62,6 +67,9 @@ namespace mln ...@@ -62,6 +67,9 @@ namespace mln
void take(point2d x) void take(point2d x)
{ {
using mln::inf;
using mln::sup;
m_pmin = inf(m_pmin, x); m_pmin = inf(m_pmin, x);
m_pmax = sup(m_pmax, x); m_pmax = sup(m_pmax, x);
...@@ -84,6 +92,9 @@ namespace mln ...@@ -84,6 +92,9 @@ namespace mln
void take(const fitting_quad& other) void take(const fitting_quad& other)
{ {
using mln::inf;
using mln::sup;
m_pmin = inf(m_pmin, other.m_pmin); m_pmin = inf(m_pmin, other.m_pmin);
m_pmax = sup(m_pmax, other.m_pmax); m_pmax = sup(m_pmax, other.m_pmax);
...@@ -411,3 +422,46 @@ draw_quad_superimpose(std::array<mln::point2d, 4> quad, ...@@ -411,3 +422,46 @@ draw_quad_superimpose(std::array<mln::point2d, 4> quad,
out(x)[0] += 128; out(x)[0] += 128;
} }
} }
void
draw_quad_superimpose(std::array<mln::point2d, 4> quad,
image2d<rgb8>& out)
{
vec2df u = (quad[1] - quad[0]).as_vec();
vec2df v = (quad[2] - quad[0]).as_vec();
vec2df w = (quad[3] - quad[0]).as_vec();
float n1 = (u[0]*v[1] - u[1]*v[0]);
float n2 = (w[0]*v[1] - w[1]*v[0]);
image2d<bool> bin;
// resize(bin, out).border(11);
bin.resize(out.domain(), 11, false);
//std::cout << "Border: " << bin.border() << std::endl;
mln_foreach(auto px, bin.pixels())
{
point2d x = 2 * (px.point() + 1);
vec2df p = x.as_vec() - quad[0].as_vec();
bool inside1, inside2;
{
float alpha = (u[0]*p[1] - u[1]*p[0]) / n1;
float beta = (p[0]*v[1] - p[1]*v[0]) / n1;
inside1 = 0 <= alpha and 0 <= beta and (alpha + beta) <= 1;
}
{
float alpha = (w[0]*p[1] - w[1]*p[0]) / n2;
float beta = (p[0]*v[1] - p[1]*v[0]) / n2;
inside2 = 0 <= alpha and 0 <= beta and (alpha + beta) <= 1;
}
px.val() = inside1 or inside2;
}
auto myse = se::make_ball2d(10);
bin = morpho::structural::external_gradient(bin, myse, productorder_less<bool>(), [](int x) -> bool { return x; });
fill(out | bin, colors::literal::red);
}
...@@ -59,6 +59,11 @@ draw_quad_superimpose(std::array<mln::point2d, 4> quad, ...@@ -59,6 +59,11 @@ draw_quad_superimpose(std::array<mln::point2d, 4> quad,
const mln::image2d<mln::uint16>& depth, const mln::image2d<mln::uint16>& depth,
mln::image2d<mln::rgb8>& out); mln::image2d<mln::rgb8>& out);
void
draw_quad_superimpose(std::array<mln::point2d, 4> quad,
mln::image2d<mln::rgb8>& out);
#endif // ! APPS_SMARTDOC_SMARTDOC_HPP #endif // ! APPS_SMARTDOC_SMARTDOC_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