Permalink
Browse files

Local homography, first part

  • Loading branch information...
1 parent e2f17c8 commit 105975a246b4ee710a9ed70b44105ab471d135ec @oleg-alexandrov oleg-alexandrov committed Apr 2, 2013
Showing with 298 additions and 259 deletions.
  1. +35 −0 src/asp/Core/LocalDisparity.cc
  2. +35 −0 src/asp/Core/LocalDisparity.h
  3. +55 −118 src/asp/Tools/stereo_corr.cc
  4. +173 −141 src/asp/Tools/stereo_rfne.cc
View
35 src/asp/Core/LocalDisparity.cc
@@ -0,0 +1,35 @@
+// __BEGIN_LICENSE__
+// Copyright (c) 2009-2012, United States Government as represented by the
+// Administrator of the National Aeronautics and Space Administration. All
+// rights reserved.
+//
+// The NGT platform is licensed under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance with the
+// License. You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// __END_LICENSE__
+
+
+/// \file LocalDisparity.cc
+///
+
+#include <vw/Image/ImageView.h>
+#include <vw/Image/Transform.h>
+#include <vw/FileIO/DiskImageView.h>
+#include <vw/Stereo/DisparityMap.h>
+#include <asp/Core/StereoSettings.h>
+#include <asp/Core/LocalDisparity.h>
+
+using namespace vw;
+using namespace vw::cartography;
+
+namespace asp {
+
+
+}
View
35 src/asp/Core/LocalDisparity.h
@@ -0,0 +1,35 @@
+// __BEGIN_LICENSE__
+// Copyright (c) 2009-2012, United States Government as represented by the
+// Administrator of the National Aeronautics and Space Administration. All
+// rights reserved.
+//
+// The NGT platform is licensed under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance with the
+// License. You may obtain a copy of the License at
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// __END_LICENSE__
+
+
+/// \file LocalDisparity.h
+///
+
+#ifndef __LOCAL_DISPARITY_H__
+#define __LOCAL_DISPARITY_H__
+
+// Forward declaration
+namespace asp {
+ class Options;
+}
+
+namespace asp {
+
+
+}
+
+#endif
View
173 src/asp/Tools/stereo_corr.cc
@@ -27,8 +27,8 @@
#include <vw/Stereo/CorrelationView.h>
#include <vw/Stereo/CostFunctions.h>
#include <vw/Stereo/DisparityMap.h>
-
#include <asp/Core/DemDisparity.h>
+#include <asp/Core/LocalDisparity.h>
using namespace vw;
using namespace vw::stereo;
@@ -91,10 +91,9 @@ void produce_lowres_disparity( Options & opt ) {
produce_dem_disparity(opt, left_camera_model, right_camera_model);
}
- ImageView<PixelMask<Vector2i> > lowres_disparity;
- read_image( lowres_disparity, opt.out_prefix + "-D_sub.tif" );
- search_range =
- stereo::get_disparity_range( lowres_disparity );
+ ImageView<PixelMask<Vector2i> > sub_disparity;
+ read_image( sub_disparity, opt.out_prefix + "-D_sub.tif" );
+ search_range = stereo::get_disparity_range( sub_disparity );
VW_OUT(DebugMessage,"asp") << "D_sub resolved search range: "
<< search_range << " px\n";
search_range.min() = floor(elem_quot(search_range.min(),downsample_scale));
@@ -183,94 +182,19 @@ void lowres_correlation( Options & opt ) {
produce_lowres_disparity( opt );
}
- vw_out() << "\n[ " << current_posix_time_string()
- << " ] : LOW-RESOLUTION CORRELATION FINISHED \n";
-}
-
-void split_n_into_k(int n, int k, std::vector<int> & partition){
-
- // We would like to split the numbers 0, ..., n - 1
- // into k buckets of approximately equal size.
- // For example, for n = 8 and k = 3, we will
- // have the split
- // {0, 1, 2}, {3, 4, 5}, {6, 7}.
-
- VW_ASSERT(n >= k && k > 0, ArgumentErr() << "split_n_into_k: Must have n >= k && k > 0.\n");
- int rem = n % k;
- int dx0 = n / k;
-
- partition.clear();
- int start = 0;
- for (int i = 0; i < k; i++){
- int dx = dx0;
- if (rem > 0){
- dx++;
- rem--;
- }
- partition.push_back(start);
- start += dx;
- }
- partition.push_back(start);
-
-}
-
-// Given a disparity map restricted to a subregion, find the homography
-// transform which aligns best the two images based on this disparity.
-template<class SeedDispT>
-Matrix<double> homography_for_disparity(BBox2i subregion,
- SeedDispT const& disparity){
-
- VW_ASSERT(subregion.width() == disparity.cols() &&
- subregion.height() == disparity.rows(),
- ArgumentErr() << "homography_for_disparity: "
- << "The sizes of subregion and disparity don't match.\n");
-
- // To do: Find the bounding box of the region with valid disparities first!
- // Even that one may not be enough!
-
- // We will split the subregion into N x N boxes, and average the
- // disparity in each box, to reduce the run-time.
- int N = 10;
-
- std::vector<int> partitionx, partitiony;
- split_n_into_k(disparity.cols(), std::min(disparity.cols(), N), partitionx);
- split_n_into_k(disparity.rows(), std::min(disparity.rows(), N), partitiony);
-
- std::vector<vw::ip::InterestPoint> left_ip, right_ip;
- for (int ix = 0; ix < (int)partitionx.size()-1; ix++){
- for (int iy = 0; iy < (int)partitiony.size()-1; iy++){
-
- // First sum up the disparities in each subbox.
- double lx = 0, ly = 0, rx = 0, ry = 0, count = 0; // int may cause overflow
- for (int x = partitionx[ix]; x < partitionx[ix+1]; x++){
- for (int y = partitiony[iy]; y < partitiony[iy+1]; y++){
-
- typename SeedDispT::pixel_type disp = disparity(x, y);
- if (!is_valid(disp)) continue;
- lx += x; rx += (x + disp.child().x());
- ly += y; ry += (y + disp.child().y());
- count++;
- }
- }
- if (count == 0) continue; // no valid points
-
- // Do the averaging. We must add the box corner to the left and
- // right interest points.
- vw::ip::InterestPoint l, r;
- l.x = subregion.min().x() + lx/count; r.x = subregion.min().x() + rx/count;
- l.y = subregion.min().y() + ly/count; r.y = subregion.min().y() + ry/count;
- left_ip.push_back(l);
- right_ip.push_back(r);
+ // Create the local homographies based on D_sub
+ if (stereo_settings().use_local_homography){
+ std::string local_hom_file = opt.out_prefix + "-local_hom.txt";
+ try {
+ ImageView<Matrix3x3> local_hom;
+ read_local_homographies(local_hom_file, local_hom);
+ } catch (vw::IOErr const& e) {
+ create_local_homographies(opt);
}
}
- try {
- return homography_fit(right_ip, left_ip, bounding_box(disparity));
- }catch ( const ArgumentErr& e ){
- // Will return the identity matrix.
- }
- return math::identity_matrix<3>();
-
+ vw_out() << "\n[ " << current_posix_time_string()
+ << " ] : LOW-RESOLUTION CORRELATION FINISHED \n";
}
// This correlator takes a low resolution disparity image as an input
@@ -284,6 +208,7 @@ class SeededCorrelatorView : public ImageViewBase<SeededCorrelatorView<Image1T,
Mask2T m_right_mask;
SeedDispT m_sub_disparity;
SeedDispT m_sub_disparity_spread;
+ ImageView<Matrix3x3> const& m_local_hom;
PProcT m_preproc_func;
// Settings
@@ -299,14 +224,16 @@ class SeededCorrelatorView : public ImageViewBase<SeededCorrelatorView<Image1T,
ImageViewBase<Mask2T> const& right_mask,
ImageViewBase<SeedDispT> const& sub_disparity,
ImageViewBase<SeedDispT> const& sub_disparity_spread,
+ ImageView<Matrix3x3> const& local_hom,
stereo::PreFilterBase<PProcT> const& filter,
BBox2i left_image_crop_win,
stereo::CostFunctionType cost_mode ) :
m_left_image(left_image.impl()), m_right_image(right_image.impl()),
m_left_mask(left_mask.impl()), m_right_mask(right_mask.impl()),
m_sub_disparity( sub_disparity.impl() ),
m_sub_disparity_spread( sub_disparity_spread.impl() ),
- m_preproc_func( filter.impl() ), m_left_image_crop_win(left_image_crop_win), m_cost_mode(cost_mode) {
+ m_local_hom(local_hom), m_preproc_func( filter.impl() ),
+ m_left_image_crop_win(left_image_crop_win), m_cost_mode(cost_mode) {
m_upscale_factor[0] = float(m_left_image.cols()) / float(m_sub_disparity.cols());
m_upscale_factor[1] = float(m_left_image.rows()) / float(m_sub_disparity.rows());
m_seed_bbox = bounding_box( m_sub_disparity );
@@ -364,33 +291,29 @@ class SeededCorrelatorView : public ImageViewBase<SeededCorrelatorView<Image1T,
ImageViewRef<typename Image2T::pixel_type> right_trans_img;
ImageViewRef<typename Mask2T::pixel_type> right_trans_mask;
+ bool do_round = true; // round integer disparities after transform
+
// User strategies
BBox2f local_search_range;
if ( stereo_settings().seed_mode == 1 || stereo_settings().seed_mode == 2 ) {
// The low-res version of bbox
BBox2i seed_bbox( elem_quot(bbox.min(), m_upscale_factor),
elem_quot(bbox.max(), m_upscale_factor) );
- if (use_local_homography){
- // Expand the box until square to make sure the local homography
- // calculation does not fail.
- int len = std::max(seed_bbox.width(), seed_bbox.height());
- seed_bbox = BBox2i(seed_bbox.max() - Vector2(len, len), seed_bbox.max());
- }
-
seed_bbox.expand(1);
seed_bbox.crop( m_seed_bbox );
VW_OUT(DebugMessage, "stereo") << "Getting disparity range for : "
<< seed_bbox << "\n";
-
SeedDispT disparity_in_box = crop( m_sub_disparity, seed_bbox );
if (!use_local_homography){
local_search_range = stereo::get_disparity_range( disparity_in_box );
}else{
- lowres_hom = homography_for_disparity(seed_bbox, disparity_in_box);
+ int ts = Options::corr_tile_size();
+ lowres_hom = m_local_hom(bbox.min().x()/ts, bbox.min().y()/ts);
local_search_range = stereo::get_disparity_range
- (transform_disparities(seed_bbox, lowres_hom, disparity_in_box));
+ (transform_disparities(do_round, seed_bbox,
+ lowres_hom, disparity_in_box));
}
if (stereo_settings().seed_mode == 2){
@@ -405,10 +328,10 @@ class SeededCorrelatorView : public ImageViewBase<SeededCorrelatorView<Image1T,
local_search_range.max() += spread.max();
}else{
SeedDispT upper_disp
- = transform_disparities(seed_bbox, lowres_hom,
+ = transform_disparities(do_round, seed_bbox, lowres_hom,
disparity_in_box + spread_in_box);
SeedDispT lower_disp
- = transform_disparities(seed_bbox, lowres_hom,
+ = transform_disparities(do_round, seed_bbox, lowres_hom,
disparity_in_box - spread_in_box);
BBox2f upper_range = stereo::get_disparity_range(upper_disp);
BBox2f lower_range = stereo::get_disparity_range(lower_disp);
@@ -424,13 +347,15 @@ class SeededCorrelatorView : public ImageViewBase<SeededCorrelatorView<Image1T,
fullres_hom = diagonal_matrix(upscale)*lowres_hom*diagonal_matrix(dnscale);
ImageViewRef< PixelMask<typename Image2T::pixel_type> >
- right_trans_masked_img = transform (copy_mask( m_right_image.impl(),
- create_mask(m_right_mask.impl()) ),
- HomographyTransform(fullres_hom),
- m_left_image.impl().cols(),
- m_left_image.impl().rows());
- right_trans_img = apply_mask(right_trans_masked_img);
- right_trans_mask = channel_cast_rescale<uint8>(select_channel(right_trans_masked_img, 1));
+ right_trans_masked_img
+ = transform (copy_mask( m_right_image.impl(),
+ create_mask(m_right_mask.impl()) ),
+ HomographyTransform(fullres_hom),
+ m_left_image.impl().cols(),
+ m_left_image.impl().rows());
+ right_trans_img = apply_mask(right_trans_masked_img);
+ right_trans_mask
+ = channel_cast_rescale<uint8>(select_channel(right_trans_masked_img, 1));
}
local_search_range = grow_bbox_to_int(local_search_range);
@@ -451,7 +376,8 @@ class SeededCorrelatorView : public ImageViewBase<SeededCorrelatorView<Image1T,
} else if ( stereo_settings().seed_mode == 0 ) {
local_search_range = stereo_settings().search_range;
- VW_OUT(DebugMessage,"stereo") << "Searching with " << stereo_settings().search_range << "\n";
+ VW_OUT(DebugMessage,"stereo") << "Searching with "
+ << stereo_settings().search_range << "\n";
}else{
vw_throw( ArgumentErr() << "stereo_corr: Invalid value for seed-mode: "
<< stereo_settings().seed_mode << ".\n" );
@@ -466,7 +392,7 @@ class SeededCorrelatorView : public ImageViewBase<SeededCorrelatorView<Image1T,
stereo_settings().xcorr_threshold,
stereo_settings().corr_max_levels );
return prerasterize_type
- (transform_disparities(bbox, inverse(fullres_hom),
+ (transform_disparities(do_round, bbox, inverse(fullres_hom),
crop(corr_view.prerasterize(bbox), bbox)),
-bbox.min().x(), -bbox.min().y(),
cols(), rows() );
@@ -496,12 +422,14 @@ seeded_correlation( ImageViewBase<Image1T> const& left,
ImageViewBase<Mask2T> const& rmask,
ImageViewBase<SeedDispT> const& sub_disparity,
ImageViewBase<SeedDispT> const& sub_disparity_spread,
+ ImageView<Matrix3x3> const& local_hom,
stereo::PreFilterBase<PProcT> const& filter,
BBox2i left_image_crop_win,
stereo::CostFunctionType cost_type ) {
typedef SeededCorrelatorView<Image1T, Image2T, Mask1T, Mask2T, SeedDispT, PProcT> return_type;
return return_type( left.impl(), right.impl(), lmask.impl(), rmask.impl(),
- sub_disparity.impl(), sub_disparity_spread.impl(), filter.impl(), left_image_crop_win, cost_type );
+ sub_disparity.impl(), sub_disparity_spread.impl(),
+ local_hom, filter.impl(), left_image_crop_win, cost_type );
}
void stereo_correlation( Options& opt ) {
@@ -541,6 +469,11 @@ void stereo_correlation( Options& opt ) {
sub_disparity_spread =
DiskImageView<PixelMask<Vector2i> >(opt.out_prefix+"-D_sub_spread.tif");
ImageViewRef<PixelMask<Vector2i> > fullres_disparity;
+ ImageView<Matrix3x3> local_hom;
+ if ( stereo_settings().use_local_homography ){
+ std::string local_hom_file = opt.out_prefix + "-local_hom.txt";
+ read_local_homographies(local_hom_file, local_hom);
+ }
DiskImageView<vw::uint8> Lmask(opt.out_prefix + "-lMask.tif"),
Rmask(opt.out_prefix + "-rMask.tif");
@@ -556,20 +489,23 @@ void stereo_correlation( Options& opt ) {
vw_out() << "\t--> Using LOG pre-processing filter with "
<< stereo_settings().slogW << " sigma blur.\n";
fullres_disparity =
- seeded_correlation( left_disk_image, right_disk_image, Lmask, Rmask, sub_disparity, sub_disparity_spread,
+ seeded_correlation( left_disk_image, right_disk_image, Lmask, Rmask,
+ sub_disparity, sub_disparity_spread, local_hom,
stereo::LaplacianOfGaussian(stereo_settings().slogW), opt.left_image_crop_win,
cost_mode );
} else if ( stereo_settings().pre_filter_mode == 1 ) {
vw_out() << "\t--> Using Subtracted Mean pre-processing filter with "
<< stereo_settings().slogW << " sigma blur.\n";
fullres_disparity =
- seeded_correlation( left_disk_image, right_disk_image, Lmask, Rmask, sub_disparity, sub_disparity_spread,
+ seeded_correlation( left_disk_image, right_disk_image, Lmask, Rmask,
+ sub_disparity, sub_disparity_spread, local_hom,
stereo::SubtractedMean(stereo_settings().slogW), opt.left_image_crop_win,
cost_mode );
} else {
vw_out() << "\t--> Using NO pre-processing filter." << std::endl;
fullres_disparity =
- seeded_correlation( left_disk_image, right_disk_image, Lmask, Rmask, sub_disparity, sub_disparity_spread,
+ seeded_correlation( left_disk_image, right_disk_image, Lmask, Rmask,
+ sub_disparity, sub_disparity_spread, local_hom,
stereo::NullOperation(), opt.left_image_crop_win,
cost_mode );
}
@@ -591,9 +527,10 @@ int main(int argc, char* argv[]) {
handle_arguments( argc, argv, opt,
CorrelationDescription() );
- // Integer correlator requires 1024 px tiles
+ // Integer correlator requires large tiles
//---------------------------------------------------------
- opt.raster_tile_size = Vector2i(1024,1024);
+ int ts = Options::corr_tile_size();
+ opt.raster_tile_size = Vector2i(ts, ts);
// Internal Processes
//---------------------------------------------------------
View
314 src/asp/Tools/stereo_rfne.cc
@@ -33,179 +33,211 @@ namespace vw {
template<> struct PixelFormatID<PixelMask<Vector<float, 5> > > { static const PixelFormatEnum value = VW_PIXEL_GENERIC_6_CHANNEL; };
}
-template <class ImageT>
-class SelectiveRasterView : public ImageViewBase< SelectiveRasterView<ImageT> > {
- ImageT m_image;
- BBox2i m_left_image_crop_win;
-
-public:
- SelectiveRasterView( ImageViewBase<ImageT> const& image,
- BBox2i left_image_crop_win ) :
- m_image( image.impl() ), m_left_image_crop_win( left_image_crop_win ) {}
-
- typedef typename ImageT::pixel_type pixel_type;
- typedef typename ImageT::result_type result_type;
- typedef typename ImageT::pixel_accessor pixel_accessor;
+template <class Image1T, class Image2T>
+ImageViewRef<PixelMask<Vector2f> >
+refine_disparity(Image1T const& left_image,
+ Image2T const& right_image,
+ ImageViewRef< PixelMask<Vector2i> > const& integer_disp,
+ Options const& opt){
+
+ ImageViewRef<PixelMask<Vector2f> > refined_disp =
+ pixel_cast<PixelMask<Vector2f> >(integer_disp);
+
+ if (stereo_settings().subpixel_mode == 0) {
+ // Do nothing
+ } else if (stereo_settings().subpixel_mode == 1) {
+ // Parabola
+ vw_out() << "\t--> Using parabola subpixel mode.\n";
+ if (stereo_settings().pre_filter_mode == 2) {
+ vw_out() << "\t--> Using LOG pre-processing filter with "
+ << stereo_settings().slogW << " sigma blur.\n";
+ typedef stereo::LaplacianOfGaussian PreFilter;
+ refined_disp =
+ parabola_subpixel( integer_disp,
+ left_image, right_image,
+ PreFilter(stereo_settings().slogW),
+ stereo_settings().subpixel_kernel );
+ } else if (stereo_settings().pre_filter_mode == 1) {
+ vw_out() << "\t--> Using Subtracted Mean pre-processing filter with "
+ << stereo_settings().slogW << " sigma blur.\n";
+ typedef stereo::SubtractedMean PreFilter;
+ refined_disp =
+ parabola_subpixel( integer_disp,
+ left_image, right_image,
+ PreFilter(stereo_settings().slogW),
+ stereo_settings().subpixel_kernel );
+ } else {
+ vw_out() << "\t--> NO preprocessing" << std::endl;
+ typedef stereo::NullOperation PreFilter;
+ refined_disp =
+ parabola_subpixel( integer_disp,
+ left_image, right_image,
+ PreFilter(),
+ stereo_settings().subpixel_kernel );
+ }
+ } else if (stereo_settings().subpixel_mode == 2) {
+ // Bayes EM
+ vw_out() << "\t--> Using affine adaptive subpixel mode\n";
+ vw_out() << "\t--> Forcing use of LOG filter with "
+ << stereo_settings().slogW << " sigma blur.\n";
+ typedef stereo::LaplacianOfGaussian PreFilter;
+ refined_disp =
+ bayes_em_subpixel( integer_disp,
+ left_image, right_image,
+ PreFilter(stereo_settings().slogW),
+ stereo_settings().subpixel_kernel,
+ stereo_settings().subpixel_max_levels );
+
+ } else if (stereo_settings().subpixel_mode == 3) {
+ // Affine and Bayes subpixel refinement always use the
+ // LogPreprocessingFilter...
+ vw_out() << "\t--> Using EM Subpixel mode "
+ << stereo_settings().subpixel_mode << std::endl;
+ vw_out() << "\t--> Mode 3 does internal preprocessing;"
+ << " settings will be ignored. " << std::endl;
+
+ typedef stereo::EMSubpixelCorrelatorView<float32> EMCorrelator;
+ EMCorrelator em_correlator(channels_to_planes(left_image),
+ channels_to_planes(right_image),
+ pixel_cast<PixelMask<Vector2f> >(integer_disp), -1);
+ em_correlator.set_em_iter_max(stereo_settings().subpixel_em_iter);
+ em_correlator.set_inner_iter_max(stereo_settings().subpixel_affine_iter);
+ em_correlator.set_kernel_size(stereo_settings().subpixel_kernel);
+ em_correlator.set_pyramid_levels(stereo_settings().subpixel_pyramid_levels);
+
+ DiskImageResourceOpenEXR em_disparity_map_rsrc(opt.out_prefix + "-F6.exr", em_correlator.format());
+
+ block_write_image(em_disparity_map_rsrc, em_correlator,
+ TerminalProgressCallback("asp", "\t--> EM Refinement :"));
+
+ DiskImageResource *em_disparity_map_rsrc_2 =
+ DiskImageResourceOpenEXR::construct_open(opt.out_prefix + "-F6.exr");
+ DiskImageView<PixelMask<Vector<float, 5> > > em_disparity_disk_image(em_disparity_map_rsrc_2);
+
+ ImageViewRef<Vector<float, 3> > disparity_uncertainty =
+ per_pixel_filter(em_disparity_disk_image,
+ EMCorrelator::ExtractUncertaintyFunctor());
+ ImageViewRef<float> spectral_uncertainty =
+ per_pixel_filter(disparity_uncertainty,
+ EMCorrelator::SpectralRadiusUncertaintyFunctor());
+ write_image(opt.out_prefix+"-US.tif", spectral_uncertainty);
+ write_image(opt.out_prefix+"-U.tif", disparity_uncertainty);
+
+ refined_disp =
+ per_pixel_filter(em_disparity_disk_image,
+ EMCorrelator::ExtractDisparityFunctor());
+ } else {
+ vw_out() << "\t--> Invalid Subpixel mode selection: " << stereo_settings().subpixel_mode << std::endl;
+ vw_out() << "\t--> Doing nothing\n";
+ }
- inline int32 cols() const { return m_image.cols(); }
- inline int32 rows() const { return m_image.rows(); }
- inline int32 planes() const { return m_image.planes(); }
+ return refined_disp;
+}
- inline pixel_accessor origin() const { return m_image.origin(); }
+// Perform refinement in each tile. If using local homography,
+// apply the local homography transform for the given tile
+// to the right image before doing refinement in that tile.
+template <class Image1T, class Image2T, class SeedDispT>
+class PerTileRfne: public ImageViewBase<PerTileRfne<Image1T, Image2T, SeedDispT> >{
+ Image1T m_left_image;
+ Image2T m_right_image;
+ SeedDispT m_integer_disp;
+ Options & m_opt;
- inline result_type operator()( int32 i, int32 j, int32 p = 0 ) const {
- return m_image( i, j, p );
+public:
+ PerTileRfne( ImageViewBase<Image1T> const& left_image,
+ ImageViewBase<Image2T> const& right_image,
+ ImageViewBase<SeedDispT> const& integer_disp,
+ Options & opt):
+ m_left_image(left_image.impl()), m_right_image(right_image.impl()),
+ m_integer_disp( integer_disp.impl() ),
+ m_opt(opt){}
+
+ // Image View interface
+ typedef PixelMask<Vector2f> pixel_type;
+ typedef pixel_type result_type;
+ typedef ProceduralPixelAccessor<PerTileRfne> pixel_accessor;
+
+ inline int32 cols() const { return m_left_image.cols(); }
+ inline int32 rows() const { return m_left_image.rows(); }
+ inline int32 planes() const { return 1; }
+
+ inline pixel_accessor origin() const { return pixel_accessor( *this, 0, 0 ); }
+
+ inline pixel_type operator()( double /*i*/, double /*j*/, int32 /*p*/ = 0 ) const {
+ vw_throw(NoImplErr() << "PerTileRfne::operator()(...) is not implemented");
+ return pixel_type();
}
typedef CropView<ImageView<pixel_type> > prerasterize_type;
inline prerasterize_type prerasterize(BBox2i const& bbox) const {
- // We do stereo only in m_left_image_crop_win. Skip the current tile if
+
+ // We do stereo only in left_image_crop_win. Skip the current tile if
// it does not intersect this region.
- BBox2i intersection = bbox; intersection.crop(m_left_image_crop_win);
+ BBox2i left_image_crop_win = m_opt.left_image_crop_win;
+ BBox2i intersection = bbox; intersection.crop(left_image_crop_win);
if (intersection.empty()){
return prerasterize_type(ImageView<pixel_type>(bbox.width(),
bbox.height()),
-bbox.min().x(), -bbox.min().y(),
cols(), rows() );
}
- ImageView<pixel_type> output =
- crop( m_image.prerasterize( bbox ), bbox );
- return prerasterize_type( output, -bbox.min().x(), -bbox.min().y(),
- cols(), rows() );
+ CropView<ImageView<pixel_type> > disparity
+ = prerasterize_type(crop(refine_disparity(m_left_image, m_right_image,
+ m_integer_disp, m_opt),
+ bbox),
+ -bbox.min().x(), -bbox.min().y(),
+ cols(), rows() );
+
+ // Set to invalid the disparity outside left_image_crop_win.
+ for (int col = bbox.min().x(); col < bbox.max().x(); col++){
+ for (int row = bbox.min().y(); row < bbox.max().y(); row++){
+ if (!left_image_crop_win.contains(Vector2(col, row))){
+ disparity(col, row) = pixel_type();
+ }
+ }
+ }
+
+ return disparity;
}
template <class DestT>
- inline void rasterize( DestT const& dest, BBox2i const& bbox ) const {
+ inline void rasterize(DestT const& dest, BBox2i bbox) const {
vw::rasterize(prerasterize(bbox), dest, bbox);
}
};
-template <class ImageT>
-SelectiveRasterView<ImageT>
-selective_rasterize( ImageViewBase<ImageT> const& image,
- BBox2i const& left_crop ) {
- return SelectiveRasterView<ImageT>( image.impl(), left_crop );
+template <class Image1T, class Image2T, class SeedDispT>
+PerTileRfne<Image1T, Image2T, SeedDispT>
+per_tile_rfne( ImageViewBase<Image1T> const& left,
+ ImageViewBase<Image2T> const& right,
+ ImageViewBase<SeedDispT> const& integer_disp,
+ Options opt) {
+ typedef PerTileRfne<Image1T, Image2T, SeedDispT> return_type;
+ return return_type( left.impl(), right.impl(), integer_disp.impl(), opt );
}
void stereo_refinement( Options& opt ) {
vw_out() << "\n[ " << current_posix_time_string() << " ] : Stage 2 --> REFINEMENT \n";
+ ImageViewRef<PixelGray<float> > left_disk_image, right_disk_image;
+ ImageViewRef<PixelMask<Vector2i> > integer_disp;
try {
- std::string filename_L = opt.out_prefix+"-L.tif",
- filename_R = opt.out_prefix+"-R.tif";
- /*
- if (MEDIAN_FILTER == 1){
- filename_L = out_prefix+"-median-L.tif";
- filename_R = out_prefix+"-median-R.tif";
- } else {
- filename_L = out_prefix+"-L.tif";
- filename_R = out_prefix+"-R.tif";
- }
- */
- typedef DiskImageView<PixelGray<float> > InnerView;
- InnerView left_disk_image(filename_L), right_disk_image(filename_R);
- DiskImageView<PixelMask<Vector2i> > disparity_disk_image(opt.out_prefix + "-D.tif");
- ImageViewRef<PixelMask<Vector2f> > disparity_map =
- pixel_cast<PixelMask<Vector2f> >(disparity_disk_image);
-
- if (stereo_settings().subpixel_mode == 0) {
- // Do nothing
- } else if (stereo_settings().subpixel_mode == 1) {
- // Parabola
- vw_out() << "\t--> Using parabola subpixel mode.\n";
- if (stereo_settings().pre_filter_mode == 2) {
- vw_out() << "\t--> Using LOG pre-processing filter with "
- << stereo_settings().slogW << " sigma blur.\n";
- typedef stereo::LaplacianOfGaussian PreFilter;
- disparity_map =
- parabola_subpixel( disparity_disk_image,
- left_disk_image, right_disk_image,
- PreFilter(stereo_settings().slogW),
- stereo_settings().subpixel_kernel );
- } else if (stereo_settings().pre_filter_mode == 1) {
- vw_out() << "\t--> Using Subtracted Mean pre-processing filter with "
- << stereo_settings().slogW << " sigma blur.\n";
- typedef stereo::SubtractedMean PreFilter;
- disparity_map =
- parabola_subpixel( disparity_disk_image,
- left_disk_image, right_disk_image,
- PreFilter(stereo_settings().slogW),
- stereo_settings().subpixel_kernel );
- } else {
- vw_out() << "\t--> NO preprocessing" << std::endl;
- typedef stereo::NullOperation PreFilter;
- disparity_map =
- parabola_subpixel( disparity_disk_image,
- left_disk_image, right_disk_image,
- PreFilter(),
- stereo_settings().subpixel_kernel );
- }
- } else if (stereo_settings().subpixel_mode == 2) {
- // Bayes EM
- vw_out() << "\t--> Using affine adaptive subpixel mode\n";
- vw_out() << "\t--> Forcing use of LOG filter with "
- << stereo_settings().slogW << " sigma blur.\n";
- typedef stereo::LaplacianOfGaussian PreFilter;
- disparity_map =
- bayes_em_subpixel( disparity_disk_image,
- left_disk_image, right_disk_image,
- PreFilter(stereo_settings().slogW),
- stereo_settings().subpixel_kernel,
- stereo_settings().subpixel_max_levels );
-
- } else if (stereo_settings().subpixel_mode == 3) {
- // Affine and Bayes subpixel refinement always use the
- // LogPreprocessingFilter...
- vw_out() << "\t--> Using EM Subpixel mode "
- << stereo_settings().subpixel_mode << std::endl;
- vw_out() << "\t--> Mode 3 does internal preprocessing;"
- << " settings will be ignored. " << std::endl;
-
- typedef stereo::EMSubpixelCorrelatorView<float32> EMCorrelator;
- EMCorrelator em_correlator(channels_to_planes(left_disk_image),
- channels_to_planes(right_disk_image),
- pixel_cast<PixelMask<Vector2f> >(disparity_disk_image), -1);
- em_correlator.set_em_iter_max(stereo_settings().subpixel_em_iter);
- em_correlator.set_inner_iter_max(stereo_settings().subpixel_affine_iter);
- em_correlator.set_kernel_size(stereo_settings().subpixel_kernel);
- em_correlator.set_pyramid_levels(stereo_settings().subpixel_pyramid_levels);
-
- DiskImageResourceOpenEXR em_disparity_map_rsrc(opt.out_prefix + "-F6.exr", em_correlator.format());
-
- block_write_image(em_disparity_map_rsrc, em_correlator,
- TerminalProgressCallback("asp", "\t--> EM Refinement :"));
-
- DiskImageResource *em_disparity_map_rsrc_2 =
- DiskImageResourceOpenEXR::construct_open(opt.out_prefix + "-F6.exr");
- DiskImageView<PixelMask<Vector<float, 5> > > em_disparity_disk_image(em_disparity_map_rsrc_2);
-
- ImageViewRef<Vector<float, 3> > disparity_uncertainty =
- per_pixel_filter(em_disparity_disk_image,
- EMCorrelator::ExtractUncertaintyFunctor());
- ImageViewRef<float> spectral_uncertainty =
- per_pixel_filter(disparity_uncertainty,
- EMCorrelator::SpectralRadiusUncertaintyFunctor());
- write_image(opt.out_prefix+"-US.tif", spectral_uncertainty);
- write_image(opt.out_prefix+"-U.tif", disparity_uncertainty);
-
- disparity_map =
- per_pixel_filter(em_disparity_disk_image,
- EMCorrelator::ExtractDisparityFunctor());
- } else {
- vw_out() << "\t--> Invalid Subpixel mode selection: " << stereo_settings().subpixel_mode << std::endl;
- vw_out() << "\t--> Doing nothing\n";
- }
-
- asp::block_write_gdal_image( opt.out_prefix + "-RD.tif",
- selective_rasterize(disparity_map,
- opt.left_image_crop_win), opt,
- TerminalProgressCallback("asp", "\t--> Refinement :") );
-
+ left_disk_image = DiskImageView< PixelGray<float> >(opt.out_prefix+"-L.tif");
+ right_disk_image = DiskImageView< PixelGray<float> >(opt.out_prefix+"-R.tif");
+ integer_disp = DiskImageView< PixelMask<Vector2i> >(opt.out_prefix + "-D.tif");
} catch (IOErr const& e) {
vw_throw( ArgumentErr() << "\nUnable to start at refinement stage -- could not read input files.\n" << e.what() << "\nExiting.\n\n" );
}
+
+ ImageViewRef< PixelMask<Vector2f> > refined_disp
+ = per_tile_rfne(left_disk_image, right_disk_image, integer_disp, opt);
+
+ asp::block_write_gdal_image( opt.out_prefix + "-RD.tif",
+ refined_disp, opt,
+ TerminalProgressCallback("asp", "\t--> Refinement :") );
}
int main(int argc, char* argv[]) {

0 comments on commit 105975a

Please sign in to comment.