SourceXtractorPlusPlus
0.21
SourceXtractor++, the next generation SExtractor
Loading...
Searching...
No Matches
SEImplementation
src
lib
Background
SE
SEBackgroundLevelAnalyzer.cpp
Go to the documentation of this file.
1
18
#include "
SEImplementation/Background/SE/SEBackgroundLevelAnalyzer.h
"
19
20
#include "
SEFramework/Image/ConstantImage.h
"
21
#include "
SEFramework/Image/MaskedImage.h
"
22
#include "
SEFramework/Image/ProcessedImage.h
"
23
#include "
SEFramework/Image/BufferedImage.h
"
24
#include "
SEFramework/Image/ScaledImageSource.h
"
25
#include "
SEImplementation/Background/Utils.h
"
26
#include "
SEImplementation/Background/SE/ImageMode.h
"
27
#include "
SEImplementation/Background/SE/MedianFilter.h
"
28
#include "
SEImplementation/Background/SE/ReplaceUndefImage.h
"
29
30
namespace
SourceXtractor
{
31
32
SEBackgroundLevelAnalyzer::SEBackgroundLevelAnalyzer
(
const
std::vector<int>
&
cell_size
,
33
const
std::vector<int>
&
smoothing_box
,
34
const
WeightImageConfig::WeightType
weight_type)
35
: m_weight_type(weight_type) {
36
assert
(
cell_size
.size() > 0 &&
cell_size
.size() < 3);
37
assert
(
smoothing_box
.size() > 0 &&
smoothing_box
.size() < 3);
38
m_cell_size
[0] =
cell_size
.front();
39
m_cell_size
[1] =
cell_size
.back();
40
m_smoothing_box
[0] =
smoothing_box
.front();
41
m_smoothing_box
[1] =
smoothing_box
.back();
42
}
43
44
static
float
computeScaling
(
const
std::shared_ptr
<
VectorImage<DetectionImage::PixelType>
>&
variance
,
45
const
std::shared_ptr
<
VectorImage<WeightImage::PixelType>
>& weight) {
46
std::vector<float>
ratios
;
47
ratios
.reserve(
variance
->getWidth() *
variance
->getHeight());
48
49
for
(
int
y
= 0;
y
<
variance
->getHeight(); ++
y
) {
50
for
(
int
x
= 0;
x
<
variance
->getWidth(); ++
x
) {
51
auto
w
= weight->getValue(
x
,
y
);
52
if
(
w
> 0) {
53
auto
v
=
variance
->getValue(
x
,
y
);
54
auto
ratio
= (
v
*
v
) /
w
;
55
if
(
ratio
> 0) {
56
ratios
.emplace_back(
ratio
);
57
}
58
}
59
}
60
}
61
62
std::sort
(
ratios
.begin(),
ratios
.end());
63
if
(
ratios
.size() % 2 == 1) {
64
return
ratios
[
ratios
.size() / 2];
65
}
66
return
(
ratios
[
ratios
.size() / 2] +
ratios
[
ratios
.size() / 2 - 1]) / 2;
67
}
68
69
static
float
getMedian
(
const
VectorImage<DetectionImage::PixelType>
&
img
) {
70
auto
v
=
img
.getData();
71
std::sort
(
v
.begin(),
v
.end());
72
auto
nitems
=
v
.size();
73
if
(
nitems
% 2 == 1) {
74
return
v
[
nitems
/ 2];
75
}
76
return
(
v
[
nitems
/ 2] +
v
[
nitems
/ 2 - 1]) / 2;
77
}
78
79
BackgroundModel
SEBackgroundLevelAnalyzer::analyzeBackground
(
80
std::shared_ptr<DetectionImage>
image
,
std::shared_ptr<WeightImage>
variance_map
,
81
std::shared_ptr
<
Image<unsigned char>
> mask,
WeightImage::PixelType
variance_threshold
)
const
{
82
83
const
auto
mask_value
=
std::numeric_limits<DetectionImage::PixelType>::lowest
();
84
85
if
(mask !=
nullptr
) {
86
bck_model_logger
.debug() <<
"\tMask image with size: ("
<< mask->getWidth() <<
","
<< mask->getHeight() <<
")"
;
87
88
// make sure the dimensions are the same
89
if
(
image
->getWidth() != mask->getWidth())
90
throw
Elements::Exception
() <<
"X-dims do not match: image="
<<
image
->getWidth() <<
" mask="
<< mask->getWidth();
91
if
(
image
->getHeight() != mask->getHeight())
92
throw
Elements::Exception
() <<
"Y-dims do not match: image="
<<
image
->getHeight() <<
" mask="
93
<< mask->getHeight();
94
95
image
=
MaskedImage<DetectionImage::PixelType, uint8_t>::create
(
image
, mask,
mask_value
);
96
}
97
98
if
(
variance_map
!=
nullptr
) {
99
bck_model_logger
.debug() <<
"\tVariance image with size: ("
<<
variance_map
->getWidth() <<
","
100
<<
variance_map
->getHeight() <<
")"
;
101
// make sure the dimensions are the same
102
if
(
image
->getWidth() !=
variance_map
->getWidth())
103
throw
Elements::Exception
() <<
"X-dims do not match: image="
<<
image
->getWidth() <<
" variance="
104
<<
variance_map
->getWidth();
105
if
(
image
->getHeight() !=
variance_map
->getHeight())
106
throw
Elements::Exception
() <<
"Y-dims do not match: image="
<<
image
->getHeight() <<
" variance="
107
<<
variance_map
->getHeight();
108
109
// Anything above the threshold is masked out
110
image
=
MaskedImage<DetectionImage::PixelType, WeightImage::PixelType, std::greater_equal>::create
(
111
image
,
variance_map
,
mask_value
,
variance_threshold
);
112
variance_map
=
MaskedImage<WeightImage::PixelType, WeightImage::PixelType, std::greater_equal>::create
(
113
variance_map
,
variance_map
,
mask_value
,
variance_threshold
);
114
}
115
116
// Create histogram model for the image
117
ImageMode<DetectionImage::PixelType>
histo
(
image
,
variance_map
,
m_cell_size
[0],
m_cell_size
[1],
mask_value
, 2, 5, 3);
118
auto
mode
=
histo
.getModeImage();
119
auto
var
=
histo
.getSigmaImage();
120
121
// Interpolate missing values
122
// The result is "materialized" into a VectorImage to avoid redundant computations on the next steps
123
mode
=
ReplaceUndef<DetectionImage::PixelType>
(*
mode
,
mask_value
);
124
var
=
ReplaceUndef<WeightImage::PixelType>
(*
var
,
mask_value
);
125
126
// Smooth with the smooth_box (median filtering)
127
std::tie
(
mode
,
var
) =
MedianFilter<DetectionImage::PixelType>
(
m_smoothing_box
)(*
mode
, *
var
);
128
auto
median
=
getMedian
(*
mode
);
129
auto
median_sigma
=
getMedian
(*
var
);
130
131
SeFloat
scaling
= 99999;
132
133
std::shared_ptr<Image<DetectionImage::PixelType>
>
final_bg
,
final_var
;
134
135
if
(
variance_map
) {
136
// Create histogram model for the variance image
137
auto
weight =
histo
.getVarianceModeImage();
138
auto
weight_var
=
histo
.getVarianceSigmaImage();
139
// Interpolate missing values
140
weight =
ReplaceUndef<DetectionImage::PixelType>
(*weight,
mask_value
);
141
// Smooth with the smooth_box (median filtering)
142
std::tie
(weight,
weight_var
) =
MedianFilter<WeightImage::PixelType>
(
m_smoothing_box
)(*weight, *
weight_var
);
143
// Compute scaling
144
scaling
=
computeScaling
(
var
, weight);
145
// Transform RMS to variance
146
final_var
=
MultiplyImage<DetectionImage::PixelType>::create
(
var
,
var
);
147
final_var
=
BufferedImage<DetectionImage::PixelType>::create
(
148
std::make_shared
<
ScaledImageSource<DetectionImage::PixelType>
>(
149
final_var
,
image
->getWidth(),
image
->getHeight(),
150
ScaledImageSource<DetectionImage::PixelType>::InterpolationType::BICUBIC
151
)
152
);
153
}
154
else
{
155
final_var
=
ConstantImage<DetectionImage::PixelType>::create
(
image
->getWidth(),
image
->getHeight(),
156
median_sigma
*
median_sigma
);
157
}
158
159
bck_model_logger
.info() <<
"Background for image: "
<<
image
->getRepr() <<
" median: "
<<
median
160
<<
" rms: "
<<
median_sigma
<<
"!"
;
161
162
final_bg
=
BufferedImage<DetectionImage::PixelType>::create
(
163
std::make_shared
<
ScaledImageSource<DetectionImage::PixelType>
>(
164
mode
,
image
->getWidth(),
image
->getHeight(),
165
ScaledImageSource<DetectionImage::PixelType>::InterpolationType::BICUBIC
166
)
167
);
168
169
return
BackgroundModel
(
final_bg
,
final_var
,
scaling
,
median_sigma
);
170
}
171
172
}
// end of namespace SourceXtractor
BufferedImage.h
ConstantImage.h
ImageMode.h
MaskedImage.h
MedianFilter.h
x
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > x
Definition
MoffatModelFittingTask.cpp:94
y
std::shared_ptr< DependentParameter< std::shared_ptr< EngineParameter > > > y
Definition
MoffatModelFittingTask.cpp:94
ProcessedImage.h
ReplaceUndefImage.h
SEBackgroundLevelAnalyzer.h
ScaledImageSource.h
Utils.h
Elements::Exception
SourceXtractor::BackgroundModel
Definition
BackgroundAnalyzer.h:33
SourceXtractor::BufferedImage::create
static std::shared_ptr< BufferedImage< T > > create(std::shared_ptr< const ImageSource > source, std::shared_ptr< TileManager > tile_manager=TileManager::getInstance())
Definition
BufferedImage.cpp:32
SourceXtractor::ConstantImage::create
static std::shared_ptr< ConstantImage< T > > create(int width, int height, T constant_value)
Definition
ConstantImage.h:42
SourceXtractor::Image< SeFloat >::PixelType
SeFloat PixelType
Definition
Image.h:48
SourceXtractor::MaskedImage::create
static std::shared_ptr< MaskedImage< T, M, Operator > > create(const std::shared_ptr< Image< T > > &image, const std::shared_ptr< Image< M > > &mask, T replacement, M mask_flag=0x01)
Definition
MaskedImage.h:78
SourceXtractor::SEBackgroundLevelAnalyzer::m_cell_size
std::array< int, 2 > m_cell_size
Definition
SEBackgroundLevelAnalyzer.h:40
SourceXtractor::SEBackgroundLevelAnalyzer::SEBackgroundLevelAnalyzer
SEBackgroundLevelAnalyzer(const std::vector< int > &cell_size, const std::vector< int > &smoothing_box, const WeightImageConfig::WeightType weight_type)
Definition
SEBackgroundLevelAnalyzer.cpp:32
SourceXtractor::SEBackgroundLevelAnalyzer::m_smoothing_box
std::array< int, 2 > m_smoothing_box
Definition
SEBackgroundLevelAnalyzer.h:41
SourceXtractor::SEBackgroundLevelAnalyzer::analyzeBackground
BackgroundModel analyzeBackground(std::shared_ptr< DetectionImage > image, std::shared_ptr< WeightImage > variance_map, std::shared_ptr< Image< unsigned char > > mask, WeightImage::PixelType variance_threshold) const override
Definition
SEBackgroundLevelAnalyzer.cpp:79
SourceXtractor::ScaledImageSource
Definition
ScaledImageSource.h:35
SourceXtractor::WeightImageConfig::WeightType
WeightType
Definition
WeightImageConfig.h:36
std::function
std::numeric_limits::lowest
T lowest(T... args)
std::make_shared
T make_shared(T... args)
SourceXtractor
Definition
Aperture.h:30
SourceXtractor::getMedian
static float getMedian(const VectorImage< DetectionImage::PixelType > &img)
Definition
SEBackgroundLevelAnalyzer.cpp:69
SourceXtractor::bck_model_logger
static Elements::Logging bck_model_logger
Definition
Utils.h:25
SourceXtractor::computeScaling
static float computeScaling(const std::shared_ptr< VectorImage< DetectionImage::PixelType > > &variance, const std::shared_ptr< VectorImage< WeightImage::PixelType > > &weight)
Definition
SEBackgroundLevelAnalyzer.cpp:44
std::ratio
std::shared_ptr
std::sort
T sort(T... args)
std::tie
T tie(T... args)
Generated by
1.10.0