Commit d9c74f63 authored by Andrey Kamaev's avatar Andrey Kamaev

All tests writing temporary files are updated to use cv::tempfile() function

parent ec3a7665
......@@ -54,7 +54,7 @@ protected:
Mat intrinsic_matrix_;
Mat distortion_coeffs_;
Size image_size_;
void run(int);
void generateIntrinsicParams();
};
......@@ -66,14 +66,14 @@ int calcDistance(const vector<Point2f>& set1, const vector<Point2f>& set2, doubl
{
return 0;
}
std::vector<int> indices;
double sum_dist = 0.0;
for(size_t i = 0; i < set1.size(); i++)
{
double min_dist = std::numeric_limits<double>::max();
int min_idx = -1;
for(int j = 0; j < (int)set2.size(); j++)
{
double dist = norm(set1[i] - set2[j]);
......@@ -83,33 +83,33 @@ int calcDistance(const vector<Point2f>& set1, const vector<Point2f>& set2, doubl
min_dist = dist;
}
}
// check validity of min_idx
if(min_idx == -1)
{
return 0;
}
std::vector<int>::iterator it = std::find(indices.begin(), indices.end(), min_idx);
if(it != indices.end())
if(it != indices.end())
{
// there are two points in set1 corresponding to the same point in set2
return 0;
}
indices.push_back(min_idx);
// printf("dist %d = %f\n", (int)i, min_dist);
sum_dist += min_dist*min_dist;
}
mean_dist = sqrt(sum_dist/set1.size());
// printf("sum_dist = %f, set1.size() = %d, mean_dist = %f\n", sum_dist, (int)set1.size(), mean_dist);
return 1;
}
CV_ChessboardSubpixelTest::CV_ChessboardSubpixelTest() :
intrinsic_matrix_(Size(3, 3), CV_64FC1), distortion_coeffs_(Size(1, 4), CV_64FC1),
intrinsic_matrix_(Size(3, 3), CV_64FC1), distortion_coeffs_(Size(1, 4), CV_64FC1),
image_size_(640, 480)
{
}
......@@ -121,13 +121,13 @@ void CV_ChessboardSubpixelTest::run( int )
int progress = 0;
RNG& rng = ts->get_rng();
const int runs_count = 20;
const int max_pattern_size = 8;
const int min_pattern_size = 5;
Mat bg(image_size_, CV_8UC1);
bg = Scalar(0);
double sum_dist = 0.0;
int count = 0;
for(int i = 0; i < runs_count; i++)
......@@ -144,13 +144,13 @@ void CV_ChessboardSubpixelTest::run( int )
pattern_size = Size(pattern_width, pattern_height);
}
ChessBoardGenerator gen_chessboard(Size(pattern_size.width + 1, pattern_size.height + 1));
// generates intrinsic camera and distortion matrices
generateIntrinsicParams();
vector<Point2f> corners;
Mat chessboard_image = gen_chessboard(bg, intrinsic_matrix_, distortion_coeffs_, corners);
Mat chessboard_image = gen_chessboard(bg, intrinsic_matrix_, distortion_coeffs_, corners);
vector<Point2f> test_corners;
bool result = findChessboardCorners(chessboard_image, pattern_size, test_corners, 15);
if(!result)
......@@ -158,47 +158,47 @@ void CV_ChessboardSubpixelTest::run( int )
#if 0
ts->printf(cvtest::TS::LOG, "Warning: chessboard was not detected! Writing image to test.jpg\n");
ts->printf(cvtest::TS::LOG, "Size = %d, %d\n", pattern_size.width, pattern_size.height);
ts->printf(cvtest::TS::LOG, "Intrinsic params: fx = %f, fy = %f, cx = %f, cy = %f\n",
intrinsic_matrix_.at<double>(0, 0), intrinsic_matrix_.at<double>(1, 1),
ts->printf(cvtest::TS::LOG, "Intrinsic params: fx = %f, fy = %f, cx = %f, cy = %f\n",
intrinsic_matrix_.at<double>(0, 0), intrinsic_matrix_.at<double>(1, 1),
intrinsic_matrix_.at<double>(0, 2), intrinsic_matrix_.at<double>(1, 2));
ts->printf(cvtest::TS::LOG, "Distortion matrix: %f, %f, %f, %f, %f\n",
ts->printf(cvtest::TS::LOG, "Distortion matrix: %f, %f, %f, %f, %f\n",
distortion_coeffs_.at<double>(0, 0), distortion_coeffs_.at<double>(0, 1),
distortion_coeffs_.at<double>(0, 2), distortion_coeffs_.at<double>(0, 3),
distortion_coeffs_.at<double>(0, 2), distortion_coeffs_.at<double>(0, 3),
distortion_coeffs_.at<double>(0, 4));
imwrite("test.jpg", chessboard_image);
#endif
continue;
}
double dist1 = 0.0;
int ret = calcDistance(corners, test_corners, dist1);
if(ret == 0)
{
ts->printf(cvtest::TS::LOG, "findChessboardCorners returns invalid corner coordinates!\n");
code = cvtest::TS::FAIL_INVALID_OUTPUT;
break;
break;
}
IplImage chessboard_image_header = chessboard_image;
cvFindCornerSubPix(&chessboard_image_header, (CvPoint2D32f*)&test_corners[0],
cvFindCornerSubPix(&chessboard_image_header, (CvPoint2D32f*)&test_corners[0],
(int)test_corners.size(), cvSize(3, 3), cvSize(1, 1), cvTermCriteria(CV_TERMCRIT_EPS|CV_TERMCRIT_ITER,300,0.1));
find4QuadCornerSubpix(chessboard_image, test_corners, Size(5, 5));
double dist2 = 0.0;
ret = calcDistance(corners, test_corners, dist2);
if(ret == 0)
{
ts->printf(cvtest::TS::LOG, "findCornerSubpix returns invalid corner coordinates!\n");
code = cvtest::TS::FAIL_INVALID_OUTPUT;
break;
break;
}
ts->printf(cvtest::TS::LOG, "Error after findChessboardCorners: %f, after findCornerSubPix: %f\n",
ts->printf(cvtest::TS::LOG, "Error after findChessboardCorners: %f, after findCornerSubPix: %f\n",
dist1, dist2);
sum_dist += dist2;
count++;
const double max_reduce_factor = 0.8;
if(dist1 < dist2*max_reduce_factor)
{
......@@ -206,33 +206,33 @@ void CV_ChessboardSubpixelTest::run( int )
code = cvtest::TS::FAIL_INVALID_OUTPUT;
break;
}
progress = update_progress( progress, i-1, runs_count, 0 );
}
sum_dist /= count;
ts->printf(cvtest::TS::LOG, "Average error after findCornerSubpix: %f\n", sum_dist);
ts->printf(cvtest::TS::LOG, "Average error after findCornerSubpix: %f\n", sum_dist);
if( code < 0 )
ts->set_failed_test_info( code );
}
void CV_ChessboardSubpixelTest::generateIntrinsicParams()
{
RNG& rng = ts->get_rng();
const double max_focus_length = 1000.0;
const double max_focus_diff = 5.0;
double fx = cvtest::randReal(rng)*max_focus_length;
double fy = fx + cvtest::randReal(rng)*max_focus_diff;
double cx = image_size_.width/2;
double cy = image_size_.height/2;
double k1 = 0.5*cvtest::randReal(rng);
double k2 = 0.05*cvtest::randReal(rng);
double p1 = 0.05*cvtest::randReal(rng);
double p2 = 0.05*cvtest::randReal(rng);
double k3 = 0.0;
intrinsic_matrix_ = (Mat_<double>(3, 3) << fx, 0.0, cx, 0.0, fy, cy, 0.0, 0.0, 1.0);
distortion_coeffs_ = (Mat_<double>(1, 5) << k1, k2, p1, p2, k3);
}
......
......@@ -473,20 +473,59 @@ string format( const char* fmt, ... )
string tempfile( const char* suffix )
{
char buf[L_tmpnam];
char* name = 0;
#ifdef ANDROID
strcpy(buf, "/sdcard/__opencv_temp_XXXXXX");
name = mktemp(buf);
#else
name = tmpnam(buf);
#endif
if (*name == '\\')
++name;
string n(name);
if (suffix != 0)
n += (n[n.size()-1] == '.' && suffix[0] == '.' ? suffix + 1 : suffix);
return n;
#if defined WIN32 || defined _WIN32
char temp_dir[MAX_PATH + 1] = { 0 };
char temp_file[MAX_PATH + 1] = { 0 };
::GetTempPathA(sizeof(temp_dir), temp_dir);
if(0 != ::GetTempFileNameA(temp_dir, "__opencv_temp.", 0, temp_file))
return string();
string name = temp_file;
if(suffix)
{
if (suffix[0] != '.')
return name + "." + suffix;
else
return name + suffix;
}
else
return name;
# else
# ifdef ANDROID
//char defaultTemplate[] = "/mnt/sdcard/__opencv_temp.XXXXXX";
char defaultTemplate[] = "/data/local/tmp/__opencv_temp.XXXXXX";
# else
char defaultTemplate[] = "/tmp/__opencv_temp.XXXXXX";
# endif
string fname;
const char *temp_dir = getenv("OPENCV_TEMP_PATH");
if(temp_dir == 0 || temp_dir[0] == 0)
fname = defaultTemplate;
else
{
fname = temp_dir;
char ech = fname[fname.size() - 1];
if(ech != '/' && ech != '\\')
fname += "/";
fname += "__opencv_temp.XXXXXX";
}
const int fd = mkstemp((char*)fname.c_str());
if(fd == -1) return "";
close(fd);
remove(fname.c_str());
if(suffix)
{
if (suffix[0] != '.')
fname = fname + "." + suffix;
else
fname += suffix;
}
return fname;
# endif
}
static CvErrorCallback customErrorCallback = 0;
......
This diff is collapsed.
This diff is collapsed.
......@@ -328,7 +328,7 @@ public:
float patternScale = 22.0f,
int nOctaves = 4,
const vector<int>& selectedPairs = vector<int>());
FREAK( const FREAK& rhs );
FREAK( const FREAK& rhs );
FREAK& operator=( const FREAK& );
virtual ~FREAK();
......@@ -349,51 +349,51 @@ public:
vector<int> selectPairs( const vector<Mat>& images, vector<vector<KeyPoint> >& keypoints,
const double corrThresh = 0.7, bool verbose = true );
AlgorithmInfo* info() const;
AlgorithmInfo* info() const;
enum
{
NB_SCALES = 64, NB_PAIRS = 512, NB_ORIENPAIRS = 45
};
enum
{
NB_SCALES = 64, NB_PAIRS = 512, NB_ORIENPAIRS = 45
};
protected:
virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
void buildPattern();
uchar meanIntensity( const Mat& image, const Mat& integral, const float kp_x, const float kp_y,
void buildPattern();
uchar meanIntensity( const Mat& image, const Mat& integral, const float kp_x, const float kp_y,
const unsigned int scale, const unsigned int rot, const unsigned int point ) const;
bool orientationNormalized; //true if the orientation is normalized, false otherwise
bool orientationNormalized; //true if the orientation is normalized, false otherwise
bool scaleNormalized; //true if the scale is normalized, false otherwise
double patternScale; //scaling of the pattern
int nOctaves; //number of octaves
bool extAll; // true if all pairs need to be extracted for pairs selection
double patternScale0;
int nOctaves0;
vector<int> selectedPairs0;
struct PatternPoint
{
float x; // x coordinate relative to center
float y; // x coordinate relative to center
float sigma; // Gaussian smoothing sigma
};
struct DescriptionPair
{
uchar i; // index of the first point
uchar j; // index of the second point
};
struct OrientationPair
{
uchar i; // index of the first point
uchar j; // index of the second point
int weight_dx; // dx/(norm_sq))*4096
int weight_dy; // dy/(norm_sq))*4096
};
vector<PatternPoint> patternLookup; // look-up table for the pattern points (position+sigma of all points at all scales and orientation)
struct PatternPoint
{
float x; // x coordinate relative to center
float y; // x coordinate relative to center
float sigma; // Gaussian smoothing sigma
};
struct DescriptionPair
{
uchar i; // index of the first point
uchar j; // index of the second point
};
struct OrientationPair
{
uchar i; // index of the first point
uchar j; // index of the second point
int weight_dx; // dx/(norm_sq))*4096
int weight_dy; // dy/(norm_sq))*4096
};
vector<PatternPoint> patternLookup; // look-up table for the pattern points (position+sigma of all points at all scales and orientation)
int patternSizes[NB_SCALES]; // size of the pattern at a specific scale (used to check if a point is within image boundaries)
DescriptionPair descriptionPairs[NB_PAIRS];
OrientationPair orientationPairs[NB_ORIENPAIRS];
......@@ -603,7 +603,7 @@ public:
// TODO implement read/write
virtual bool empty() const;
AlgorithmInfo* info() const;
protected:
......@@ -641,8 +641,8 @@ protected:
class CV_EXPORTS AdjusterAdapter: public FeatureDetector
{
public:
/** pure virtual interface
*/
/** pure virtual interface
*/
virtual ~AdjusterAdapter() {}
/** too few features were detected so, adjust the detector params accordingly
* \param min the minimum number of desired features
......@@ -682,7 +682,7 @@ public:
/** \param adjuster an AdjusterAdapter that will do the detection and parameter adjustment
* \param max_features the maximum desired number of features
* \param max_iters the maximum number of times to try to adjust the feature detector params
* for the FastAdjuster this can be high, but with Star or Surf this can get time consuming
* for the FastAdjuster this can be high, but with Star or Surf this can get time consuming
* \param min_features the minimum desired features
*/
DynamicAdaptedFeatureDetector( const Ptr<AdjusterAdapter>& adjuster, int min_features=400, int max_features=500, int max_iters=5 );
......@@ -693,8 +693,8 @@ protected:
virtual void detectImpl( const Mat& image, vector<KeyPoint>& keypoints, const Mat& mask=Mat() ) const;
private:
DynamicAdaptedFeatureDetector& operator=(const DynamicAdaptedFeatureDetector&);
DynamicAdaptedFeatureDetector(const DynamicAdaptedFeatureDetector&);
DynamicAdaptedFeatureDetector& operator=(const DynamicAdaptedFeatureDetector&);
DynamicAdaptedFeatureDetector(const DynamicAdaptedFeatureDetector&);
int escape_iters_;
int min_features_, max_features_;
......@@ -792,7 +792,7 @@ public:
virtual bool empty() const;
protected:
virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
virtual void computeImpl( const Mat& image, vector<KeyPoint>& keypoints, Mat& descriptors ) const;
Ptr<DescriptorExtractor> descriptorExtractor;
};
......@@ -962,7 +962,7 @@ class CV_EXPORTS_W DescriptorMatcher : public Algorithm
public:
virtual ~DescriptorMatcher();
/*
/*
* Add descriptors to train descriptor collection.
* descriptors Descriptors to add. Each descriptors[i] is a descriptors set from one image.
*/
......@@ -1078,7 +1078,7 @@ protected:
static bool isMaskedOut( const vector<Mat>& masks, int queryIdx );
static Mat clone_op( Mat m ) { return m.clone(); }
void checkMasks( const vector<Mat>& masks, int queryDescriptorsCount ) const;
void checkMasks( const vector<Mat>& masks, int queryDescriptorsCount ) const;
// Collection of descriptors from train images.
vector<Mat> trainDescCollection;
......
......@@ -48,8 +48,8 @@ class CV_FastTest : public cvtest::BaseTest
{
public:
CV_FastTest();
~CV_FastTest();
protected:
~CV_FastTest();
protected:
void run(int);
};
......@@ -58,13 +58,13 @@ CV_FastTest::~CV_FastTest() {}
void CV_FastTest::run( int )
{
Mat image1 = imread(string(ts->get_data_path()) + "inpaint/orig.jpg");
Mat image2 = imread(string(ts->get_data_path()) + "cameracalibration/chess9.jpg");
Mat image1 = imread(string(ts->get_data_path()) + "inpaint/orig.jpg");
Mat image2 = imread(string(ts->get_data_path()) + "cameracalibration/chess9.jpg");
string xml = string(ts->get_data_path()) + "fast/result.xml";
if (image1.empty() || image2.empty())
{
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
......@@ -73,20 +73,20 @@ void CV_FastTest::run( int )
cvtColor(image2, gray2, CV_BGR2GRAY);
vector<KeyPoint> keypoints1;
vector<KeyPoint> keypoints2;
vector<KeyPoint> keypoints2;
FAST(gray1, keypoints1, 30);
FAST(gray2, keypoints2, 30);
for(size_t i = 0; i < keypoints1.size(); ++i)
{
const KeyPoint& kp = keypoints1[i];
cv::circle(image1, kp.pt, cvRound(kp.size/2), CV_RGB(255, 0, 0));
cv::circle(image1, kp.pt, cvRound(kp.size/2), CV_RGB(255, 0, 0));
}
for(size_t i = 0; i < keypoints2.size(); ++i)
{
const KeyPoint& kp = keypoints2[i];
cv::circle(image2, kp.pt, cvRound(kp.size/2), CV_RGB(255, 0, 0));
cv::circle(image2, kp.pt, cvRound(kp.size/2), CV_RGB(255, 0, 0));
}
Mat kps1(1, (int)(keypoints1.size() * sizeof(KeyPoint)), CV_8U, &keypoints1[0]);
......@@ -99,14 +99,14 @@ void CV_FastTest::run( int )
fs << "exp_kps1" << kps1;
fs << "exp_kps2" << kps2;
fs.release();
}
}
if (!fs.isOpened())
fs.open(xml, FileStorage::READ);
Mat exp_kps1, exp_kps2;
Mat exp_kps1, exp_kps2;
read( fs["exp_kps1"], exp_kps1, Mat() );
read( fs["exp_kps2"], exp_kps2, Mat() );
read( fs["exp_kps2"], exp_kps2, Mat() );
fs.release();
if ( 0 != norm(exp_kps1, kps1, NORM_L2) || 0 != norm(exp_kps2, kps2, NORM_L2))
......@@ -114,7 +114,7 @@ void CV_FastTest::run( int )
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return;
}
/* cv::namedWindow("Img1"); cv::imshow("Img1", image1);
cv::namedWindow("Img2"); cv::imshow("Img2", image2);
cv::waitKey(0);*/
......
......@@ -50,8 +50,8 @@ using namespace cv;
class CV_MserTest : public cvtest::BaseTest
{
public:
CV_MserTest();
protected:
CV_MserTest();
protected:
void run(int);
int LoadBoxes(const char* path, vector<CvBox2D>& boxes);
int SaveBoxes(const char* path, const vector<CvBox2D>& boxes);
......@@ -71,7 +71,7 @@ int CV_MserTest::LoadBoxes(const char* path, vector<CvBox2D>& boxes)
{
return 0;
}
while (!feof(f))
{
CvBox2D box;
......@@ -175,12 +175,12 @@ void CV_MserTest::run(int)
{
RotatedRect box = fitEllipse(msers[i]);
box.angle=(float)CV_PI/2-box.angle;
boxes.push_back(box);
boxes.push_back(box);
}
string boxes_path = string(ts->get_data_path()) + "mser/boxes.txt";
string calc_boxes_path = string(ts->get_data_path()) + "mser/boxes.calc.txt";
if (!LoadBoxes(boxes_path.c_str(),boxes_orig))
{
SaveBoxes(boxes_path.c_str(),boxes);
......
......@@ -128,7 +128,7 @@ void NearestNeighborTest::run( int /*start_from*/ ) {
randu( desc, Scalar(minValue), Scalar(maxValue) );
createModel( desc );
tempCode = checkGetPoins( desc );
if( tempCode != cvtest::TS::OK )
{
......@@ -149,9 +149,9 @@ void NearestNeighborTest::run( int /*start_from*/ ) {
ts->printf( cvtest::TS::LOG, "bad accuracy of Find \n" );
code = tempCode;
}
releaseModel();
ts->set_failed_test_info( code );
}
......@@ -398,7 +398,7 @@ void CV_FlannSavedIndexTest::createModel(const cv::Mat &data)
}
string filename = tempfile();
index->save( filename );
createIndex( data, SavedIndexParams(filename.c_str()));
remove( filename.c_str() );
}
......
......@@ -529,7 +529,7 @@ GPU_PERF_TEST(VideoWriter, cv::gpu::DeviceInfo, std::string)
cv::gpu::setDevice(devInfo.deviceID());
std::string inputFile = perf::TestBase::getDataPath(std::string("gpu/video/") + GET_PARAM(1));
std::string outputFile = inputFile.substr(0, inputFile.find('.')) + "_test.avi";
std::string outputFile = cv::tempfile(".avi");
cv::VideoCapture reader(inputFile);
ASSERT_TRUE( reader.isOpened() );
......
......@@ -338,7 +338,7 @@ GPU_PERF_TEST(VideoWriter, cv::gpu::DeviceInfo, std::string)
const double FPS = 25.0;
std::string inputFile = perf::TestBase::getDataPath(std::string("gpu/video/") + GET_PARAM(1));
std::string outputFile = inputFile.substr(0, inputFile.find('.')) + "_test.avi";
std::string outputFile = cv::tempfile(".avi");
cv::VideoCapture reader(inputFile);
ASSERT_TRUE( reader.isOpened() );
......
......@@ -687,7 +687,7 @@ PARAM_TEST_CASE(VideoWriter, cv::gpu::DeviceInfo, std::string)
cv::gpu::setDevice(devInfo.deviceID());
inputFile = std::string(cvtest::TS::ptr()->get_data_path()) + "video/" + inputFile;
outputFile = inputFile.substr(0, inputFile.find('.')) + "_test.avi";
outputFile = cv::tempfile(".avi");
}
};
......
......@@ -59,7 +59,7 @@ public:
const int img_c = 4096;
const double fps0 = 15;
const double time_sec = 1;
const size_t n = sizeof(codec_bmp_tags)/sizeof(codec_bmp_tags[0]);
bool created = false;
......@@ -68,7 +68,7 @@ public:
{
stringstream s; s << codec_bmp_tags[j].tag;
int tag = codec_bmp_tags[j].tag;
if( tag != MKTAG('H', '2', '6', '3') &&
tag != MKTAG('H', '2', '6', '1') &&
//tag != MKTAG('D', 'I', 'V', 'X') &&
......@@ -93,7 +93,7 @@ public:
{
double fps = fps0;
Size frame_s = Size(img_c, img_r);
if( tag == CV_FOURCC('H', '2', '6', '1') )
frame_s = Size(352, 288);
else if( tag == CV_FOURCC('H', '2', '6', '3') )
......@@ -101,10 +101,10 @@ public:
/*else if( tag == CV_FOURCC('M', 'J', 'P', 'G') ||
tag == CV_FOURCC('j', 'p', 'e', 'g') )
frame_s = Size(1920, 1080);*/
if( tag == CV_FOURCC('M', 'P', 'E', 'G') )
fps = 25;
VideoWriter writer(filename, tag, fps, frame_s);
if (writer.isOpened() == false)
......@@ -157,9 +157,9 @@ public:
Mat img, img_next;
cap >> img;
cap >> img_next;
CV_Assert( !img0.empty() && !img.empty() && img_next.empty() );
double diff = norm(img0, img, CV_C);
CV_Assert( diff == 0 );
}
......
......@@ -59,7 +59,7 @@ public:
ts->printf(cvtest::TS::LOG, "finish reading big image\n");
if (img.empty()) ts->set_failed_test_info(cvtest::TS::FAIL_INVALID_TEST_DATA);
ts->printf(cvtest::TS::LOG, "start writing big image\n");
imwrite(string(ts->get_data_path()) + "readwrite/write.png", img);
imwrite(cv::tempfile(".png"), img);
ts->printf(cvtest::TS::LOG, "finish writing big image\n");
}
catch(...)
......@@ -72,10 +72,14 @@ public:
string ext_from_int(int ext)
{
#ifdef HAVE_PNG
if (ext == 0) return ".png";
#endif
if (ext == 1) return ".bmp";
if (ext == 2) return ".pgm";
#ifdef HAVE_TIFF
if (ext == 3) return ".tiff";
#endif
return "";
}
......@@ -92,16 +96,21 @@ public:
for (int k = 1; k <= 5; ++k)
{
for (int ext = 0; ext < 4; ++ext) // 0 - png, 1 - bmp, 2 - pgm, 3 - tiff
{
if(ext_from_int(ext).empty())
continue;
for (int num_channels = 1; num_channels <= 3; num_channels+=2)
{
ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ext_from_int(ext).c_str());
Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));
ts->printf(ts->LOG, "writing image : %s\n", string(string(ts->get_data_path()) + "readwrite/test" + ext_from_int(ext)).c_str());
imwrite(string(ts->get_data_path()) + "readwrite/test" + ext_from_int(ext), img);
ts->printf(ts->LOG, "reading test image : %s\n", string(string(ts->get_data_path()) + "readwrite/test" + ext_from_int(ext)).c_str());
Mat img_test = imread(string(ts->get_data_path()) + "readwrite/test" + ext_from_int(ext), CV_LOAD_IMAGE_UNCHANGED);
string img_path = cv::tempfile(ext_from_int(ext).c_str());
ts->printf(ts->LOG, "writing image : %s\n", img_path.c_str());
imwrite(img_path, img);
ts->printf(ts->LOG, "reading test image : %s\n", img_path.c_str());
Mat img_test = imread(img_path, CV_LOAD_IMAGE_UNCHANGED);
if (img_test.empty()) ts->set_failed_test_info(ts->FAIL_MISMATCH);
......@@ -115,14 +124,17 @@ public:
ts->set_failed_test_info(ts->FAIL_MISMATCH);
}
}
}
#ifdef HAVE_JPEG
for (int num_channels = 1; num_channels <= 3; num_channels+=2)
{
// jpeg
ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_8U, num_channels, ".jpg");
Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_8U, num_channels), Scalar::all(0));
circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));
string filename = string(ts->get_data_path() + "readwrite/test_" + char(k + 48) + "_c" + char(num_channels + 48) + "_.jpg");
string filename = cv::tempfile(".jpg");
imwrite(filename, img);
img = imread(filename, CV_LOAD_IMAGE_UNCHANGED);
......@@ -142,14 +154,17 @@ public:
ts->set_failed_test_info(ts->FAIL_MISMATCH);
}
}
#endif
#ifdef HAVE_TIFF
for (int num_channels = 1; num_channels <= 3; num_channels+=2)
{
// tiff
ts->printf(ts->LOG, "image type depth:%d channels:%d ext: %s\n", CV_16U, num_channels, ".tiff");
Mat img(img_r * k, img_c * k, CV_MAKETYPE(CV_16U, num_channels), Scalar::all(0));
circle(img, Point2i((img_c * k) / 2, (img_r * k) / 2), cv::min((img_r * k), (img_c * k)) / 4 , Scalar::all(255));
string filename = string(ts->get_data_path() + "readwrite/test.tiff");
string filename = cv::tempfile(".tiff");
imwrite(filename, img);
ts->printf(ts->LOG, "reading test image : %s\n", filename.c_str());
Mat img_test = imread(filename, CV_LOAD_IMAGE_UNCHANGED);
......@@ -171,6 +186,7 @@ public:
ts->set_failed_test_info(ts->FAIL_MISMATCH);
}
}
#endif
}
}
catch(const cv::Exception & e)
......@@ -205,9 +221,7 @@ public:
TEST(Highgui_Image, write_big) { CV_GrfmtWriteBigImageTest test; test.safe_run(); }
#endif
#if defined(HAVE_PNG) && defined(HAVE_TIFF) && defined(HAVE_JPEG)
TEST(Highgui_Image, write_imageseq) { CV_GrfmtWriteSequenceImageTest test; test.safe_run(); }
#endif
TEST(Highgui_Image, read_bmp_rle8) { CV_GrfmtReadBMPRLE8Test test; test.safe_run(); }
......@@ -155,7 +155,7 @@ void CV_HighGuiTest::ImageTest(const string& dir)
for(size_t i = 0; i < ext_num; ++i)
{
string ext = exts[i];
string full_name = "img." + ext;
string full_name = cv::tempfile(ext.c_str());
ts->printf(ts->LOG, " full_name : %s\n", full_name.c_str());
imwrite(full_name, image);
......@@ -225,7 +225,7 @@ void CV_HighGuiTest::ImageTest(const string& dir)
void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt)
{
string src_file = dir + "../cv/shared/video_for_test.avi";
string tmp_name = format("video_%s.%s", cvtest::fourccToString(fmt.fourcc).c_str(), fmt.ext.c_str());
string tmp_name = cv::tempfile((cvtest::fourccToString(fmt.fourcc) + "." + fmt.ext).c_str());
ts->printf(ts->LOG, "reading video : %s and converting it to %s\n", src_file.c_str(), tmp_name.c_str());
......@@ -291,8 +291,8 @@ void CV_HighGuiTest::VideoTest(const string& dir, const cvtest::VideoFormat& fmt
if (psnr < thresDbell)
{
printf("Too low psnr = %gdb\n", psnr);
imwrite("img.png", img);
imwrite("img1.png", img1);
// imwrite("img.png", img);
// imwrite("img1.png", img1);
ts->set_failed_test_info(ts->FAIL_MISMATCH);
break;
}
......@@ -323,7 +323,7 @@ void CV_HighGuiTest::SpecificImageTest(const string& dir)
stringstream s_digit; s_digit << i;
string full_name = "img_"+s_digit.str()+".bmp";
string full_name = cv::tempfile((s_digit.str() + ".bmp").c_str());
ts->printf(ts->LOG, " full_name : %s\n", full_name.c_str());
imwrite(full_name, image);
......@@ -395,7 +395,7 @@ void CV_HighGuiTest::SpecificVideoTest(const string& dir, const cvtest::VideoFor
int fourcc = fmt.fourcc;
string fourcc_str = cvtest::fourccToString(fourcc);
const string video_file = "video_" + fourcc_str + "." + ext;
const string video_file = cv::tempfile((fourcc_str + "." + ext).c_str());
Size frame_size(968 & -2, 757 & -2);
VideoWriter writer(video_file, fourcc, 25, frame_size, true);
......
......@@ -53,29 +53,27 @@ public:
{
framesize = Size(640, 480);
}
Mat drawFrame(int i)
{
Mat mat = Mat::zeros(framesize, CV_8UC3);
mat = Scalar(fabs(cos(i*0.08)*255), fabs(sin(i*0.05)*255), i);
putText(mat, format("%03d", i), Point(10, 350), 0, 10, Scalar(128, 255, 255), 15);
return mat;
}
string getFilename(const cvtest::VideoFormat& fmt)
{
return format("test_video_%s.%s", cvtest::fourccToString(fmt.fourcc).c_str(), fmt.ext.c_str());
return cv::tempfile((cvtest::fourccToString(fmt.fourcc) + "." + fmt.ext).c_str());
}
bool CreateTestVideo(const cvtest::VideoFormat& fmt, int framecount)
bool CreateTestVideo(const cvtest::VideoFormat& fmt, int framecount, string filename)
{
string filename = getFilename(fmt);
VideoWriter writer(filename, fmt.fourcc, 25, framesize, true);
if( !writer.isOpened() )
return false;
for (int i = 0; i < framecount; ++i)
{
Mat img = drawFrame(i);
......@@ -87,7 +85,7 @@ public:
void run(int)
{
int n_frames = 100;
for( int testcase = 0; ; testcase++ )
{
const cvtest::VideoFormat& fmt = cvtest::g_specific_fmt_list[testcase];
......@@ -96,82 +94,82 @@ public:
string filename = getFilename(fmt);
ts->printf(ts->LOG, "\nFile: %s\n", filename.c_str());
if( !CreateTestVideo(fmt, n_frames) )
if( !CreateTestVideo(fmt, n_frames, filename) )
{
ts->printf(ts->LOG, "\nError: cannot create video file");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
VideoCapture cap(filename);
if (!cap.isOpened())
{
ts->printf(ts->LOG, "\nError: cannot read video file.");
ts->set_failed_test_info(ts->FAIL_INVALID_TEST_DATA);
return;
}
int N0 = (int)cap.get(CV_CAP_PROP_FRAME_COUNT);
cap.set(CV_CAP_PROP_POS_FRAMES, 0);
int N = (int)cap.get(CV_CAP_PROP_FRAME_COUNT);
if (N != n_frames || N != N0)
{
ts->printf(ts->LOG, "\nError: returned frame count (N0=%d, N=%d) is different from the reference number %d\n", N0, N, n_frames);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
for (int k = 0; k < N; ++k)
{
int idx = theRNG().uniform(0, N);
if( !cap.set(CV_CAP_PROP_POS_FRAMES, idx) )
{
ts->printf(ts->LOG, "\nError: cannot seek to frame %d.\n", idx);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
int idx1 = (int)cap.get(CV_CAP_PROP_POS_FRAMES);
Mat img; cap >> img;
Mat img0 = drawFrame(idx);
if( idx != idx1 )
{
ts->printf(ts->LOG, "\nError: the current position (%d) after seek is different from specified (%d)\n",
idx1, idx);
ts->printf(ts->LOG, "Saving both frames ...\n");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
imwrite("opencv_test_highgui_postest_actual.png", img);
imwrite("opencv_test_highgui_postest_expected.png", img0);
// imwrite("opencv_test_highgui_postest_actual.png", img);
// imwrite("opencv_test_highgui_postest_expected.png", img0);
return;
}
if (img.empty())
{
ts->printf(ts->LOG, "\nError: cannot read a frame at position %d.\n", idx);
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
return;
}
double err = PSNR(img, img0);
if( err < 20 )
{
ts->printf(ts->LOG, "The frame read after positioning to %d is incorrect (PSNR=%g)\n", idx, err);
ts->printf(ts->LOG, "Saving both frames ...\n");
ts->set_failed_test_info(ts->FAIL_INVALID_OUTPUT);
imwrite("opencv_test_highgui_postest_actual.png", img);
imwrite("opencv_test_highgui_postest_expected.png", img0);
// imwrite("opencv_test_highgui_postest_actual.png", img);
// imwrite("opencv_test_highgui_postest_expected.png", img0);
return;
}
}
}
}
Size framesize;
};
......
......@@ -52,10 +52,10 @@ class CV_GrabcutTest : public cvtest::BaseTest
{
public:
CV_GrabcutTest();
~CV_GrabcutTest();
~CV_GrabcutTest();
protected:
bool verify(const Mat& mask, const Mat& exp);
void run(int);
void run(int);
};
CV_GrabcutTest::CV_GrabcutTest() {}
......@@ -73,29 +73,29 @@ bool CV_GrabcutTest::verify(const Mat& mask, const Mat& exp)
}
void CV_GrabcutTest::run( int /* start_from */)
{
{
cvtest::DefaultRngAuto defRng;
Mat img = imread(string(ts->get_data_path()) + "shared/airplane.jpg");
Mat img = imread(string(ts->get_data_path()) + "shared/airplane.jpg");
Mat mask_prob = imread(string(ts->get_data_path()) + "grabcut/mask_prob.png", 0);
Mat exp_mask1 = imread(string(ts->get_data_path()) + "grabcut/exp_mask1.png", 0);
Mat exp_mask2 = imread(string(ts->get_data_path()) + "grabcut/exp_mask2.png", 0);
if (img.empty() || (!mask_prob.empty() && img.size() != mask_prob.size()) ||
(!exp_mask1.empty() && img.size() != exp_mask1.size()) ||
(!exp_mask2.empty() && img.size() != exp_mask2.size()) )
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
ts->set_failed_test_info(cvtest::TS::FAIL_MISSING_TEST_DATA);
return;
}
Rect rect(Point(24, 126), Point(483, 294));
Mat exp_bgdModel, exp_fgdModel;
Mat mask;
mask = Scalar(0);
Mat bgdModel, fgdModel;
grabCut( img, mask, rect, bgdModel, fgdModel, 0, GC_INIT_WITH_RECT );
grabCut( img, mask, rect, bgdModel, fgdModel, 0, GC_INIT_WITH_RECT );
grabCut( img, mask, rect, bgdModel, fgdModel, 2, GC_EVAL );
// Multiply images by 255 for more visuality of test data.
......@@ -109,16 +109,16 @@ void CV_GrabcutTest::run( int /* start_from */)
exp_mask1 = (mask & 1) * 255;
imwrite(string(ts->get_data_path()) + "grabcut/exp_mask1.png", exp_mask1);
}
if (!verify((mask & 1) * 255, exp_mask1))
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return;
}
mask = mask_prob;
bgdModel.release();
fgdModel.release();
fgdModel.release();
rect = Rect();
grabCut( img, mask, rect, bgdModel, fgdModel, 0, GC_INIT_WITH_MASK );
grabCut( img, mask, rect, bgdModel, fgdModel, 1, GC_EVAL );
......@@ -128,13 +128,13 @@ void CV_GrabcutTest::run( int /* start_from */)
exp_mask2 = (mask & 1) * 255;
imwrite(string(ts->get_data_path()) + "grabcut/exp_mask2.png", exp_mask2);
}
if (!verify((mask & 1) * 255, exp_mask2))
{
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
ts->set_failed_test_info(cvtest::TS::FAIL_MISMATCH);
return;
}
ts->set_failed_test_info(cvtest::TS::OK);
}
ts->set_failed_test_info(cvtest::TS::OK);
}
TEST(Imgproc_GrabCut, regression) { CV_GrabcutTest test; test.safe_run(); }
......
......@@ -50,8 +50,8 @@ class CV_WatershedTest : public cvtest::BaseTest
{
public:
CV_WatershedTest();
~CV_WatershedTest();
protected:
~CV_WatershedTest();
protected:
void run(int);
};
......@@ -59,23 +59,23 @@ CV_WatershedTest::CV_WatershedTest() {}
CV_WatershedTest::~CV_WatershedTest() {}
void CV_WatershedTest::run( int /* start_from */)
{
string exp_path = string(ts->get_data_path()) + "watershed/wshed_exp.png";
{
string exp_path = string(ts->get_data_path()) + "watershed/wshed_exp.png";
Mat exp = imread(exp_path, 0);
Mat orig = imread(string(ts->get_data_path()) + "inpaint/orig.jpg");
FileStorage fs(string(ts->get_data_path()) + "watershed/comp.xml", FileStorage::READ);
if (orig.empty() || !fs.isOpened())
{
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
CvSeq* cnts = (CvSeq*)fs["contours"].readObj();
Mat markers(orig.size(), CV_32SC1);
markers = Scalar(0);
IplImage iplmrks = markers;
IplImage iplmrks = markers;
vector<unsigned char> colors(1);
for(int i = 0; cnts != 0; cnts = cnts->h_next, ++i )
......@@ -105,25 +105,25 @@ void CV_WatershedTest::run( int /* start_from */)
if (pixel <= 0 || pixel > compNum)
continue; // bad result, doing nothing and going to get error latter;
// repaint in saved color to compare with expected;
if(exp.data)
pixel = colors[pixel];
pixel = colors[pixel];
}
}
}
Mat markers8U;
markers.convertTo(markers8U, CV_8U, 1, 1);
if( exp.empty() || orig.size() != exp.size() )
{
imwrite(exp_path, markers8U);
exp = markers8U;
}
if (0 != norm(markers8U, exp, NORM_INF))
{
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
{
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
return;
}
ts->set_failed_test_info(cvtest::TS::OK);
......
......@@ -366,7 +366,7 @@ void CV_CvEMTest::run( int /*start_from*/ )
int currCode = runCase(caseIndex++, params, trainData, trainLabels, testData, testLabels, sizes);
code = currCode == cvtest::TS::OK ? code : currCode;
}
ts->set_failed_test_info( code );
}
......@@ -382,7 +382,7 @@ protected:
samples.at<float>(0,0) = 1;
samples.at<float>(1,0) = 2;
samples.at<float>(2,0) = 3;
Mat labels(samples.rows, 1, CV_32S);
CvEMParams params;
......@@ -398,7 +398,7 @@ protected:
// Write out
string filename = tempfile() + ".xml";
string filename = cv::tempfile(".xml");
{
FileStorage fs = FileStorage(filename, FileStorage::WRITE);
try
......
......@@ -421,7 +421,7 @@ void CV_StereoMatchingTest::run(int)
ts->set_failed_test_info( code );
return;
}
string fullResultFilename = dataPath + ALGORITHMS_DIR + algorithmName + RESULT_FILE;
FileStorage resFS( fullResultFilename, FileStorage::READ );
bool isWrite = true; // write or compare results
......@@ -660,7 +660,7 @@ class CV_StereoGCTest : public CV_StereoMatchingTest
public:
CV_StereoGCTest()
{
name = "stereogc";
name = "stereogc";
fill(rmsEps.begin(), rmsEps.end(), 3.f);
fracEps[0] = 0.05f; // all
fracEps[1] = 0.05f; // noOccl
......
......@@ -527,7 +527,7 @@ protected:
firstResult.at<int>(i) = static_cast<int>(em.predict(samples.row(i))[1]);
// Write out
string filename = tempfile() + ".xml";
string filename = cv::tempfile(".xml");
{
FileStorage fs = FileStorage(filename, FileStorage::WRITE);
try
......
......@@ -62,7 +62,7 @@ protected:
class CV_AMLTest : public CV_MLBaseTest
{
public:
CV_AMLTest( const char* _modelName );
CV_AMLTest( const char* _modelName );
protected:
virtual int run_test_case( int testCaseIdx );
virtual int validate_test_results( int testCaseIdx );
......@@ -71,7 +71,7 @@ protected:
class CV_SLMLTest : public CV_MLBaseTest
{
public:
CV_SLMLTest( const char* _modelName );
CV_SLMLTest( const char* _modelName );
protected:
virtual int run_test_case( int testCaseIdx );
virtual int validate_test_results( int testCaseIdx );
......
......@@ -84,7 +84,7 @@ int CV_SLMLTest::validate_test_results( int testCaseIdx )
// 1. compare files
ifstream f1( fname1.c_str() ), f2( fname2.c_str() );
string s1, s2;
int lineIdx = 0;
int lineIdx = 0;
CV_Assert( f1.is_open() && f2.is_open() );
for( ; !f1.eof() && !f2.eof(); lineIdx++ )
{
......
......@@ -44,7 +44,7 @@
#include <string>
#ifdef HAVE_CVCONFIG_H
#ifdef HAVE_CVCONFIG_H
#include "cvconfig.h"
#endif
......@@ -61,7 +61,7 @@ const CvRect true_bounding_boxes[3] = {cvRect(0, 45, 362, 452), cvRect(304, 0, 6
class CV_LatentSVMDetectorTest : public cvtest::BaseTest
{
protected:
protected:
void run(int);
bool isEqual(CvRect r1, CvRect r2, int eps);
};
......@@ -75,7 +75,7 @@ bool CV_LatentSVMDetectorTest::isEqual(CvRect r1, CvRect r2, int eps)
}
void CV_LatentSVMDetectorTest::run( int /* start_from */)
{
{
string img_path = string(ts->get_data_path()) + "latentsvmdetector/cat.jpg";
string model_path = string(ts->get_data_path()) + "latentsvmdetector/models_VOC2007/cat.xml";
int numThreads = -1;
......@@ -102,7 +102,7 @@ void CV_LatentSVMDetectorTest::run( int /* start_from */)
}
CvMemStorage* storage = cvCreateMemStorage(0);
CvSeq* detections = 0;
CvSeq* detections = 0;
detections = cvLatentSvmDetectObjects(image, detector, storage, 0.5f, numThreads);
if (detections->total != num_detections)
{
......
......@@ -49,8 +49,8 @@ class CV_InpaintTest : public cvtest::BaseTest
{
public:
CV_InpaintTest();
~CV_InpaintTest();
protected:
~CV_InpaintTest();
protected:
void run(int);
};
......@@ -61,43 +61,40 @@ CV_InpaintTest::~CV_InpaintTest() {}
void CV_InpaintTest::run( int )
{
string folder = string(ts->get_data_path()) + "inpaint/";
Mat orig = imread(folder + "orig.jpg");
string folder = string(ts->get_data_path()) + "inpaint/";
Mat orig = imread(folder + "orig.jpg");
Mat exp1 = imread(folder + "exp1.png");
Mat exp2 = imread(folder + "exp2.png");
Mat mask = imread(folder + "mask.png");
Mat mask = imread(folder + "mask.png");
if (orig.empty() || exp1.empty() || exp2.empty() || mask.empty())
{
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_TEST_DATA );
return;
}
Mat inv_mask;
Mat inv_mask;
mask.convertTo(inv_mask, CV_8UC3, -1.0, 255.0);
Mat mask1ch;
cv::cvtColor(mask, mask1ch, CV_BGR2GRAY);
Mat test = orig.clone();
test.setTo(Scalar::all(255), mask1ch);
test.setTo(Scalar::all(255), mask1ch);
Mat res1, res2;
inpaint( test, mask1ch, res1, 5, CV_INPAINT_NS );
inpaint( test, mask1ch, res2, 5, CV_INPAINT_TELEA );
imwrite("d:/exp1.png", res1);
imwrite("d:/exp2.png", res2);
inpaint( test, mask1ch, res2, 5, CV_INPAINT_TELEA );
Mat diff1, diff2;
absdiff( orig, res1, diff1 );
absdiff( orig, res2, diff2 );
double n1 = norm(diff1.reshape(1), NORM_INF, inv_mask.reshape(1));
double n2 = norm(diff2.reshape(1), NORM_INF, inv_mask.reshape(1));
if (n1 != 0 || n2 != 0)
{
{
ts->set_failed_test_info( cvtest::TS::FAIL_MISMATCH );
return;
}
......@@ -109,9 +106,9 @@ void CV_InpaintTest::run( int )
n2 = norm(diff2.reshape(1), NORM_INF, mask.reshape(1));
const int jpeg_thres = 3;
if (n1 > jpeg_thres || n2 > jpeg_thres)
if (n1 > jpeg_thres || n2 > jpeg_thres)
{
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
ts->set_failed_test_info( cvtest::TS::FAIL_BAD_ACCURACY );
return;
}
......
......@@ -37,8 +37,6 @@ for l in open("%s/api" % sys.argv[1]):
# Validation: check that any optional arguments are last
had_error = False
for (f, args, ty, flags) in api:
if f == 'PolarToCart':
print f, [(a.init != None) for a in args]
has_init = [(a.init != None) for a in args if not 'O' in a.flags]
if True in has_init and not all(has_init[has_init.index(True):]):
print 'Error in definition for "%s", optional arguments must be last' % f
......@@ -130,7 +128,7 @@ def has_optional(al):
def gen(name, args, ty, flags):
yield ""
if has_optional(args):
yield "static PyObject *pycv%s(PyObject *self, PyObject *args, PyObject *kw)" % cname(name)
yield "static PyObject *pycv%s(PyObject *self, PyObject *args, PyObject *kw)" % cname(name)
else:
yield "static PyObject *pycv%s(PyObject *self, PyObject *args)" % cname(name)
if 'doconly' in flags:
......@@ -185,7 +183,7 @@ def gen(name, args, ty, flags):
in_args = [ a for a in args if not 'O' in a.flags ]
fmt0 = "".join([ fmap[a.ty] for a in in_args if not a.init])
fmt1 = "".join([ fmap[a.ty] for a in in_args if a.init])
yield ''
if len(fmt0 + fmt1) > 0:
if len(fmt1) > 0:
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment