File: multihist.cc

package info (click to toggle)
mia 2.2.2-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 13,532 kB
  • ctags: 16,800
  • sloc: cpp: 137,909; python: 1,057; ansic: 998; sh: 146; xml: 127; csh: 24; makefile: 13
file content (164 lines) | stat: -rw-r--r-- 4,555 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
/* -*- mia-c++  -*-
 *
 * This file is part of MIA - a toolbox for medical image analysis 
 * Copyright (c) Leipzig, Madrid 1999-2014 Gert Wollny
 *
 * MIA is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with MIA; if not, see <http://www.gnu.org/licenses/>.
 *
 */

#include <sstream>
#include <ostream>
#include <fstream>
#include <mia/core.hh>
#include <mia/2d.hh>

NS_MIA_USE;
using namespace std;

const SProgramDescription g_description = {
	
	{pdi_group, 	"Processing of series of 2D images in a 3D fashion (out-of-core)"}, 
	{pdi_short, "histogram of a series of 2D images"}, 
	
	
	{pdi_description, "This program evaluates the histogram over a series of 2D images"}, 
	
	
	{pdi_example_descr,"Evaluate the histogram over all consecutively numbered images that follow the "
	 "numbering pattern inputXXXX.exr and store the output histogram in histo.txt. "
	 "Use the range [0,256] and 64 bins."}, 
	
	
	{pdi_example_code, "-i input0000.exr -o histo.txt --min 0 --max 256 --bins 64"}
}; 

class CHistAccumulator : public TFilter<bool> {
public:
	CHistAccumulator(float min, float max, size_t bins):
		m_histo(THistogramFeeder<float>(min, max, bins)), 
		m_last(0)
	{
	}

	template <typename T>
	bool operator () (const T2DImage<T>& image) {
		for(auto i = image.begin(); i != image.end(); ++i)
			m_histo.push(*i);
		return true;
	}

	void resize() {
		for (size_t i = 0; i < 	m_histo.size(); ++i) {
			if (m_histo[i] > 0 )
				m_last = i;
		}
	}
			
	bool save(const string& fname)const
	{
		ofstream file(fname.c_str());
		for (size_t i = 0; i < 	m_last; ++i) {
			const THistogram<THistogramFeeder<float > >::value_type v = m_histo.at(i);
			file << v.first << " " << v.second << "\n";
		}
		return file.good();
	}

	int propose_threshold()const {
		int pos = m_last / 10; 
		int max_pos = m_last / 6; 
		double val = m_histo[pos];
		
		for (int i = pos; i > 10; --i)
			if (m_histo[i] < val) {
				pos = i; 
				val = m_histo[i]; 
			}
		
		for (int i = pos; i < max_pos; ++i)
			if (m_histo[i] < val) {
				pos = i; 
				val = m_histo[i]; 
			}
		return pos; 
	}
private:
	THistogram<THistogramFeeder<float > > m_histo;
	size_t m_last; 
};



int do_main( int argc, char *argv[] )
{
	float hmin = 0;
	float hmax = 65535;
	size_t bins = 65536;

	string out_filename;
	string in_filename;
		
	const C2DImageIOPluginHandler::Instance& imageio = C2DImageIOPluginHandler::instance();

	CCmdOptionList options(g_description);
	options.add(make_opt( in_filename, "in-file", 'i', "input image(s) to be filtered", 
			      CCmdOptionFlags::required_input, &imageio));
	options.add(make_opt( out_filename, "out", 'o', "output file name", 
			      CCmdOptionFlags::required_output));
	options.add(make_opt( hmin, "min", 0, "minimum of histogram range"));
	options.add(make_opt( hmax, "max", 0, "maximum of histogram range"));
	options.add(make_opt( bins, "bins", 0, "number of histogram bins"));
		
	if (options.parse(argc, argv) != CCmdOptionList::hr_no)
		return EXIT_SUCCESS; 




	size_t start_filenum = 0;
	size_t end_filenum  = 0;
	size_t format_width = 0;

	string src_basename = get_filename_pattern_and_range(in_filename, start_filenum, end_filenum, format_width);
		
	if (start_filenum >= end_filenum)
		throw invalid_argument(string("no files match pattern ") + src_basename);


	CHistAccumulator histo_accu(hmin, hmax, bins);
	for (size_t i = start_filenum; i < end_filenum; ++i) {
		string src_name = create_filename(src_basename.c_str(), i);
		C2DImageIOPluginHandler::Instance::PData  in_image_list = imageio.load(src_name);
		cvmsg() << "Read:" << src_name << "\r";
		if (in_image_list.get() && in_image_list->size()) {
			for (auto k = in_image_list->begin(); k != in_image_list->end(); ++k)
				accumulate(histo_accu, **k);
		}
	}
	cvmsg() << "\n";
		
	histo_accu.resize(); 
		
	if (!histo_accu.save(out_filename))
		throw runtime_error(string("Error writing output file:") + out_filename);
		
		

	cout << histo_accu.propose_threshold(); 
	return EXIT_SUCCESS;

}
#include <mia/internal/main.hh>
MIA_MAIN(do_main);