298 lines
8.8 KiB
C++
298 lines
8.8 KiB
C++
#include "cvtest.h"
|
|
|
|
#if 0
|
|
|
|
#define debug //enables showing images.
|
|
#define CONSOLEOUTPUT //enables printing rms error and percentage of bad pixels to console.
|
|
|
|
//#define LOAD //enables skipping computing disparities and load them from images.
|
|
//#define SAVEIMAGES //enables saving computed disparity and red-marked disparity images.
|
|
|
|
void MarkPixel(const IplImage* markedDisparity, const int h, const int w)
|
|
{
|
|
uchar* data = (uchar*)&markedDisparity->imageData[h*markedDisparity->widthStep + w*3];
|
|
data[0] = 0;
|
|
data[1] = 0;
|
|
data[2] = 255;
|
|
}
|
|
|
|
int CalculateErrors(const IplImage* disparity,const IplImage* groundTruth, IplImage* markedDisparity,
|
|
double &rms_error, double &percentage_of_bad_pixels,
|
|
const int maxDisparity CV_DEFAULT(16), const int eval_ignore_border CV_DEFAULT(10))
|
|
{
|
|
if (disparity->width != groundTruth->width)
|
|
return CvTS::FAIL_INVALID_TEST_DATA;
|
|
if (disparity->height != groundTruth->height)
|
|
return CvTS::FAIL_INVALID_TEST_DATA;
|
|
|
|
const double eval_bad_thresh = 1.0;
|
|
|
|
char* DC = disparity->imageData;
|
|
char* DT = groundTruth->imageData;
|
|
|
|
double currSum = 0;
|
|
unsigned int bad_pixels_counter=0;
|
|
|
|
double diff=0;
|
|
|
|
int w = disparity->width;
|
|
int h = disparity->height;
|
|
unsigned int numPixels = w*h;
|
|
|
|
for(int i=eval_ignore_border; i<h-eval_ignore_border; i++)
|
|
for(int j=eval_ignore_border; j<w-eval_ignore_border; j++)
|
|
{
|
|
diff = (double)abs(DC[i*disparity->widthStep+j] - DT[i*groundTruth->widthStep+j])/(double)maxDisparity;
|
|
currSum += diff*diff;
|
|
|
|
if ( diff > eval_bad_thresh )
|
|
{
|
|
bad_pixels_counter++;
|
|
MarkPixel(markedDisparity, i, j);
|
|
}
|
|
}
|
|
|
|
currSum /=(double)numPixels;
|
|
rms_error = sqrt(currSum);
|
|
|
|
percentage_of_bad_pixels = (double)bad_pixels_counter/(double)numPixels * 100;
|
|
|
|
return 0;
|
|
}
|
|
|
|
class CV_StereoCorrespondenceTestGC : public CvTest
|
|
{
|
|
public:
|
|
CV_StereoCorrespondenceTestGC();
|
|
protected:
|
|
void run(int);
|
|
};
|
|
|
|
|
|
CV_StereoCorrespondenceTestGC::CV_StereoCorrespondenceTestGC():
|
|
CvTest( "stereo-gc", "cvFindStereoCorrespondenceGC" )
|
|
{
|
|
support_testing_modes = CvTS::CORRECTNESS_CHECK_MODE;
|
|
}
|
|
|
|
/* ///////////////////// stereo_correspondece_test ///////////////////////// */
|
|
void CV_StereoCorrespondenceTestGC::run( int )
|
|
{
|
|
int code = CvTS::OK;
|
|
|
|
const double rms_error_thresh = 1000.0;
|
|
const double percentage_of_bad_pixels_thresh = 90.0;
|
|
|
|
double rms_error[2];
|
|
double percentage_of_bad_pixels[2];
|
|
|
|
/* test parameters */
|
|
char filepath[1000];
|
|
char filename[1000];
|
|
//char extension[5];
|
|
|
|
IplImage* left ;
|
|
IplImage* right;
|
|
IplImage* disparity_left;
|
|
IplImage* disparity_right;
|
|
IplImage* groundTruthLeft;
|
|
IplImage* groundTruthRight;
|
|
|
|
sprintf( filepath, "%sstereocorrespondence/", ts->get_data_path() );
|
|
sprintf( filename, "%sstereocorrespondence_list.txt", filepath );
|
|
|
|
FILE* f = fopen(filename,"r");
|
|
int numImages=0;
|
|
fscanf(f,"%d\n",&numImages);
|
|
|
|
for(int i=0; i<numImages; i++)
|
|
{
|
|
/*Load left and right image from the storage*/
|
|
char dataName[100];
|
|
int maxDisparity=0;
|
|
|
|
fscanf(f,"%s %d\n",dataName,&maxDisparity);
|
|
sprintf(filename,"%s%sL.png",filepath,dataName);
|
|
left = cvLoadImage(filename,0);
|
|
sprintf(filename,"%s%sR.png",filepath,dataName);
|
|
right = cvLoadImage(filename,0);
|
|
|
|
if (!left || !right)
|
|
{
|
|
ts->printf( CvTS::LOG, "Left or right image doesn't exist" );
|
|
code = CvTS::FAIL_MISSING_TEST_DATA;
|
|
goto _exit_;
|
|
}
|
|
if ((cvGetSize(left).height != cvGetSize(right).height)
|
|
|| ((cvGetSize(left).width != cvGetSize(right).width)))
|
|
{
|
|
ts->printf( CvTS::LOG, "Left and right image sizes aren't equal" );
|
|
code = CvTS::FAIL_MISSING_TEST_DATA;
|
|
goto _exit_;
|
|
}
|
|
|
|
sprintf(filename,"%s%s_gtL.png",filepath,dataName);
|
|
groundTruthLeft = cvLoadImage(filename,0);
|
|
sprintf(filename,"%s%s_gtR.png",filepath,dataName);
|
|
groundTruthRight = cvLoadImage(filename,0);
|
|
|
|
if (!groundTruthLeft && !groundTruthRight)
|
|
{
|
|
ts->printf( CvTS::LOG, "Left and right ground truth images don't exist" );
|
|
code = CvTS::FAIL_MISSING_TEST_DATA;
|
|
goto _exit_;
|
|
}
|
|
|
|
for(int i=0; i<2; i++)
|
|
{
|
|
IplImage*& groundTruth = (i == 0) ? groundTruthLeft : groundTruthRight;
|
|
if (groundTruth)
|
|
if (groundTruth->nChannels != 1)
|
|
{
|
|
IplImage* tmp = groundTruth;
|
|
groundTruth = cvCreateImage(cvGetSize(left),IPL_DEPTH_8U,1);
|
|
cvCvtColor(tmp, groundTruth,CV_BGR2GRAY);
|
|
}
|
|
}
|
|
|
|
/*Find disparity map for current image pair*/
|
|
#ifndef LOAD
|
|
disparity_left = cvCreateImage( cvGetSize(left), IPL_DEPTH_32S, 1 );
|
|
disparity_right = cvCreateImage( cvGetSize(left), IPL_DEPTH_32S, 1 );
|
|
|
|
CvStereoGCState* state = cvCreateStereoGCState(maxDisparity, 2);
|
|
cvFindStereoCorrespondenceGC( left, right,
|
|
disparity_left, disparity_right, state);
|
|
|
|
double scale = 256/maxDisparity ;
|
|
if (!strcmp(dataName,"sawtooth") || !strcmp(dataName,"map") || !strcmp(dataName,"poster")
|
|
|| !strcmp(dataName,"bull") || !strcmp(dataName,"barn1") || !strcmp(dataName,"barn2"))
|
|
scale = 8.0;
|
|
|
|
IplImage* temp;
|
|
temp = disparity_left;
|
|
disparity_left = cvCreateImage(cvGetSize(temp), IPL_DEPTH_8U,1);
|
|
cvConvertScale(temp, disparity_left, -scale);
|
|
temp = disparity_right;
|
|
disparity_right = cvCreateImage(cvGetSize(temp), IPL_DEPTH_8U,1);
|
|
cvConvertScale(temp, disparity_right, scale );
|
|
#endif
|
|
#ifdef LOAD
|
|
disparity_left;
|
|
disparity_right;
|
|
sprintf(filename,"%s%s_dLgc.png",filepath,dataName);
|
|
disparity_left = cvLoadImage(filename,0);
|
|
sprintf(filename,"%s%s_dRgc.png",filepath,dataName);
|
|
disparity_right = cvLoadImage(filename,0);
|
|
#endif
|
|
#ifdef debug
|
|
cvNamedWindow("disparity_left");
|
|
cvNamedWindow("disparity_right");
|
|
cvNamedWindow("ground_truth_left");
|
|
cvNamedWindow("ground_truth_right");
|
|
|
|
cvShowImage("disparity_left",disparity_left);
|
|
cvShowImage("disparity_right",disparity_right);
|
|
cvShowImage("ground_truth_left", groundTruthLeft);
|
|
cvShowImage("ground_truth_right", groundTruthRight);
|
|
#endif
|
|
|
|
/*Calculate RMS error and percentage of bad pixels*/
|
|
IplImage* markedDisparity_left = cvCreateImage(cvGetSize(left), IPL_DEPTH_8U, 3);
|
|
IplImage* markedDisparity_right = cvCreateImage(cvGetSize(left), IPL_DEPTH_8U, 3);
|
|
cvCvtColor(disparity_left,markedDisparity_left,CV_GRAY2RGB);
|
|
cvCvtColor(disparity_right,markedDisparity_right,CV_GRAY2RGB);
|
|
|
|
int eval_ignore_border = 10;
|
|
if (strcmp(dataName,"tsukuba") == 0)
|
|
eval_ignore_border = 18;
|
|
|
|
/*Left*/
|
|
int retcode[2] = {0,0};
|
|
if (groundTruthLeft)
|
|
retcode[0] = CalculateErrors(disparity_left,groundTruthLeft, markedDisparity_left,
|
|
rms_error[0], percentage_of_bad_pixels[0], maxDisparity, eval_ignore_border);
|
|
/*Right*/
|
|
if (groundTruthRight)
|
|
retcode[1] = CalculateErrors(disparity_right,groundTruthRight, markedDisparity_right,
|
|
rms_error[1], percentage_of_bad_pixels[1], maxDisparity, eval_ignore_border);
|
|
|
|
#ifdef SAVEIMAGES
|
|
#ifndef LOAD
|
|
sprintf(filename,"%s%s_dLgc.png",filepath,dataName);
|
|
cvSaveImage(filename,disparity_left);
|
|
sprintf(filename,"%s%s_dRgc.png",filepath,dataName);
|
|
cvSaveImage(filename,disparity_right);
|
|
|
|
sprintf(filename,"%s%s_mdLgc.png",filepath,dataName);
|
|
cvSaveImage(filename,markedDisparity_left);
|
|
sprintf(filename,"%s%s_mdRgc.png",filepath,dataName);
|
|
cvSaveImage(filename,markedDisparity_right);
|
|
#endif
|
|
#endif
|
|
#ifdef debug
|
|
cvNamedWindow("markedDisparity_left");
|
|
cvNamedWindow("markedDisparity_right");
|
|
cvShowImage("markedDisparity_left",markedDisparity_left);
|
|
cvShowImage("markedDisparity_right",markedDisparity_right);
|
|
cvWaitKey(1000);
|
|
#endif
|
|
if (retcode[0])
|
|
{
|
|
ts->printf(CvTS::LOG,"Calculation error");
|
|
code = retcode[0];
|
|
//goto _exit_;
|
|
}
|
|
if (retcode[1])
|
|
{
|
|
ts->printf(CvTS::LOG,"Calculation error");
|
|
code = retcode[1];
|
|
//goto _exit_;
|
|
}
|
|
#ifdef CONSOLEOUTPUT
|
|
printf("\n%s\n",dataName);
|
|
if (groundTruthLeft)
|
|
printf("L rms error = %f\npercentage of bad pixels = %f\n",
|
|
rms_error[0], percentage_of_bad_pixels[0]);
|
|
if(groundTruthRight)
|
|
printf("R rms error = %f\npercentage of bad pixels = %f\n",
|
|
rms_error[1], percentage_of_bad_pixels[1]);
|
|
#endif
|
|
for(int i=0; i<2; i++)
|
|
{
|
|
IplImage* groundTruth = (i == 0) ? groundTruthLeft : groundTruthRight;
|
|
if (groundTruth)
|
|
{
|
|
if (rms_error[i] > rms_error_thresh)
|
|
{
|
|
ts->printf( CvTS::LOG, "Big RMS error" );
|
|
code = CvTS::FAIL_BAD_ACCURACY;
|
|
//goto _exit_;
|
|
}
|
|
if (percentage_of_bad_pixels[i] > percentage_of_bad_pixels_thresh)
|
|
{
|
|
ts->printf( CvTS::LOG, "Big percentage of bad pixels" );
|
|
code = CvTS::FAIL_BAD_ACCURACY;
|
|
//goto _exit_;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
_exit_:
|
|
cvReleaseImage(&left);
|
|
cvReleaseImage(&right);
|
|
cvReleaseImage(&disparity_left);
|
|
cvReleaseImage(&disparity_right);
|
|
cvReleaseImage(&groundTruthLeft);
|
|
cvReleaseImage(&groundTruthRight);
|
|
#ifndef LOAD
|
|
//cvReleaseStereoCorrespondenceGCState(&stereoMatcher);
|
|
#endif
|
|
if( code < 0 )
|
|
ts->set_failed_test_info( code );
|
|
}
|
|
|
|
CV_StereoCorrespondenceTestGC stereo_correspondece_test_gc;
|
|
|
|
#endif
|