Commit b57d26e9 authored by green's avatar green Committed by Yann Jacquelet
Browse files

Fix last details in the image processing chain.

	* green/tools/annotating/histo/histo.cc: Manage new inputs/outputs.
	* green/tools/annotating/opening/opening.cc: Manage new inputs/outputs.
	* green/tools/annotating/iz/Makefile.am: New Makefile.
	* green/tools/annotating/iz/iz.cc: New file.
	* green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs.
parent 17304c0d
......@@ -75,6 +75,16 @@
* bin/pgm_to_pbm.cc,
* bin/ppm_negate.cc: New.
2010-02-10 Yann Jacquelet <jacquelet@lrde.epita.fr>
Fix last details in the image processing chain.
* green/tools/annotating/histo/histo.cc: Manage new inputs/outputs.
* green/tools/annotating/opening/opening.cc: Manage new inputs/outputs.
* green/tools/annotating/iz/Makefile.am: New Makefile.
* green/tools/annotating/iz/iz.cc: New file.
* green/tools/annotating/regmax/regmax.cc: Manage new inputs/outputs.
2010-01-05 Yann Jacquelet <jacquelet@lrde.epita.fr>
Extend the histogram visualization tools for new projection concept.
......
......@@ -16,14 +16,14 @@
#include <mln/fun/v2v/rgb8_to_rgbn.hh>
#include <mln/io/dump/save.hh>
#include <mln/io/pbm/load.hh>
#include <mln/io/pbm/save.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
#include <mln/io/ppm/load.hh>
#include <mln/io/dump/save.hh>
#include <mln/io/pgm/save.hh>
#include <mln/io/ppm/save.hh>
#include <mln/literal/colors.hh>
#include <mln/opt/at.hh>
#include <mln/pw/value.hh>
......@@ -33,15 +33,19 @@
template <unsigned n>
void mk_histo(const std::string& input,
const std::string& output,
const std::string& histo,
const std::string& mask)
void mk_histo(const std::string& input, // in
const std::string& quant, // in
const std::string& histo, // out
const std::string& proj1, // out
const std::string& proj2, // out
const std::string& mask) // [in]
{
typedef mln::value::int_u8 t_int_u8;
typedef mln::value::int_u<n> t_int_un;
typedef mln::value::rgb8 t_rgb8;
typedef mln::value::rgb<n> t_rgbn;
typedef mln::image2d<t_int_u8> t_image2d_int_u8;
typedef mln::image2d<t_int_un> t_image2d_int_un;
typedef mln::image2d<t_rgb8> t_image2d_rgb8;
typedef mln::image2d<t_rgbn> t_image2d_rgbn;
typedef mln::image2d<bool> t_image2d_bool;
......@@ -54,7 +58,9 @@ void mk_histo(const std::string& input,
t_image2d_rgbn i1_input; // input rgbn
t_image2d_bool m0_input; // mask input
t_histo3d h1_input; // histo input
t_image2d_int_u8 p1_histo; // histo proj
t_image2d_int_u8 p1_histo1;// histo proj1
t_image2d_rgbn p1_histo2;// histo proj2
t_rgbn red(mln::literal::red);
mln::io::ppm::load(i0_input, input.c_str());
i1_input = mln::data::transform(i0_input, t_rgb8_to_rgbn());
......@@ -72,9 +78,13 @@ void mk_histo(const std::string& input,
// END OF IMAGE PROCESSING CHAIN
// BEGIN DUMPING
p1_histo = mln::display::display_histo3d_unsigned(h1_input);
p1_histo1 = mln::display::display_histo3d_unsigned(h1_input);
p1_histo2 = mln::display::display3_histo3d_unsigned(h1_input, red);
mln::io::ppm::save(i1_input, quant.c_str());
mln::io::dump::save(h1_input, histo.c_str());
mln::io::pgm::save(p1_histo, output.c_str());
mln::io::pgm::save(p1_histo1, proj1.c_str());
mln::io::ppm::save(p1_histo2, proj2.c_str());
// END DUMPING
}
......@@ -82,35 +92,47 @@ void mk_histo(const std::string& input,
void usage()
{
std::cout << std::endl;
std::cout << "histo input.ppm q out.ppm histo.dump [msk.pbm]" << std::endl;
std::cout << "where" << std::endl;
std::cout << "input.ppm is the 8 bits color ppm image" << std::endl;
std::cout << "q is the degree of quanification {2,3,4,5,6,7,8}" << std::endl;
std::cout << "out.pgm is the r/g projection of the histogram" << std::endl;
std::cout << "out.dump is the quantified color histogram" << std::endl;
std::cout << "msk.pbm is the mask which select the pixels" << std::endl;
std::cout << "histo input.ppm q quant.ppm histo.dump proj.pgm"
<< " proj.ppm [msk.pbm]" << std::endl;
std::cout << std::endl;
std::cout << "where :" << std::endl;
std::cout << "* [ in] input.ppm is the 8 bits color ppm image" << std::endl;
std::cout << "* [ in] q is the degree of quantification"
<< " {2,3,4,5,6,7,8}" << std::endl;
std::cout << "* [out] quant.ppm is the q bits quantified input"
<< " image" << std::endl;
std::cout << "* [out] histo.dump is the quantified color"
<< " histogram" << std::endl;
std::cout << "* [out] proj.pgm is the r/g projection of the"
<< " histogram (summing along the blue axe)" << std::endl;
std::cout << "* [out] proj.ppm is the r/g projection of the"
<< " histogram with maxima plot on" << std::endl;
std::cout << "* [ in] msk.pbm is the mask which selects the"
<< " pixels" << std::endl;
std::cout << std::endl;
}
int main(int argc, char* args[])
{
if (5 == argc || 6 == argc)
if (7 == argc || 8 == argc)
{
const std::string input(args[1]);
const char q = args[2][0];
const std::string output(args[3]);
const std::string histo(args[4]);
const std::string mask(6 == argc? args[5] : "");
const std::string input(args[1]); // in
const char q = args[2][0]; // in
const std::string quant(args[3]); // out
const std::string histo(args[4]); // out
const std::string proj1(args[5]); // out
const std::string proj2(args[6]); // out
const std::string mask(8 == argc? args[7] : ""); // [in]
switch(q)
{
case '2': mk_histo<2>(input, output, histo, mask); break;
case '3': mk_histo<3>(input, output, histo, mask); break;
case '4': mk_histo<4>(input, output, histo, mask); break;
case '5': mk_histo<5>(input, output, histo, mask); break;
case '6': mk_histo<6>(input, output, histo, mask); break;
case '7': mk_histo<7>(input, output, histo, mask); break;
case '8': mk_histo<8>(input, output, histo, mask); break;
case '2': mk_histo<2>(input, quant, histo, proj1, proj2, mask); break;
case '3': mk_histo<3>(input, quant, histo, proj1, proj2, mask); break;
case '4': mk_histo<4>(input, quant, histo, proj1, proj2, mask); break;
case '5': mk_histo<5>(input, quant, histo, proj1, proj2, mask); break;
case '6': mk_histo<6>(input, quant, histo, proj1, proj2, mask); break;
case '7': mk_histo<7>(input, quant, histo, proj1, proj2, mask); break;
case '8': mk_histo<8>(input, quant, histo, proj1, proj2, mask); break;
default: usage(); break;
}
}
......
#
# Generic Makefile
#
#########
# TOOLS #
#########
INCLUDES= -I$(HOME)/svn/oln/trunk/milena/sandbox/green
#CXXFLAGS= -ggdb -O0 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
#CXXFLAGS= -DNDEBUG -O1 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
CXXFLAGS= -DNDEBUG -O3 -Wall -W -pedantic -ansi -pipe $(INCLUDES)
ECHO= echo
RM= rm
MKDIR= mkdir -p
CP= cp
SOURCE_PATTERN= green/tools
BUILD__PATTERN= green/build/tools
ifeq ($(findstring $(BUILD__PATTERN),$(PWD)), $(BUILD__PATTERN))
# Case where make is done from build directory.
SOURCE_DIR= $(subst $(BUILD__PATTERN),$(SOURCE_PATTERN),$(PWD))
BUILD__DIR= $(PWD)
else
# Case where make is done from source directory.
SOURCE_DIR= $(PWD)
BUILD__DIR= $(subst $(SOURCE_PATTERN),$(BUILD__PATTERN),$(PWD))
endif
SRC= $(notdir $(wildcard $(SOURCE_DIR)/*.cc))
OLD= $(notdir $(wildcard $(SOURCE_DIR)/*~))
OBJ= $(patsubst %.cc,%.o,$(SRC))
SOURCE_MAKEFILE=Makefile.am
BUILD__MAKEFILE=Makefile
TARGET_FILE= $(notdir $(PWD))
SOURCE_FILES= $(notdir $(wildcard $(SOURCE_DIR)/*.*))
BUILD__FILES= $(filter-out $(SRC) $(SOURCE_MAKEFILE), $(SOURCE_FILES))
BUILD__F_PATH= $(addprefix $(BUILD__DIR)/,$(BUILD__FILES))
SOURCE_F_PATH= $(addprefix $(SOURCE_DIR)/,$(SOURCE_FILES))
BUILD__M_PATH= $(addprefix $(BUILD__DIR)/,$(BUILD__MAKEFILE))
SOURCE_M_PATH= $(addprefix $(SOURCE_DIR)/,$(SOURCE_MAKEFILE))
TARGET_F_PATH= $(addprefix $(BUILD__DIR)/,$(TARGET_FILE))
OBJ_F_PATH= $(addprefix $(BUILD__DIR)/,$(OBJ))
SRC_F_PATH= $(addprefix $(SOURCE_DIR)/,$(SRC))
OLD_F_PATH= $(addprefix $(SOURCE_DIR)/,$(OLD))
#############
# BOOTSTRAP #
#############
bootstrap: $(BUILD__DIR) $(BUILD__F_PATH) $(BUILD__M_PATH)
# Create, if nessary, the destination directory
$(BUILD__DIR):
$(MKDIR) $(BUILD__DIR)
# Copy, if nessary, all the files, except the Makefile.am
$(BUILD__F_PATH): $(SOURCE_F_PATH)
$(CP) $(addprefix $(SOURCE_DIR),$(@F)) $@
# Copy if nessary, the Makefile.am into Makefile
$(BUILD__M_PATH): $(SOURCE_M_PATH)
$(CP) $(SOURCE_M_PATH) $(BUILD__M_PATH)
#######
# ALL #
#######
# We assume that the call is done from the build directory.
# With the directive vpath, hidden files are found in the source directory.
all: $(TARGET_F_PATH)
$(TARGET_F_PATH): $(OBJ_F_PATH)
$(LINK.cc) $< $(LOADLIBES) $(LDLIBS) -o $@
$(OBJ_F_PATH):$(SRC_F_PATH)
$(COMPILE.cc) $(OUTPUT_OPTION) $<
#########
# CLEAN #
#########
# Force every time the deletion
clean: clean_target clean_obj clean_dst clean_old #clean_make
clean_target:
-@$(RM) $(TARGET_F_PATH) &> /dev/null
clean_obj:
-@$(RM) $(OBJ_F_PATH) &> /dev/null
clean_dst:
-@$(RM) $(BUILD_F_PATH) &> /dev/null
clean_make:
-@$(RM) $(BUILD_M_PATH) &> /dev/null
clean_old:
-@$(RM) $(OLD_F_PATH) &> /dev/null
#########
# PRINT #
#########
print: print_tools print_bootstrap
print_tools:
@$(ECHO) "HOME = $(HOME)"
@$(ECHO) "INCLUDES = $(INCLUDES)"
@$(ECHO) "CXXFLAGS = $(CXXFLAGS)"
@$(ECHO) "ECHO = $(ECHO)"
@$(ECHO) "RM = $(RM)"
@$(ECHO) "MKDIR = $(MKDIR)"
@$(ECHO) "CP = $(CP)"
@$(ECHO)
print_bootstrap:
@$(ECHO) "PWD = $(PWD)"
@$(ECHO) "SOURCE_PATTERN = $(SOURCE_PATTERN)"
@$(ECHO) "BUILD__PATTERN = $(BUILD__PATTERN)"
@$(ECHO) "SOURCE_DIR = $(SOURCE_DIR)"
@$(ECHO) "BUILD__DIR = $(BUILD__DIR)"
@$(ECHO) "SOURCE_MAKEFILE = $(SOURCE_MAKEFILE)"
@$(ECHO) "BUILD__MAKEFILE = $(BUILD__MAKEFILE)"
@$(ECHO) "TARGET_FILE = $(TARGET_FILE)"
@$(ECHO) "SOURCE_FILES = $(SOURCE_FILES)"
@$(ECHO) "SOURCE_F_PATH = $(SOURCE_F_PATH)"
@$(ECHO) "BUILD__FILES = $(BUILD__FILES)"
@$(ECHO) "BUILD__F_PATH = $(BUILD__F_PATH)"
@$(ECHO) "BUILD__M_PATH = $(BUILD__M_PATH)"
@$(ECHO) "SOURCE_M_PATH = $(SOURCE_M_PATH)"
@$(ECHO) "SRC = $(SRC)"
@$(ECHO) "OBJ = $(OBJ)"
@$(ECHO) "OLD = $(OLD)"
@$(ECHO) "SRC_F_PATH = $(SRC_F_PATH)"
@$(ECHO) "OBJ_F_PATH = $(OBJ_F_PATH)"
@$(ECHO) "OLD_F_PATH = $(OLD_F_PATH)"
@$(ECHO)
// TOOLS ==> influence zone transformation
#include <iostream>
#include <fstream>
#include <boost/format.hpp>
#include <mln/accu/stat/histo3d_rgb.hh>
#include <mln/core/macros.hh>
#include <mln/core/alias/neighb3d.hh>
#include <mln/core/image/image2d.hh>
#include <mln/core/image/image3d.hh>
#include <mln/data/compute.hh>
#include <mln/display/display_histo.hh>
#include <mln/io/dump/load.hh>
#include <mln/io/dump/save.hh>
#include <mln/io/ppm/load.hh>
#include <mln/io/ppm/save.hh>
#include <mln/io/pgm/load.hh>
#include <mln/io/pgm/save.hh>
#include <mln/literal/colors.hh>
#include <mln/labeling/compute.hh>
#include <mln/labeling/mean_values.hh>
#include <mln/transform/influence_zone_geodesic.hh>
#include <mln/value/int_u8.hh>
template <unsigned n>
struct t_labeling_rgbn : mln::Function_v2v< t_labeling_rgbn<n> >
{
typedef mln::value::rgb<n> t_rgbn;
typedef mln::value::label_8 t_lbl8;
typedef t_rgbn argument;
typedef t_lbl8 result;
typedef mln::image3d<t_lbl8> t_label;
const t_label& _label;
t_labeling_rgbn(const t_label& label) : _label(label) {}
result operator()(const argument& c) const
{
t_lbl8 tmp = mln::opt::at(_label, c.blue(), c.red(), c.green());
return tmp;
}
};
void compute_stats(const mln::image2d<mln::value::rgb8>& i_input_rgb8,
const mln::image2d<mln::value::label_8>& l_input_lbl8,
const mln::image3d<unsigned>& h_histo_rgbn,
const mln::image3d<mln::value::label_8>& l_histo_lbl8,
const mln::value::label_8& n_labels,
const std::string& log)
{
typedef mln::algebra::vec<3,float> t_vec3f;
typedef mln::accu::math::sum<unsigned,unsigned> t_sum;
typedef mln::accu::stat::mean<t_vec3f,t_vec3f,t_vec3f> t_mean;
typedef mln::util::array<unsigned> t_count_array;
typedef mln::util::array<t_vec3f> t_mean_array;
mln::util::array<float> abs((unsigned)(n_labels)+1);
mln::util::array<float> rel((unsigned)(n_labels)+1);
unsigned nb = 0;
for (unsigned i = 0; i <= n_labels; ++i)
{
abs[i] = 0.0;
rel[i] = 0.0;
}
// COMPUTE THE SUM
t_count_array count = mln::labeling::compute(t_sum(),
h_histo_rgbn,
l_histo_lbl8,
n_labels);
// COMPUTE THE TOTAL
for (unsigned i = 0; i <= n_labels; ++i)
{
unsigned c = count[i];
nb += c;
}
// COMPUTE THE PERCENTAGES
for (unsigned i = 0; i <= n_labels; ++i)
if (0 < count[i])
{
abs[i] = ((float)count[i] / nb)*100.0;
rel[i] = ((float)count[i] / (nb - count[0]))*100.0;
}
// COMPUTE THE MEAN
t_mean_array mean = mln::labeling::compute(t_mean(),
i_input_rgb8,
l_input_lbl8,
n_labels);
// CORRECT 0 LABEL STATS
rel[0] = 0;
mean[0][0] = 255.0;
mean[0][1] = 255.0;
mean[0][2] = 0.0;
// PRINT STATS
std::ofstream log_stream(log.c_str());
for (unsigned i = 0; i <= n_labels; ++i)
{
const t_vec3f& mean_v = mean[i];
log_stream << boost::format("%2i|"
"r = %6.2f, g = %6.2f, b = %6.2f |"
"c = %7i, %%i = %5.2f, %%c = %5.2f")
% i
% mean_v[0]
% mean_v[1]
% mean_v[2]
% count[i]
% abs[i]
% rel[i]
<< std::endl;
}
log_stream << std::endl << std::endl;
log_stream.flush();
log_stream.close();
}
bool expect(std::istream& stream, const std::string expected)
{
bool result;
std::string got;
stream >> got;
result = (got == expected);
return result;
}
std::istream& operator>>(std::istream& stream,
mln::algebra::vec<3,float>& color)
{
unsigned lbl;
stream >> lbl;
if (expect(stream, std::string("|")) &&
expect(stream, std::string("r")) &&
expect(stream, std::string("=")))
{
stream >> color[0];
if (expect(stream, std::string(",")) &&
expect(stream, std::string("g")) &&
expect(stream, std::string("=")))
{
stream >> color[1];
if (expect(stream, std::string(",")) &&
expect(stream, std::string("b")) &&
expect(stream, std::string("=")))
{
stream >> color[2];
}
}
}
return stream;
}
void load(mln::util::array< mln::algebra::vec<3,float> >& m2_label,
const char *colormap)
{
typedef mln::algebra::vec<3,float> t_vec3f;
typedef mln::util::array<t_vec3f> t_mean_array;
std::ifstream stream(colormap);
std::string buffer;
getline(stream, buffer);
while (0 < buffer.size())
{
std::stringstream line(buffer);
t_vec3f mean_v;
line >> mean_v;
m2_label.append(mean_v);
getline(stream, buffer);
}
stream.close();
}
template<unsigned n>
void mk_iz(const std::string& labeled, // in
const unsigned d, // in
const mln::neighb3d& nbh, // in
const std::string& input, // in
const std::string& quant, // in
const std::string& histo, // in
const std::string& colormap,// in
const std::string& iz, // out
const std::string& proj, // out
const std::string& mean, // out
const std::string& stats) // [out]
{
typedef mln::value::int_u8 t_int_u8;
typedef mln::value::label_8 t_lbl8;
typedef mln::value::rgb8 t_rgb8;
typedef mln::value::rgb<n> t_rgbn;
typedef mln::algebra::vec<3,float> t_v3f;
typedef mln::image2d<t_int_u8> t_image2d_int_u8;
typedef mln::image2d<t_rgb8> t_image2d_rgb8;
typedef mln::image2d<t_rgbn> t_image2d_rgbn;
typedef mln::image2d<t_lbl8> t_image2d_lbl8;
typedef mln::image3d<unsigned> t_histo3d;
typedef mln::image3d<t_lbl8> t_image3d_lbl8;
typedef mln::accu::meta::stat::histo3d_rgb t_histo3d_fun;
typedef mln::accu::stat::mean<t_v3f,t_v3f,t_v3f> t_mean;
typedef mln::util::array<t_v3f> t_mean_array;
// START OF IMAGE PROCESSING CHAIN
t_image2d_rgb8 i0_input; // input img
t_image2d_rgbn i1_input; // quant img
t_histo3d h1_input; // histo input
t_histo3d h2_input; // histo input
t_image2d_int_u8 p1_histo; // histo proj
t_image2d_rgb8 p3_histo; // histo proj
t_image3d_lbl8 l2_histo; // label histo
t_image3d_lbl8 l3_histo; // iz label hist
t_mean_array m2_label; // colormap
t_mean_array m3_label; // colormap
t_image2d_lbl8 l3_input; // label input
t_image2d_rgb8 i3_mean; // reconstructed
t_lbl8 n_lbl; // nb labels
t_rgb8 red(mln::literal::red);
mln::io::dump::load(l2_histo, labeled.c_str());
mln::io::ppm::load(i0_input, input.c_str());
mln::io::ppm::load(i1_input, quant.c_str());
mln::io::dump::load(h1_input, histo.c_str());
load(m2_label, colormap.c_str());
if (0 == d)
{
l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh);
}
else
{
l3_histo = mln::transform::influence_zone_geodesic(l2_histo, nbh, d);
}
// END OF IMAGE PROCESSING CHAIN
// BEGIN DUMPING
n_lbl = (t_lbl8)(m2_label.size()-1);
l3_input = mln::data::transform(i1_input, t_labeling_rgbn<n>(l3_histo));
i3_mean = mln::labeling::mean_values(i0_input, l3_input, n_lbl);
m3_label = mln::labeling::compute(t_mean(), i0_input, l3_input, n_lbl);
// CORRECT 0 LABEL STATS
m3_label[0][0] = 255.0;
m3_label[0][1] = 255.0;
m3_label[0][2] = 0.0;
p3_histo = mln::display::display3_histo3d_unsigned<n>(h1_input,
l3_histo,
m3_label,
red);
mln::io::dump::save(l3_input, iz.c_str());
mln::io::ppm::save(p3_histo, proj.c_str());
mln::io::ppm::save(i3_mean, mean.c_str());
if (0 < stats.size())