Skip to content

Commit

Permalink
SGM: Improved ROI handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ScottMcMichael committed Aug 31, 2016
1 parent ce9f324 commit a1d6d91
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 29 deletions.
42 changes: 30 additions & 12 deletions src/vw/Stereo/SGM.cc
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void SemiGlobalMatcher::evaluate_path(
// Get something reasonable here, don't want to spend too much time tweaking up front.

// TODO!

/*
AccumCostType penalty = 0;
if ( disparity_diff == 0 ) {
// No penalty, zero integer disparity
Expand All @@ -91,11 +91,11 @@ void SemiGlobalMatcher::evaluate_path(
// the smaller the assessed penalty is for a disparity jump.
penalty = std::max(PENALTY1, path_intensity_gradient ? PENALTY2/path_intensity_gradient : PENALTY2);
}

*/

//// TODO: Consider intensity diff?
//const AccumCostType P_A = 20; // TODO: This needs to be related to the local cost sizes!
//AccumCostType penalty = disparity_diff * P_A;
// TODO: Consider intensity diff?
const AccumCostType P_A = 20; // TODO: This needs to be related to the local cost sizes!
AccumCostType penalty = disparity_diff * P_A;



Expand Down Expand Up @@ -131,7 +131,7 @@ void SemiGlobalMatcher::evaluate_path(



ImageView<Vector<SemiGlobalMatcher::DisparityType,2> >
SemiGlobalMatcher::DisparityImage
SemiGlobalMatcher::create_disparity_view( boost::shared_array<AccumCostType> const accumulated_costs ) {
// Init output vector
ImageView<Vector<DisparityType,2> > disparity( m_num_output_cols, m_num_output_rows );
Expand Down Expand Up @@ -181,9 +181,9 @@ SemiGlobalMatcher::CostType SemiGlobalMatcher::get_cost(ImageView<uint8> const&
return CostType(sum);
}

ImageView<Vector<SemiGlobalMatcher::DisparityType,2> >
SemiGlobalMatcher::DisparityImage
SemiGlobalMatcher::semi_global_matching_func( ImageView<uint8> const& left_image,
ImageView<uint8> const& right_image ) {
ImageView<uint8> const& right_image ) {

std::cout << "Init!\n";

Expand Down Expand Up @@ -214,22 +214,40 @@ SemiGlobalMatcher::semi_global_matching_func( ImageView<uint8> const& left_image
{
Timer timer("\tCost Calculation");

const int half_kernel_size = (m_kernel_size-1) / 2;
// Compute safe bounds to search through.
// - Any location we don't compute a cost for defaults to the max cost,
// essentially ignoring that location.
// -

const int half_kernel_size = (m_kernel_size-1) / 2;

int min_row = half_kernel_size - m_min_disp_y; // Assumes the (0,0) pixels are aligned
int min_col = half_kernel_size - m_min_disp_x;
int max_row = std::min(left_image.rows() - half_kernel_size,
right_image.rows() - (half_kernel_size + m_max_disp_y) );
int max_col = std::min(left_image.cols() - half_kernel_size,
right_image.cols() - (half_kernel_size + m_max_disp_x) );
if (min_row < 0) min_row = 0;
if (min_col < 0) min_col = 0;
if (max_row > left_image.rows()) min_row = left_image.rows();
if (max_col > left_image.cols()) min_col = left_image.cols();

std::cout << "Computed cost bounding box: " << std::endl;
printf("min_row = %d, min_col = %d, max_row = %d, max_col = %d\n", min_row, min_col, max_row, max_col);

size_t d=0;
for ( int dy = m_min_disp_y; dy <= m_max_disp_y; dy++ ) { // For each disparity
for ( int dx = m_min_disp_x; dx <= m_max_disp_x; dx++ ) {

// Make sure we don't go out of bounds here due to the disparity shift and kernel.
for ( int j = half_kernel_size; j < (size.y()-half_kernel_size)-dy; j++ ) { // For each row in left
for ( int i = half_kernel_size; i < (size.x()-half_kernel_size)-dx; i++ ) { // For each column in left
for ( int j = min_row; j < max_row; j++ ) { // For each row in left
for ( int i = min_col; i < max_col; i++ ) { // For each column in left

// Currently this computes only the SINGLE PIXEL difference.
// Could improve results by converting to block matching around the center pixel.

// TODO: Add or subtract the disparity?
bool debug = ((i == 219) && (j == 173));
bool debug = ((i == 73) && (j == 159));
size_t cost_index = get_cost_index(i, j, d);
m_cost_buffer[cost_index] = get_cost(left_image, right_image, i, j, i+dx,j+dy, debug);

Expand Down
14 changes: 11 additions & 3 deletions src/vw/Stereo/SGM.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ namespace vw {

/* TODO LIST
- Increase speed, it is way too slow!
- Support min and max disparity range set on the fly.
- Clean up interfaces/ROI handling.
- Handle non-uint8 input images.
- Integrate with disparity code as an option for the low-
resolution disparity search.
NOTES:
- Using a block size in the initial cost calculation does not seem to improve the results.
Instead it gives splotchy output. No real effect on speed.
- All the required time is in the path iteration functions!
*/


Expand All @@ -33,6 +39,8 @@ class SemiGlobalMatcher {
typedef int16 CostType; ///< Used to describe a single disparity cost.
typedef int32 AccumCostType; ///< Used to accumulate CostType values.

typedef ImageView<Vector<DisparityType,2> > DisparityImage;

public: // Functions

// Set the parameters to be used for future SGM calls
Expand All @@ -41,7 +49,7 @@ class SemiGlobalMatcher {
int kernel_size);

/// Invokes a 8 path version of SGM
ImageView<Vector<DisparityType,2> >
DisparityImage
semi_global_matching_func( ImageView<uint8> const& left_image,
ImageView<uint8> const& right_image );

Expand Down Expand Up @@ -91,7 +99,7 @@ class SemiGlobalMatcher {


/// Goes across all the viterbi diagrams and extracts out the minimum vector.
ImageView<Vector<DisparityType,2> >
DisparityImage
create_disparity_view( boost::shared_array<AccumCostType> const accumulated_costs );

/// Converts from a linear disparity index to the dx, dy values it represents.
Expand Down
45 changes: 31 additions & 14 deletions src/vw/Stereo/tests/TestSGM.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,16 @@ using namespace vw::stereo;
TEST( SGM, basic ) {

/*
// For this example, the disparity is (2,1) for each pixel!
// For this perfect test case, the correct disparity is (2,1) for each pixel!
int min_disp_x = -4;
int max_disp_x = 4;
int min_disp_y = -3;
int max_disp_y = 3;
int kernel_size = 1;
DiskImageView<PixelGray<uint8> > inputLeft ("left.tif");
DiskImageView<PixelGray<uint8> > inputRight("left_shift.tif");
BBox2i leftRoi (0,0,400, 400);
BBox2i rightRoi(0,0,400+dx, 400+dy);
BBox2i rightRoi(0,0,400, 400);
*/
/*
DiskImageView<PixelGray<uint8> > inputLeft ("left4.tif");
Expand All @@ -45,43 +50,55 @@ TEST( SGM, basic ) {
BBox2i rightRoi(0,0,80+dx, 80+dy);
*/
/*
int min_disp_x = -2;
int max_disp_x = 10;
int min_disp_y = -2;
int max_disp_y = 12;
int kernel_size = 1;
DiskImageView<PixelGray<uint8> > inputLeft ("left3.tif");
DiskImageView<PixelGray<uint8> > inputRight("right3.tif");
BBox2i leftRoi (0,0,200, 200);
BBox2i rightRoi(0,0,200+dx, 200+dy);
*/
/*
DiskImageView<PixelGray<uint8> > inputLeft ("moc_right.tif");
DiskImageView<PixelGray<uint8> > inputRight("moc_left.tif");
BBox2i leftRoi (0,0,300, 300);
BBox2i rightRoi(0,0,300+dx, 300+dy);
BBox2i rightRoi(0,0,200, 200);
*/

// The results may actually be pretty good except for the border region.
int min_disp_x = -5;
int max_disp_x = 5;
int min_disp_y = -5;
int max_disp_y = 5;
int kernel_size = 1;
DiskImageView<PixelGray<uint8> > inputLeft ("moc_left_u8.tif");
DiskImageView<PixelGray<uint8> > inputRight("moc_right_u8.tif");
BBox2i leftRoi (0,0,340, 340);
BBox2i rightRoi(0,0,340, 340);

/*
// Note that the matches have higher column values in the left image.
// X disparities are in the 0-140 range, y is 0 disparity.
// - Results are similar to the
int min_disp_x = 30;
int max_disp_x = 140;
int min_disp_y = 0;
int max_disp_y = 0;
int kernel_size = 5;
int kernel_size = 1;
DiskImageView<PixelGray<uint8> > inputLeft ("cones_right.pgm");
DiskImageView<PixelGray<uint8> > inputRight("cones_left.pgm");
BBox2i leftRoi (0,0,700, 200);
BBox2i rightRoi(0,0,700+max_disp_x, 200+max_disp_y);

*/


ImageView<uint8> left = crop(inputLeft, leftRoi);
ImageView<uint8> right = crop(inputRight, rightRoi);

//write_image("left_in.tif", left);
//write_image("right_in.tif", right);
write_image("left_in.tif", left);
write_image("right_in.tif", right);



SemiGlobalMatcher matcher;
matcher.setParameters(min_disp_x, min_disp_y, max_disp_x, max_disp_y, kernel_size);
ImageView<Vector<uint8, 2> > result = matcher.semi_global_matching_func(left, right);
SemiGlobalMatcher::DisparityImage result = matcher.semi_global_matching_func(left, right);

std::cout << "Writing output...\n";
write_image("SGM_output.tif", result);
Expand Down

0 comments on commit a1d6d91

Please sign in to comment.