Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/MarianoJT88/PD-Flow
Browse files Browse the repository at this point in the history
# Conflicts:
#	main_scene_flow_impair.cpp
#	scene_flow_impair.cpp
  • Loading branch information
MarianoJT88 committed Sep 22, 2017
2 parents c7f2440 + b28ff8a commit 4b02fcf
Show file tree
Hide file tree
Showing 5 changed files with 219 additions and 49 deletions.
21 changes: 19 additions & 2 deletions README.txt
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,20 @@ Both apps can read command line arguments. By adding the argument "--help" you w

--rows r: Number of rows at the finest level of the pyramid
Options: r=15, r=30, r=60, r=120, r=240, r=480 (if VGA)


The coarsest level of the pyramid is always 15 x 20, so the total number of coarse-to-fine levels will depend on the parameter "rows". By default, rows = 240.

The images that "Scene-Flow-Impair" reads must be named as "I1" (first intensity image), "I2" (second intensity image", "Z1" (first depth image) and "Z2" (second depth image) and must be located in the same directory as the executable. Furthermore, they must be saved with the following format:
The images that "Scene-Flow-Impair" reads can be specified on the command line

--i1 <filename> : The file name of the first intensity image. Defaults to i1.png

--i2 <filename> : The file name of the second intensity image. Defaults to i2.png

--z1 <filename> : The file name of the first depth image. Defaults to z1.png

--z2 <filename> : The file name of the second depth image. Defaults to z2.png

Note these names are case sensitive and the files must be located in the same directory as the executable unless an absolute path is specified. Furthermore, they must be saved with the following format:

intensity images - 8 bit in PNG. Resolution of VGA or QVGA
Clue: Use cv::Mat image_name(height, width, CV_8U) and
Expand All @@ -56,6 +65,14 @@ depth images - 16 bit monochrome in PNG, scaled by 5000. Resolution of VGA or QV
cv::imwrite(filename, image_name) to store them.
Multiply the real depth by 5000.

Scene-Flow_Impair writes outputs to two files, a text version containing the full scene flow and an image representation. The root of these files can be specified using

--out <root> : The output file name root. Defaults to pdflow.
The results will be written to <root>_resultsNN.txt and root_representationNN.png
where NN is a two digit number.

--no-show : Supresses display of images so that the code can be run in batch mode. Output files are still generated


The algorithm convergence is set to a fixed number of iterations at each level of the coarse-to-fine scheme, and depends on the amount of levels and the level itself. If necessary, it can be changed by modifying the variable num_max_iter[].

Expand Down
147 changes: 131 additions & 16 deletions main_scene_flow_impair.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,108 @@
using namespace std;




//==================================================================
// Arguments for running the algorithm - parsed from command line
//==================================================================
struct Launch_args {
unsigned int rows;
unsigned int show_help;
const char *intensity_filename_1;
const char *intensity_filename_2;
const char *depth_filename_1;
const char *depth_filename_2;
const char *output_filename_root;
bool no_show;
};

/**
* Parse arguments from the command line. Valid arguments are:
* --help (in which case other args are ignored)
* --rows r
* --i1 <filename> The first RGB image file name. Defaults to i1.png
* --i2 <filename> The second RGB image file name
* --z1 <filename> The first depth image file name
* --z2 <filename> The second depth image file name
* @param num_arg Number of arguments present
* @param argv Array of pointers to arguments
* @param args A launch_args structure which is populated by this method.
* @return true if arguments were successfully parsed, otherwise false
*/
bool parse_arguments( int num_arg, char *argv[], Launch_args& args) {
// Initialise with defaults
args.show_help = 0;
args.rows = 240;
args.intensity_filename_1 = "i1.png";
args.intensity_filename_2 = "i2.png";
args.depth_filename_1 = "z1.png";
args.depth_filename_2 = "z2.png";
args.output_filename_root = "pdflow";
args.no_show = false;

// Now check what's provided
bool parsed_ok = true;
int arg_idx = 1;
while( parsed_ok && ( arg_idx < num_arg ) ){
if( strcmp( "--help", argv[arg_idx]) == 0 ) {
// Stop parsing after seeing help
args.show_help = 1;
break;

} else if ( strcmp( "--rows", argv[arg_idx]) == 0 ) {
int rows = -1;
if( ++arg_idx < num_arg ) {
rows = stoi( argv[arg_idx]);
}
if( rows == 15 || rows == 30 || rows == 60 || rows == 120 || rows == 240 || rows == 480 ) {
args.rows = rows;
} else {
parsed_ok = false;
}
} else if ( strcmp( "--i1", argv[arg_idx]) == 0 ) {
if( ++arg_idx < num_arg ) {
args.intensity_filename_1 = argv[arg_idx];
} else {
parsed_ok = false;
}
} else if ( strcmp( "--i2", argv[arg_idx]) == 0 ) {
if( ++arg_idx < num_arg ) {
args.intensity_filename_2 = argv[arg_idx];
} else {
parsed_ok = false;
}
} else if ( strcmp( "--z1", argv[arg_idx]) == 0 ) {
if( ++arg_idx < num_arg ) {
args.depth_filename_1 = argv[arg_idx];
} else {
parsed_ok = false;
}
} else if ( strcmp( "--z2", argv[arg_idx]) == 0 ) {
if( ++arg_idx < num_arg ) {
args.depth_filename_2 = argv[arg_idx];
} else {
parsed_ok = false;
}
} else if ( strcmp( "--out", argv[arg_idx]) == 0 ) {
if( ++arg_idx < num_arg ) {
args.output_filename_root = argv[arg_idx];
} else {
parsed_ok = false;
}
} else if ( strcmp( "--no-show", argv[arg_idx]) == 0 ) {
args.no_show = true;
} else {
parsed_ok = false;
break;
}

arg_idx++;
}

return parsed_ok;
}

// ------------------------------------------------------
// MAIN
// ------------------------------------------------------
Expand All @@ -35,44 +137,57 @@ int main(int num_arg, char *argv[])
//==============================================================================
// Read arguments
//==============================================================================
unsigned int rows = 240; //Default value

if (num_arg <= 1); //No arguments
else if ( string(argv[1]) == "--help")
{
Launch_args args;
if( !parse_arguments( num_arg, argv, args ) || args.show_help ) {
printf("\n\t Arguments of the function 'main' \n");
printf("==============================================================\n\n");
printf(" --help: Shows this menu... \n\n");
printf(" --rows r: Number of rows at the finest level of the pyramid. \n");
printf("\t Options: r=15, r=30, r=60, r=120, r=240, r=480 (if VGA)\n");
printf(" --i1 <filename> : The first RGB image file name. Defaults to i1.png\n" );
printf(" --i2 <filename> : The second RGB image file name. Defaults to i2.png\n" );
printf(" --z1 <filename> : The first depth image file name. Defaults to z1.png\n" );
printf(" --z2 <filename> : The second depth image file name. Defaults to z2.png\n" );
printf(" --out <filename>: The output file name root. Omit file extension. Defaults to pdflow\n" );
printf(" --no-show : Don't show the output results. Useful for batch processing\n");
getwchar();
return 1;
}
else
{
if ( string(argv[1]) == "--rows")
rows = stoi(argv[2]);
}

//==============================================================================
// Main operations
//==============================================================================

PD_flow_opencv sceneflow(rows);
PD_flow_opencv sceneflow(args.rows,
args.intensity_filename_1,
args.intensity_filename_2,
args.depth_filename_1,
args.depth_filename_2,
args.output_filename_root);

//Initialize CUDA and set some internal variables
sceneflow.initializeCUDA();

bool imloaded = sceneflow.loadRGBDFrames();

if (imloaded == 1)
{
{
sceneflow.solveSceneFlowGPU();
sceneflow.showImages();
sceneflow.showAndSaveResults();

if( args.no_show )
{
cv::Mat image = sceneflow.createImage( );
sceneflow.saveResults( image );
}
else
{
sceneflow.showImages();
sceneflow.showAndSaveResults();
printf("\nPush any key over the scene flow image to finish\n");
cv::waitKey(0);
}

sceneflow.freeGPUMemory();
printf("\nPush any key over the scene flow image to finish\n");
cv::waitKey(0);
}

return 0;
Expand Down
78 changes: 51 additions & 27 deletions scene_flow_impair.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,13 @@ bool fileExists(const std::string& path)
return 0 == access(path.c_str(), 0x00 ); // 0x00 = Check for existence only!
}

PD_flow_opencv::PD_flow_opencv(unsigned int rows_config)
{
PD_flow_opencv::PD_flow_opencv(unsigned int rows_config,
const char *intensity_filename_1,
const char *intensity_filename_2,
const char *depth_filename_1,
const char *depth_filename_2,
const char* output_filename_root) {

rows = rows_config; //Maximum size of the coarse-to-fine scheme - Default 240 (QVGA)
cols = rows*320/240;
ctf_levels = static_cast<unsigned int>(log2(float(rows/15))) + 1;
Expand Down Expand Up @@ -62,8 +67,16 @@ PD_flow_opencv::PD_flow_opencv(unsigned int rows_config)
lambda_i = 0.04f;
lambda_d = 0.35f;
mu = 75.f;

// Set file names
this->intensity_filename_1 = intensity_filename_1;
this->intensity_filename_2 = intensity_filename_2;
this->depth_filename_1 = depth_filename_1;
this->depth_filename_2 = depth_filename_2;
this->output_filename_root = output_filename_root;
}


void PD_flow_opencv::createImagePyramidGPU()
{
//Copy new frames to the scene flow object
Expand Down Expand Up @@ -161,11 +174,8 @@ void PD_flow_opencv::freeGPUMemory()

void PD_flow_opencv::initializeCUDA()
{
char name[100];

//Read one image to know the image resolution
sprintf(name, "i1.png");
intensity1 = cv::imread(name, CV_LOAD_IMAGE_GRAYSCALE);
intensity1 = cv::imread(intensity_filename_1, CV_LOAD_IMAGE_GRAYSCALE);

width = intensity1.cols;
height = intensity1.rows;
Expand Down Expand Up @@ -207,15 +217,13 @@ void PD_flow_opencv::showImages()

bool PD_flow_opencv::loadRGBDFrames()
{
char name[100];
cv::Mat depth_float;

//First intensity image
sprintf(name, "i1.png");
intensity1 = cv::imread(name, CV_LOAD_IMAGE_GRAYSCALE);
intensity1 = cv::imread(intensity_filename_1, CV_LOAD_IMAGE_GRAYSCALE);
if (intensity1.empty())
{
printf("\nThe first intensity image (i1) cannot be found, please check that it is in the correct folder \n");
printf("\nThe first intensity image (%s) cannot be found, please check that it is in the correct folder \n", intensity_filename_1);
return 0;
}

Expand All @@ -224,11 +232,10 @@ bool PD_flow_opencv::loadRGBDFrames()
I[v + u*height] = float(intensity1.at<unsigned char>(v,u));

//First depth image
sprintf(name, "z1.png");
depth1 = cv::imread(name, -1);
depth1 = cv::imread(depth_filename_1, -1);
if (depth1.empty())
{
printf("\nThe first depth image (z1) cannot be found, please check that it is in the correct folder \n");
printf("\nThe first depth image (%s) cannot be found, please check that it is in the correct folder \n", depth_filename_1);
return 0;
}

Expand All @@ -241,11 +248,10 @@ bool PD_flow_opencv::loadRGBDFrames()


//Second intensity image
sprintf(name, "i2.png");
intensity2 = cv::imread(name, CV_LOAD_IMAGE_GRAYSCALE);
intensity2 = cv::imread(intensity_filename_2, CV_LOAD_IMAGE_GRAYSCALE);
if (intensity2.empty())
{
printf("\nThe second intensity image (i2) cannot be found, please check that it is in the correct folder \n");
printf("\nThe second intensity image (%s) cannot be found, please check that it is in the correct folder \n", intensity_filename_2);
return 0;
}

Expand All @@ -254,11 +260,10 @@ bool PD_flow_opencv::loadRGBDFrames()
I[v + u*height] = float(intensity2.at<unsigned char>(v,u));

//Second depth image
sprintf(name, "z2.png");
depth2 = cv::imread(name, -1);
depth2 = cv::imread(depth_filename_2, -1);
if (depth2.empty())
{
printf("\nThe second depth image (z2) cannot be found, please check that they are in the correct folder \n");
printf("\nThe second depth image (%s) cannot be found, please check that they are in the correct folder \n", depth_filename_2);
return 0;
}
depth2.convertTo(depth_float, CV_32FC1, 1.0 / 5000.0);
Expand All @@ -271,7 +276,8 @@ bool PD_flow_opencv::loadRGBDFrames()
return 1;
}

void PD_flow_opencv::showAndSaveResults()
// Create the image
cv::Mat PD_flow_opencv::createImage() const
{
//Save scene flow as an RGB image (one colour per direction)
cv::Mat sf_image(rows, cols, CV_8UC3);
Expand All @@ -298,20 +304,25 @@ void PD_flow_opencv::showAndSaveResults()
sf_image.at<cv::Vec3b>(v,u)[2] = static_cast<unsigned char>(255.f*fabs(dzp[v + u*rows])/maxmodz); //Red - z
}

//Show the scene flow as an RGB image
cv::namedWindow("SceneFlow", cv::WINDOW_NORMAL);
cv::moveWindow("SceneFlow",width - cols/2,height - rows/2);
cv::imshow("SceneFlow", sf_image);

return sf_image;
}


/**
* Save results without displaying them
*/
void PD_flow_opencv::saveResults( const cv::Mat& sf_image ) const
{
//Save the scene flow as a text file
char name[100];
char name[500];
int nFichero = 0;
bool free_name = false;

while (!free_name)
{
nFichero++;
sprintf(name, "pdflow_results%02u.txt", nFichero );
sprintf(name, "%s_results%02u.txt", output_filename_root, nFichero );
free_name = !fileExists(name);
}

Expand All @@ -333,7 +344,20 @@ void PD_flow_opencv::showAndSaveResults()
f_res.close();

//Save the RGB representation of the scene flow
sprintf(name, "pdflow_representation%02u.png", nFichero);
sprintf(name, "%s_representation%02u.png", output_filename_root, nFichero);
printf("Saving the visual representation to file: %s \n", name);
cv::imwrite(name, sf_image);
}


void PD_flow_opencv::showAndSaveResults( )
{
cv::Mat sf_image = createImage( );

//Show the scene flow as an RGB image
cv::namedWindow("SceneFlow", cv::WINDOW_NORMAL);
cv::moveWindow("SceneFlow",width - cols/2,height - rows/2);
cv::imshow("SceneFlow", sf_image);

saveResults( sf_image );
}
Loading

0 comments on commit 4b02fcf

Please sign in to comment.