SOMModel.txx 5.19 KB
Newer Older
1
2
3
4
5
6
7
8
#ifndef SOMModel_txx
#define SOMModel_txx

#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"

#include "itkMacro.h"

9
10
11
12
13
14

// test text file
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include <fstream> 

15
16
17

#include "itkImage.h"

18
19
20
21
namespace otb
{


22
23
template <class TInputValue, unsigned int MapDimension>
SOMModel<TInputValue,  MapDimension>::SOMModel()
24
{
25
	this->m_Dimension = MapType::ImageDimension;
26
27
28
}


29
30
template <class TInputValue, unsigned int MapDimension>
SOMModel<TInputValue, MapDimension>::~SOMModel()
31
32
33
34
{
}


35
36
template <class TInputValue, unsigned int MapDimension>
void SOMModel<TInputValue,  MapDimension>::Train()
37
38
39
40
41
42
43
44
45
46
47
48
49
50
{
	
    typename EstimatorType::Pointer estimator = EstimatorType::New();
	
    estimator->SetListSample(m_ListSample);
    estimator->SetMapSize(m_MapSize);
    estimator->SetNeighborhoodSizeInit(m_NeighborhoodSizeInit);
    estimator->SetNumberOfIterations(m_NumberOfIterations);
    estimator->SetBetaInit(m_BetaInit);
    estimator->SetBetaEnd(m_BetaEnd);
    estimator->SetMaxWeight(m_MaxWeight);
    //AddProcess(estimator,"Learning");
    estimator->Update();
    m_SOMMap = estimator->GetOutput();
51
   }
52
53


54

55
56
template <class TInputValue, unsigned int MapDimension>
bool SOMModel<TInputValue, MapDimension>::CanReadFile(const std::string & filename)
57
{
58
59
60
61
62
63
64
65
	try
	{
		this->Load(filename);
	}
	catch(...)
	{
	return false;
	}
66
67
68
69
	return true;
}


70
71
template <class TInputValue, unsigned int MapDimension>
bool SOMModel<TInputValue, MapDimension>::CanWriteFile(const std::string & filename)
72
73
74
75
{
	return true;
}

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
template<typename T>
std::ostream& binary_write(std::ostream& stream, const T& value){
    return stream.write(reinterpret_cast<const char*>(&value), sizeof(T));
}


std::ostream& binary_write_string(std::ofstream& stream, const std::string& value){
    return stream.write(value.c_str(), value.length());
}

template<typename T>
std::istream & binary_read(std::istream& stream, T& value){
    return stream.read(reinterpret_cast<char*>(&value), sizeof(T));
}



93
94
template <class TInputValue, unsigned int MapDimension>
void SOMModel<TInputValue, MapDimension>::Save(const std::string & filename, const std::string & name)
95
{
96
97
98
99
	itk::ImageRegionConstIterator<MapType> inputIterator(m_SOMMap,m_SOMMap->GetLargestPossibleRegion());
	inputIterator.GoToBegin();
	std::ofstream ofs(filename, std::ios::binary);
	binary_write_string(ofs,"som"); 
100
	binary_write(ofs,static_cast<unsigned int>(MapDimension));
101
102
	SizeType size = m_SOMMap->GetLargestPossibleRegion().GetSize() ;
	for (size_t i=0;i<MapDimension;i++){
103
		binary_write(ofs,size[i]);
104
	}
105
106
107
108
109
110
111
	  
	binary_write(ofs,inputIterator.Get().GetNumberOfElements());
	while(!inputIterator.IsAtEnd()){
		InputSampleType vect = inputIterator.Get();
		for (size_t i=0;i<vect.GetNumberOfElements();i++){
			binary_write(ofs,vect[i]);
		}	
112
	++inputIterator;
113
114
	}
	ofs.close();
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
	
	if (this->m_WriteMap == true)     // output the map vectors in a txt file
	{
		std::ofstream otxt(filename+".txt");
		inputIterator.GoToBegin();
		while(!inputIterator.IsAtEnd())
		{
			InputSampleType vect = inputIterator.Get();
			for (size_t i=0;i<vect.GetNumberOfElements();i++)
			{
				
				otxt << vect[i] << " ";
			}	
			otxt << std::endl;
			++inputIterator;
		}
		otxt.close();
	}
133
134
}

135
136
template <class TInputValue, unsigned int MapDimension>
void SOMModel<TInputValue, MapDimension>::Load(const std::string & filename, const std::string & name)
137
{
138
	
139
	std::ifstream ifs(filename, std::ios::binary);
140
	
141
142
143
144
145
146
147
	/**  Read the model key (should be som) */
	char s[]="   ";
	for (int i=0; i<3; i++){	
		binary_read(ifs,s[i]);
	}
	std::string modelType(s);
	/** Read the dimension of the map (should be equal to MapDimension) */
148
	
149
	unsigned int dimension;
150
151
	binary_read(ifs,dimension);
	if (modelType != "som" || dimension != MapDimension){
152
153
154
155
156
		itkExceptionMacro(<< "Error opening " << filename.c_str() );
    }
    
	SizeType size;
	itk::Index< MapDimension > index;
157
158
	for (int i=0 ; i<MapDimension; i++)
	{
159
		binary_read(ifs,size[i]);
160
		index[i]=0;
161
	}
162
163
	unsigned int numberOfElements;
	binary_read(ifs,numberOfElements);
164
165
166
	m_SOMMap = MapType::New();
	typename MapType::RegionType region;
	region.SetSize( size );
167
	m_SOMMap->SetNumberOfComponentsPerPixel(numberOfElements);
168
169
170
171
172
	region.SetIndex( index );
	m_SOMMap->SetRegions( region );
	m_SOMMap->Allocate();

	itk::ImageRegionIterator<MapType> outputIterator(m_SOMMap,region);
173
    outputIterator.GoToBegin();
174
175
	std::string value;
	while(!outputIterator.IsAtEnd()){
176
177
		InputSampleType  vect(numberOfElements);
		for (int i=0 ; i<numberOfElements; i++)
178
		{
179
180
181
			float v;    // InputValue type is not the same during training anddimredvector.
			binary_read(ifs,v);
			vect[i] = static_cast<double>(v);
182
183
184
		}
		outputIterator.Set(vect);
		++outputIterator;
185
186
	}
	ifs.close();
187
	
188
	this->m_Dimension = MapType::ImageDimension;
189
190
191
}


192
193
template <class TInputValue, unsigned int MapDimension>
typename SOMModel<TInputValue, MapDimension>::TargetSampleType
194
SOMModel<TInputValue, MapDimension>::DoPredict(const InputSampleType & value, ConfidenceValueType * quality) const
195
196
{ 
    TargetSampleType target;
197
    target.SetSize(this->m_Dimension);
198
199
	
    auto winner =m_SOMMap->GetWinner(value);
200
    for (int i=0; i< this->m_Dimension ;i++) {
201
202
		target[i] = winner.GetElement(i); 
	}
203

204
	return target;
205
206
207
208
}

} // namespace otb
#endif