URL:
https://svn.lrde.epita.fr/svn/oln/trunk/milena/sandbox
ChangeLog:
2009-03-05 Fabien Freling <fabien.freling(a)lrde.epita.fr>
Add source for dicom2dump tool.
* fabien/TODO: Simple TODO reminder.
* fabien/bin/Makefile: Makefile to compile dicom binaries.
* fabien/bin/dicom2dump.cc: Binary to convert dicom to dump.
* fabien/bin/dicom_mask.cc: Binary to extract simple mask
from dicom images.
* fabien/igr/Makefile: Update.
* fabien/igr/launch2d.sh: Update.
* fabien/igr/launch3d.sh: Update.
* fabien/igr/seg2d.cc: Update.
* fabien/igr/seg3d.cc: Update.
* fabien/igr/seg_vol_irm.hh: Implement different threshold
techniques: double and deviation.
---
TODO | 13 +++++++-
bin/Makefile | 23 ++++++++++++++
bin/dicom2dump.cc | 32 ++++++++++++++++++++
bin/dicom_mask.cc | 38 ++++++++++++++++++++++++
igr/Makefile | 6 +++
igr/launch2d.sh | 14 ++++++---
igr/launch3d.sh | 12 +++++--
igr/seg2d.cc | 17 ++++++++++
igr/seg3d.cc | 17 ++++++++++
igr/seg_vol_irm.hh | 82 +++++++++++++++++++++++++++++++++++++++--------------
10 files changed, 221 insertions(+), 33 deletions(-)
Index: trunk/milena/sandbox/fabien/igr/seg_vol_irm.hh
===================================================================
--- trunk/milena/sandbox/fabien/igr/seg_vol_irm.hh (revision 3481)
+++ trunk/milena/sandbox/fabien/igr/seg_vol_irm.hh (revision 3482)
@@ -39,6 +39,7 @@
#include <mln/value/int_u12.hh>
#include <mln/value/int_u16.hh>
#include <mln/value/rgb8.hh>
+#include <mln/value/label_16.hh>
#include <mln/io/pgm/all.hh>
#include <mln/io/pbm/all.hh>
@@ -56,6 +57,7 @@
#include <mln/labeling/blobs.hh>
#include <mln/labeling/compute.hh>
+#include <mln/labeling/foreground.hh>
#include <mln/labeling/fill_holes.hh>
#include <mln/labeling/n_max.hh>
@@ -85,7 +87,6 @@
#include <mln/pw/all.hh>
#include <mln/morpho/elementary/gradient_internal.hh>
-#include <mln/morpho/closing.hh>
#include <mln/morpho/dilation.hh>
#include <mln/morpho/erosion.hh>
@@ -149,12 +150,30 @@
+template <typename I>
+void
+save_regions_color(const Image<I>& ima, metal::int_<2>)
+{
+ io::ppm::save(ima, "regions_color.ppm");
+}
+
+
+
+template <typename I>
+void
+save_regions_color(const Image<I>& ima, metal::int_<3>)
+{
+ io::dump::save(ima, "regions_color.dump");
+}
+
+
+
template <typename I, typename N>
unsigned
find_threshold_value(const Image<I>& input, const Neighborhood<N>&
nbh)
{
- int bg_thres = 30;
- int obj_thres = 15;
+ int bg_thres = 20;
+ int obj_thres = 10;
mln_ch_value(I, bool) ima_bg;
initialize(ima_bg, input);
@@ -166,15 +185,16 @@
unsigned result = 0;
- histo::array<mln_value(I)> arr_histo = histo::compute(input);
+ // We remove the 0 value because it is not part of the image.
+ histo::array<mln_value(I)> arr_histo = histo::compute(input | pw::value(input) !=
0);
image1d<unsigned> ima_histo;
convert::from_to(arr_histo, ima_histo);
- // We remove the 0 value because it is not part of the image.
- ima_histo(point1d(0)) = 0;
-
+ std::ofstream fout("histo.plot");
+ fout << "0 0" << std::endl;
for (unsigned int i = 1; i < ima_histo.nelements(); ++i)
{
+ fout << i << " " << ima_histo(point1d(i)) <<
std::endl;
ima_histo(point1d(i)) += ima_histo(point1d(i - 1));
}
accu::max<unsigned> max_accu;
@@ -207,26 +227,41 @@
io::dump::save(ima_obj, "obj.dump");
}
- ima_bg = close_threshold(ima_bg, metal::int_<I::site::dim>(), 3, 5); // 5, 7?
- ima_obj = close_threshold(ima_obj, metal::int_<I::site::dim>(), 3, 5);
+ ima_bg = close_threshold(ima_bg, metal::int_<I::site::dim>(), 9, 15);
+ ima_obj = close_threshold(ima_obj, metal::int_<I::site::dim>(), 9, 11);
// Debug output images
mln_ch_value(I, rgb8) out = level::convert(rgb8(), level::stretch(int_u8(), input));
data::fill((out | pw::value(morpho::elementary::gradient_internal(ima_bg, nbh)) ==
true).rw(), literal::red);
data::fill((out | pw::value(morpho::elementary::gradient_internal(ima_obj, nbh)) ==
true).rw(), literal::green);
+ save_regions_color(out, metal::int_<I::site::dim>());
if (I::site::dim == 2)
{
io::pbm::save(ima_bg, "bg_closed.pbm");
io::pbm::save(ima_obj, "obj_closed.pbm");
- io::ppm::save(out, "regions_color.ppm");
}
if (I::site::dim == 3)
{
io::dump::save(ima_bg, "bg_closed.dump");
io::dump::save(ima_obj, "obj_closed.dump");
- io::dump::save(out, "regions_color.dump");
}
+ // Labeling
+ /*label_16 nlabels = 0;
+
+ mln_ch_value(I, label_16) bg_labels = labeling::foreground(ima_bg, nbh, nlabels);
+ mln_ch_value(I, label_16) obj_labels = labeling::foreground(ima_obj, nbh, nlabels);
+
+ accu::count<int_u8> a_;
+ util::array<unsigned> arr_label = labeling::compute(a_, ima_bg, bg_labels,
nlabels);
+ util::array<label_16> arr_big = labeling::n_max<label_16>(arr_label, 1);
+ data::fill((ima_bg | (pw::value(bg_labels) != pw::cst(arr_big[1]))).rw(), false);
+
+ arr_label = labeling::compute(a_, ima_obj, obj_labels, nlabels);
+ arr_big = labeling::n_max<label_16>(arr_label, 1);
+ data::fill((ima_obj | (pw::value(obj_labels) != pw::cst(arr_big[1]))).rw(), false);*/
+
+ // Histo
histo::array<mln_value(I)> bg_histo = histo::compute(input | pw::value(ima_bg) ==
true);
histo::array<mln_value(I)> obj_histo = histo::compute(input | pw::value(ima_obj)
== true);
@@ -236,23 +271,27 @@
ima_bg_histo(point1d(0)) = 0;
unsigned bg_sum = level::compute(sum_accu, ima_bg_histo);
// We remove the 0 value because it is not part of the image.
- std::ofstream fout_bg("bg_histo_norm.plot");
+ std::ofstream fout_bg("bg_histo.plot");
+ std::ofstream fout_p_bg("bg_histo_norm.plot");
for (unsigned int i = 0; i < ima_bg_histo.nelements(); ++i)
{
+ fout_bg << i << " " << ima_bg_histo(point1d(i)) <<
std::endl;
ima_bg_histo(point1d(i)) *= 10000;
ima_bg_histo(point1d(i)) /= bg_sum;
- fout_bg << i << " " << ima_bg_histo(point1d(i)) <<
std::endl;
+ fout_p_bg << i << " " << ima_bg_histo(point1d(i))
<< std::endl;
}
image1d<unsigned> ima_obj_histo;
convert::from_to(obj_histo, ima_obj_histo);
unsigned obj_sum = level::compute(sum_accu, ima_obj_histo);
- std::ofstream fout_obj("obj_histo_norm.plot");
+ std::ofstream fout_obj("obj_histo.plot");
+ std::ofstream fout_p_obj("obj_histo_norm.plot");
for (unsigned int i = 0; i < ima_obj_histo.nelements(); ++i)
{
+ fout_obj << i << " " << ima_obj_histo(point1d(i))
<< std::endl;
ima_obj_histo(point1d(i)) *= 10000;
ima_obj_histo(point1d(i)) /= obj_sum;
- fout_obj << i << " " << ima_obj_histo(point1d(i))
<< std::endl;
+ fout_p_obj << i << " " << ima_obj_histo(point1d(i))
<< std::endl;
}
// Search for the index with the min distance between histogrammes.
@@ -275,7 +314,7 @@
unsigned
find_threshold_mean(const Image<I>& input, const Neighborhood<N>&
nbh)
{
- unsigned result = 0;
+ unsigned coef = 1;
accu::mean<unsigned> mean_accu;
unsigned mean = level::compute(mean_accu, (input | (pw::value(input) != 0)));
@@ -283,13 +322,13 @@
accu::stat::deviation<unsigned, unsigned, float> dev_accu(mean);
float deviation = level::compute(dev_accu, (input | pw::value(input) != 0));
- std::cout << "mean = " << mean << std::endl <<
"deviation = " << deviation << std::endl;
- return floor(deviation);
+ std::cout << "[mean = " << mean << " | deviation =
" << deviation << "]";
+ return floor(mean + coef * deviation);
}
-template <typename I, typename N, typename L>
+/*template <typename I, typename N, typename L>
mln_ch_value(I, bool)
igr_seg(const Image<I>& input_, const Neighborhood<N>& nbh_, L&
nlabels)
{
@@ -301,9 +340,10 @@
mln_ch_value(I, bool) ima_thres;
initialize(ima_thres, input);
data::fill(ima_thres, false);
- //unsigned threshold_value = find_threshold_value(input, nbh);
+ std::cout << "double threshold value = " <<
find_threshold_value(input, nbh) << std::endl;
unsigned threshold_value = find_threshold_mean(input, nbh);
+ std::cout << " deviation threshold value = " << threshold_value
<< std::endl;
data::fill((ima_thres | pw::value(input) < pw::cst(threshold_value)).rw(), true);
return ima_thres;
-}
+}*/
Index: trunk/milena/sandbox/fabien/igr/seg2d.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/seg2d.cc (revision 3481)
+++ trunk/milena/sandbox/fabien/igr/seg2d.cc (revision 3482)
@@ -34,7 +34,22 @@
label_16 nlabels;
image2d<int_u12> ima;
io::dicom::load(ima, argv[1]);
- io::pbm::save(igr_seg(ima, c4(), nlabels), "result.pbm");
+
+ image2d<bool> ima_thres;
+ initialize(ima_thres, ima);
+ data::fill(ima_thres, false);
+ unsigned threshold_value = find_threshold_value(ima, c4());
+ std::cout << "double threshold value = " << threshold_value
<< std::endl;
+ data::fill((ima_thres | pw::value(ima) < pw::cst(threshold_value)).rw(), true);
+
+ io::pbm::save(ima_thres, "result_double.pbm");
+
+ data::fill(ima_thres, false);
+ threshold_value = find_threshold_mean(ima, c4());
+ std::cout << " deviation threshold value = " << threshold_value
<< std::endl;
+ data::fill((ima_thres | pw::value(ima) < pw::cst(threshold_value)).rw(), true);
+
+ io::pbm::save(ima_thres, "result_deviation.pbm");
return 0;
}
Index: trunk/milena/sandbox/fabien/igr/launch2d.sh
===================================================================
--- trunk/milena/sandbox/fabien/igr/launch2d.sh (revision 3481)
+++ trunk/milena/sandbox/fabien/igr/launch2d.sh (revision 3482)
@@ -3,8 +3,9 @@
process_file ()
{
./seg2d $1
- if [ -f result.pbm ]; then
- mv result.pbm results/${2}_06_result.pbm
+ if [ -f result_double.pbm ]; then
+ mv result_double.pbm results/${2}_06_result_double.pbm
+ mv result_deviation.pbm results/${2}_07_result_deviation.pbm
fi
if [ -f bg.pbm ]; then
@@ -14,10 +15,15 @@
mv bg_closed.pbm results/${2}_02_bg_closed.pbm
mv obj_closed.pbm results/${2}_04_obj_closed.pbm
+ if [ -f regions_color.ppm ]; then
mv regions_color.ppm results/${2}_05_regions_color.ppm
+ fi
- mv bg_histo_norm.plot results/${2}_bg.plot
- mv obj_histo_norm.plot results/${2}_obj.plot
+ mv histo.plot results/${2}.plot
+ mv bg_histo.plot results/${2}_bg.plot
+ mv obj_histo.plot results/${2}_obj.plot
+ mv bg_histo_norm.plot results/${2}_p_bg.plot
+ mv obj_histo_norm.plot results/${2}_p_obj.plot
fi
}
Index: trunk/milena/sandbox/fabien/igr/seg3d.cc
===================================================================
--- trunk/milena/sandbox/fabien/igr/seg3d.cc (revision 3481)
+++ trunk/milena/sandbox/fabien/igr/seg3d.cc (revision 3482)
@@ -36,7 +36,22 @@
label_16 nlabels;
image3d<int_u12> ima;
io::dicom::load(ima, argv[1]);
- io::dump::save(igr_seg(ima, c6(), nlabels), "result.dump");
+
+ image3d<bool> ima_thres;
+ initialize(ima_thres, ima);
+ data::fill(ima_thres, false);
+ unsigned threshold_value = find_threshold_value(ima, c6());
+ std::cout << "double threshold value = " << threshold_value
<< std::endl;
+ data::fill((ima_thres | pw::value(ima) < pw::cst(threshold_value)).rw(), true);
+
+ io::dump::save(ima_thres, "result_double.dump");
+
+ data::fill(ima_thres, false);
+ threshold_value = find_threshold_mean(ima, c6());
+ std::cout << " deviation threshold value = " << threshold_value
<< std::endl;
+ data::fill((ima_thres | pw::value(ima) < pw::cst(threshold_value)).rw(), true);
+
+ io::dump::save(ima_thres, "result_deviation.dump");
return 0;
}
Index: trunk/milena/sandbox/fabien/igr/launch3d.sh
===================================================================
--- trunk/milena/sandbox/fabien/igr/launch3d.sh (revision 3481)
+++ trunk/milena/sandbox/fabien/igr/launch3d.sh (revision 3482)
@@ -3,7 +3,8 @@
process_file ()
{
./seg3d $1
- ../bin/dump2pbm result.dump results/${2}_06_result.pbm
+ ../bin/dump2pbm result_double.dump results/${2}_06_result_double.pbm
+ ../bin/dump2pbm result_deviation.dump results/${2}_07_result_deviation.pbm
../bin/dump2pbm bg.dump results/${2}_01_bg.pbm
../bin/dump2pbm obj.dump results/${2}_03_obj.pbm
@@ -11,12 +12,15 @@
../bin/dump2pbm bg_closed.dump results/${2}_02_bg_closed.pbm
../bin/dump2pbm obj_closed.dump results/${2}_04_obj_closed.pbm
-#../bin/dump2ppm regions_color.dump results/${2}_05_colors.ppm
+ ../bin/dump2ppm regions_color.dump results/${2}_05_regions_colors.ppm
rm *.dump
- mv bg_histo_norm.plot results/${2}_bg.plot
- mv obj_histo_norm.plot results/${2}_obj.plot
+ mv histo.plot results/${2}.plot
+ mv bg_histo.plot results/${2}_bg.plot
+ mv obj_histo.plot results/${2}_obj.plot
+ mv bg_histo_norm.plot results/${2}_p_bg.plot
+ mv obj_histo_norm.plot results/${2}_p_obj.plot
}
process_file "/Users/HiSoKa/Work/IGR/souris18/irm/IM_0052.dcm" "52"
Index: trunk/milena/sandbox/fabien/igr/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/igr/Makefile (revision 3481)
+++ trunk/milena/sandbox/fabien/igr/Makefile (revision 3482)
@@ -16,5 +16,11 @@
3d: seg_vol_irm.hh seg3d.cc
g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} seg3d.cc -o seg3d
+grad: grad_clo_and_wshd.cc
+ g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} $^ -o grad_clo
+
+wst: wst_rag.cc
+ g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} $^ -o wst_rag
+
clean:
rm -rf *.dump *.p?m *.plot *.log *.csv
Index: trunk/milena/sandbox/fabien/TODO
===================================================================
--- trunk/milena/sandbox/fabien/TODO (revision 3481)
+++ trunk/milena/sandbox/fabien/TODO (revision 3482)
@@ -9,5 +9,14 @@
[X] Create binaries
[X] Create scripts shell
-[ ] Check standard deviation
-
+[X] Generate color images for regions
+[X] Generate histograms (normal, bg, obj, p_bg, p_obj)
+[ ] Test processing chain on US
+[X] Create README file for special images
+[ ] Implement watershed
+[X] Create tool for dicom mask
+[X] Check conversion for mask (everything except int_u12(0))
+[ ] Extract ROI (projection or fill holes)
+[ ] Create routine for region colors
+[ ] Create dicom2dump (2d, 3d, int_u8, int_u12)
+[ ] After threshold, take biggest object and then erode, dilate
Index: trunk/milena/sandbox/fabien/bin/dicom2dump.cc
===================================================================
--- trunk/milena/sandbox/fabien/bin/dicom2dump.cc (revision 0)
+++ trunk/milena/sandbox/fabien/bin/dicom2dump.cc (revision 3482)
@@ -0,0 +1,32 @@
+#include <mln/core/concept/image.hh>
+#include <mln/core/image/image3d.hh>
+
+#include <mln/value/int_u12.hh>
+#include <mln/io/dicom/load.hh>
+#include <mln/io/dump/save.hh>
+
+
+
+int usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.dcm
output.dump" << std::endl;
+ std::cerr << "\t work for 3D images encoded in int_u12" <<
std::endl;
+ return 1;
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u12;
+
+ if (argc != 3)
+ return usage(argv);
+
+ image3d<int_u12> ima;
+ io::dicom::load(ima, argv[1]);
+ io::dump::save(ima, argv[2]);
+
+ return 0;
+}
Index: trunk/milena/sandbox/fabien/bin/dicom_mask.cc
===================================================================
--- trunk/milena/sandbox/fabien/bin/dicom_mask.cc (revision 0)
+++ trunk/milena/sandbox/fabien/bin/dicom_mask.cc (revision 3482)
@@ -0,0 +1,38 @@
+#include <mln/core/concept/image.hh>
+#include <mln/core/image/image2d.hh>
+
+#include <mln/value/int_u8.hh>
+#include <mln/io/dicom/load.hh>
+#include <mln/io/pbm/save.hh>
+
+#include <mln/literal/colors.hh>
+
+#include <mln/level/transform.hh>
+#include <mln/fun/v2b/threshold.hh>
+
+#include <mln/data/fill.hh>
+#include <mln/pw/all.hh>
+
+
+void usage(char* argv[])
+{
+ std::cerr << "usage: " << argv[0] << " input.dcm
output.pbm" << std::endl;
+ abort();
+}
+
+
+
+int main(int argc, char* argv[])
+{
+ using namespace mln;
+ using value::int_u8;
+
+ if (argc != 3)
+ usage(argv);
+
+ image2d<int_u8> input;
+ io::dicom::load(input, argv[1]);
+
+ image2d<bool> ima = level::transform(input,
fun::v2b::threshold<int_u8>(1));
+ io::pbm::save(ima, argv[2]);
+}
Index: trunk/milena/sandbox/fabien/bin/Makefile
===================================================================
--- trunk/milena/sandbox/fabien/bin/Makefile (revision 0)
+++ trunk/milena/sandbox/fabien/bin/Makefile (revision 3482)
@@ -0,0 +1,23 @@
+GDCM_SRC_DIR = /Users/HiSoKa/Downloads/gdcm-2.0.10
+GDCM_BIN_DIR = /Users/HiSoKa/Downloads/gdcmbin
+
+DICOM_INC = -I${GDCM_SRC_DIR}/Source/Common/ \
+ -I${GDCM_BIN_DIR}/Source/Common/ \
+ -I${GDCM_SRC_DIR}/Source/DataDictionary/ \
+ -I${GDCM_SRC_DIR}/Source/MediaStorageAndFileFormat/ \
+ -I${GDCM_SRC_DIR}/Source/DataStructureAndEncodingDefinition/
+
+# "-framework CoreFoundation" is a Mac OS X specific flag
+DICOM_LIB = -L${GDCM_BIN_DIR}/bin \
+ -lgdcmCommon -lgdcmDICT -lgdcmDSED -lgdcmIOD -lgdcmMSFF -lgdcmexpat -lgdcmjpeg12
-lgdcmjpeg16 -lgdcmjpeg8 -lgdcmopenjpeg -lgdcmuuid -lgdcmzlib \
+ -framework CoreFoundation
+
+CXXFLAGS = -DNDEBUG -O1
+
+all: mask dump
+
+mask: dicom_mask.cc
+ g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} $^ -o dicom_mask
+
+dump: dicom2dump.cc
+ g++ -I../../../ ${DICOM_INC} ${DICOM_LIB} ${CXXFLAGS} $^ -o dicom2dump