bool findChessboardCornersSB(InputArray image,Size patternSize, OutputArray corners,
int flags,OutputArray meta);
/** @overload */
-CV_EXPORTS_W static inline
+CV_EXPORTS_W inline
bool findChessboardCornersSB(InputArray image, Size patternSize, OutputArray corners,
int flags = 0)
{
return findChessboardCornersSB(image, patternSize, corners, flags, noArray());
}
+/** @brief Estimates the sharpness of a detected chessboard.
+
+Image sharpness, as well as brightness, are a critical parameter for accuracte
+camera calibration. For accessing these parameters for filtering out
+problematic calibraiton images, this method calculates edge profiles by traveling from
+black to white chessboard cell centers. Based on this, the number of pixels is
+calculated required to transit from black to white. This width of the
+transition area is a good indication of how sharp the chessboard is imaged
+and should be below ~3.0 pixels.
+
+@param image Gray image used to find chessboard corners
+@param patternSize Size of a found chessboard pattern
+@param corners Corners found by findChessboardCorners(SB)
+@param rise_distance Rise distance 0.8 means 10% ... 90% of the final signal strength
+@param vertical By default edge responses for horizontal lines are calculated
+@param sharpness Optional output array with a sharpness value for calculated edge responses (see description)
+
+The optional sharpness array is of type CV_32FC1 and has for each calculated
+profile one row with the following five entries:
+* 0 = x coordinate of the underlying edge in the image
+* 1 = y coordinate of the underlying edge in the image
+* 2 = width of the transition area (sharpness)
+* 3 = signal strength in the black cell (min brightness)
+* 4 = signal strength in the white cell (max brightness)
+
+@return Scalar(average sharpness, average min brightness, average max brightness,0)
+*/
+CV_EXPORTS_W Scalar estimateChessboardSharpness(InputArray image, Size patternSize, InputArray corners,
+ float rise_distance=0.8F,bool vertical=false,
+ OutputArray sharpness=noArray());
+
+
//! finds subpixel-accurate positions of the chessboard corners
CV_EXPORTS_W bool find4QuadCornerSubpix( InputArray img, InputOutputArray corners, Size region_size );
// calc images
// for each angle step
int scale_id = scale-parameters.min_scale;
- int scale_size = int(pow(2.0,scale+1+super_res)-1);
- int scale_size2 = int((scale_size/10)*2+1);
+ int scale_size = int(pow(2.0,scale+1+super_res));
+ int scale_size2 = int((scale_size/7)*2+1);
std::vector<cv::UMat> images;
images.resize(2*num);
cv::UMat rotated,filtered_h,filtered_v;
- cv::blur(gray_image,images[0],cv::Size(scale_size,scale_size2));
- cv::blur(gray_image,images[num],cv::Size(scale_size2,scale_size));
+ cv::boxFilter(gray_image,images[0],-1,cv::Size(scale_size,scale_size2));
+ cv::boxFilter(gray_image,images[num],-1,cv::Size(scale_size2,scale_size));
for(int i=1;i<num;++i)
{
float angle = parameters.resolution*i;
rotate(-angle,gray_image,size,rotated);
- cv::blur(rotated,filtered_h,cv::Size(scale_size,scale_size2));
- cv::blur(rotated,filtered_v,cv::Size(scale_size2,scale_size));
+ cv::boxFilter(rotated,filtered_h,-1,cv::Size(scale_size,scale_size2));
+ cv::boxFilter(rotated,filtered_v,-1,cv::Size(scale_size2,scale_size));
// rotate filtered images back
rotate(angle,filtered_h,gray_image.size(),images[i]);
if(parameters.filter)
{
cv::Mat high,low;
- cv::blur(feature_maps[scale_id],low,cv::Size(scale_size,scale_size));
+ cv::boxFilter(feature_maps[scale_id],low,-1,cv::Size(scale_size,scale_size));
int scale2 = int((scale_size/6))*2+1;
- cv::blur(feature_maps[scale_id],high,cv::Size(scale2,scale2));
+ cv::boxFilter(feature_maps[scale_id],high,-1,cv::Size(scale2,scale2));
feature_maps[scale_id] = high-0.8*low;
}
}
if(flags & CALIB_CB_EXHAUSTIVE)
{
para.max_tests = 100;
- para.max_points = std::max(500,pattern_size.width*pattern_size.height*2);
+ para.max_points = std::max(1000,pattern_size.width*pattern_size.height*2);
flags ^= CALIB_CB_EXHAUSTIVE;
}
if(flags & CALIB_CB_ACCURACY)
return true;
}
+// public API
+cv::Scalar estimateChessboardSharpness(InputArray image_, Size patternSize, InputArray corners_,
+ float rise_distance,bool vertical, cv::OutputArray sharpness)
+{
+ CV_INSTRUMENT_REGION();
+ int type = image_.type(), depth = CV_MAT_DEPTH(type), cn = CV_MAT_CN(type);
+ CV_CheckType(type, depth == CV_8U && (cn == 1 || cn == 3),
+ "Only 8-bit grayscale or color images are supported");
+ if(patternSize.width <= 2 || patternSize.height <= 2)
+ CV_Error(Error::StsOutOfRange, "Both width and height of the pattern should have bigger than 2");
+
+ cv::Mat corners = details::normalizeVector(corners_);
+ std::vector<cv::Point2f> points;
+ corners.reshape(2,corners.rows).convertTo(points,CV_32FC2);
+ if(int(points.size()) != patternSize.width * patternSize.height)
+ CV_Error(Error::StsBadArg, "Size mismatch between patternSize and number of provided corners.");
+
+ Mat img;
+ if (image_.channels() != 1)
+ cvtColor(image_, img, COLOR_BGR2GRAY);
+ else
+ img = image_.getMat();
+
+ details::Chessboard::Board board(patternSize,points);
+ return board.calcEdgeSharpness(img,rise_distance,vertical,sharpness);
+}
+
+
} // namespace cv
String _filename = folder + (String)board_list[idx * 2 + 1];
bool doesContatinChessboard;
+ float sharpness;
Mat expected;
{
FileStorage fs1(_filename, FileStorage::READ);
fs1["corners"] >> expected;
fs1["isFound"] >> doesContatinChessboard;
+ fs1["sharpness"] >> sharpness ;
fs1.release();
}
size_t count_exp = static_cast<size_t>(expected.cols * expected.rows);
flags = 0;
}
bool result = findChessboardCornersWrapper(gray, pattern_size,v,flags);
+ if(result && sharpness && (pattern == CHESSBOARD_SB || pattern == CHESSBOARD))
+ {
+ Scalar s= estimateChessboardSharpness(gray,pattern_size,v);
+ if(fabs(s[0] - sharpness) > 0.1)
+ {
+ ts->printf(cvtest::TS::LOG, "chessboard image has a wrong sharpness in %s. Expected %f but measured %f\n", img_file.c_str(),sharpness,s[0]);
+ ts->set_failed_test_info( cvtest::TS::FAIL_INVALID_OUTPUT );
+ show_points( gray, expected, v, result );
+ return;
+ }
+ }
if(result ^ doesContatinChessboard || (doesContatinChessboard && v.size() != count_exp))
{
ts->printf( cvtest::TS::LOG, "chessboard is detected incorrectly in %s\n", img_file.c_str() );