19PatchSampler::PatchSampler(std::vector<SingleView::Ptr>
const& _views,
21 int _x,
int _y,
float _depth,
float _dzI,
float _dzJ)
29 , success(views.size(), false)
38 patchPoints.resize(nrSamples);
39 masterColorSamples.resize(nrSamples);
40 masterViewDirs.resize(nrSamples);
46 bottomRight = midPix + h;
47 if (topLeft[0] < 0 || topLeft[1] < 0
48 || bottomRight[0] > masterImg->width()-1
49 || bottomRight[1] > masterImg->height()-1)
53 std::size_t count = 0;
54 for (
int j = topLeft[1]; j <= bottomRight[1]; ++j)
55 for (
int i = topLeft[0]; i <= bottomRight[0]; ++i)
56 masterViewDirs[count++] = refV->viewRayScaled(i, j);
60 computeMasterSamples();
71 imgPos.resize(nrSamples);
76 float mfp = refV->footPrintScaled(p0);
77 float nfp = views[v]->footPrint(p0);
79 std::cerr <<
"Error in getFastColAndDerivSamples! "
80 <<
"footprint in master view: " << mfp << std::endl;
81 throw std::out_of_range(
"Negative pixel footprint");
85 float ratio = nfp / mfp;
87 while (ratio < 0.5f) {
91 mmLevel = views[v]->clampLevel(mmLevel);
95 float d = (views[v]->worldToScreen(p1, mmLevel)
96 - views[v]->worldToScreen(patchPoints[12], mmLevel)).norm();
100 stepSize[v] = 1.f / d;
104 int const w = img->width();
105 int const h = img->height();
109 std::vector<math::Vec2f> gradDir(nrSamples);
110 for (std::size_t i = 0; i < nrSamples; ++i)
113 math::Vec3f p1(patchPoints[i] + masterViewDirs[i] * stepSize[v]);
114 imgPos[i] = views[v]->worldToScreen(p0, mmLevel);
116 if (!(imgPos[i][0] > 0 && imgPos[i][0] < w-1 &&
117 imgPos[i][1] > 0 && imgPos[i][1] < h-1)) {
120 gradDir[i] = views[v]->worldToScreen(p1, mmLevel) - imgPos[i];
129 for (std::size_t i = 0; i < nrSamples; ++i)
130 deriv[i] /= stepSize[v];
138 if (neighColorSamples[v].empty())
139 computeNeighColorSamples(v);
144 for (std::size_t i = 0; i < nrSamples; ++i)
145 meanY += neighColorSamples[v][i];
146 meanY /= (float) nrSamples;
150 for (std::size_t i = 0; i < nrSamples; ++i)
152 sqrDevY += (neighColorSamples[v][i] - meanY).square_norm();
154 devXY += (masterColorSamples[i] - meanX)
155 .dot(neighColorSamples[v][i] - meanY);
157 float tmp = sqrt(sqrDevX * sqrDevY);
160 return (devXY / tmp);
168 if (neighColorSamples[u].empty())
169 computeNeighColorSamples(u);
170 if (neighColorSamples[v].empty())
171 computeNeighColorSamples(v);
177 for (std::size_t i = 0; i < nrSamples; ++i)
179 meanX += neighColorSamples[u][i];
180 meanY += neighColorSamples[v][i];
188 for (std::size_t i = 0; i < nrSamples; ++i)
190 sqrDevX += (neighColorSamples[u][i] - meanX).square_norm();
191 sqrDevY += (neighColorSamples[v][i] - meanY).square_norm();
192 devXY += (neighColorSamples[u][i] - meanX)
193 .dot(neighColorSamples[v][i] - meanY);
196 float tmp = sqrt(sqrDevX * sqrDevY);
198 return (devXY / tmp);
206 if (neighColorSamples[v].empty())
207 computeNeighColorSamples(v);
212 for (std::size_t i = 0; i < nrSamples; ++i) {
213 for (
int c = 0; c < 3; ++c) {
214 sum += std::abs(cs[c] * neighColorSamples[v][i][c] -
215 masterColorSamples[i][c]);
224 if (neighColorSamples[v].empty())
225 computeNeighColorSamples(v);
230 for (std::size_t i = 0; i < nrSamples; ++i)
232 for (
int c = 0; c < 3; ++c)
234 float diff = cs[c] * neighColorSamples[v][i][c] -
235 masterColorSamples[i][c];
245 std::size_t right = nrSamples/2 + offset;
246 std::size_t left = nrSamples/2 - offset;
247 std::size_t top = offset;
248 std::size_t bottom = nrSamples - 1 - offset;
250 math::Vec3f a(patchPoints[right] - patchPoints[left]);
251 math::Vec3f b(patchPoints[top] - patchPoints[bottom]);
262 success.resize(views.size(),
false);
267 computePatchPoints();
268 neighColorSamples.clear();
269 neighDerivSamples.clear();
270 neighPosSamples.clear();
274PatchSampler::computePatchPoints()
278 unsigned int count = 0;
279 for (
int j = topLeft[1]; j <= bottomRight[1]; ++j)
281 for (
int i = topLeft[0]; i <= bottomRight[0]; ++i)
283 float tmpDepth = depth + (i - midPix[0]) * dzI +
284 (j - midPix[1]) * dzJ;
290 patchPoints[count] = refV->camPos + tmpDepth *
291 masterViewDirs[count];
298PatchSampler::computeMasterSamples()
304 std::size_t count = 0;
305 std::vector<math::Vec2i> imgPos(nrSamples);
306 for (
int j = topLeft[1]; j <= bottomRight[1]; ++j)
307 for (
int i = topLeft[0]; i <= bottomRight[0]; ++i)
309 imgPos[count][0] = i;
310 imgPos[count][1] = j;
316 for (std::size_t i = 0; i < nrSamples; ++i)
317 for (
int c = 0; c < 3; ++c)
319 assert(masterColorSamples[i][c] >= 0 &&
320 masterColorSamples[i][c] <= 1);
321 masterMeanCol += masterColorSamples[i][c];
324 masterMeanCol /= 3.f * nrSamples;
325 if (masterMeanCol < 0.01f || masterMeanCol > 0.99f) {
334 for (std::size_t i = 0; i < nrSamples; ++i)
336 masterColorSamples[i] /= masterMeanCol;
337 meanX += masterColorSamples[i];
343 for (std::size_t i = 0; i < nrSamples; ++i)
344 sqrDevX += (masterColorSamples[i] - meanX).square_norm();
348PatchSampler::computeNeighColorSamples(std::size_t v)
352 Samples & color = neighColorSamples[v];
359 float mfp = refV->footPrintScaled(p0);
360 float nfp = views[v]->footPrint(p0);
362 std::cerr <<
"Error in computeNeighColorSamples! "
363 <<
"footprint in master view: " << mfp << std::endl;
364 throw std::out_of_range(
"Negative pixel print");
368 float ratio = nfp / mfp;
371 while (ratio < 0.5f) {
375 mmLevel = views[v]->clampLevel(mmLevel);
377 int const w = img->width();
378 int const h = img->height();
380 color.resize(nrSamples);
381 imgPos.resize(nrSamples);
383 for (std::size_t i = 0; i < nrSamples; ++i) {
384 imgPos[i] = views[v]->worldToScreen(patchPoints[i], mmLevel);
386 if (!(imgPos[i][0] > 0 && imgPos[i][0] < w-1 &&
387 imgPos[i][1] > 0 && imgPos[i][1] < h-1)) {
Vector class for arbitrary dimensions and types.
Vector< T, N > cross(Vector< T, N > const &other) const
Cross product between this and another vector.
Vector< T, N > & fill(T const &value)
Fills all vector elements with the given value.
Vector< T, N > & normalize(void)
Normalizes self and returns reference to self.
std::shared_ptr< Image< T > const > ConstPtr
std::vector< bool > success
math::Vec3f getPatchNormal() const
void fastColAndDeriv(std::size_t v, Samples &color, Samples &deriv)
Draw color samples and derivatives in neighbor view v.
float getSSD(std::size_t v, math::Vec3f const &cs)
Computes the sum of squared differences between reference view and neighbor v with respect to color s...
void update(float newDepth, float newDzI, float newDzJ)
float getFastNCC(std::size_t v)
Compute NCC between reference view and a neighbor view.
float getNCC(std::size_t u, std::size_t v)
Compute NCC between two neighboring views.
float getSAD(std::size_t v, math::Vec3f const &cs)
Computes the sum of absolute differences between reference view and neighbor v with respect to color ...
std::shared_ptr< SingleView > Ptr
#define MVS_NAMESPACE_BEGIN
#define MVS_NAMESPACE_END
void colAndExactDeriv(mve::ByteImage const &img, PixelCoords const &imgPos, PixelCoords const &gradDir, Samples &color, Samples &deriv)
interpolate color and derivative at given sample positions
void getXYZColorAtPos(mve::ByteImage const &img, PixelCoords const &imgPos, Samples *color)
interpolate only color at given sample positions
std::vector< math::Vec3f > Samples
void getXYZColorAtPix(mve::ByteImage const &img, std::vector< math::Vec2i > const &imgPos, Samples *color)
get color at given pixel positions (no interpolation)
std::vector< math::Vec2f > PixelCoords
unsigned int filterWidth
Size of the patch is width * width, defaults to 5x5.
std::size_t refViewNr
The reference view ID to reconstruct.