Skip to content

Commit

Permalink
fix issues with calibration for large images
Browse files Browse the repository at this point in the history
for larger cal images (~4kx4k) the keypoint finding routine wasn't working
well. Now it checks to be sure that the 3 keypoints are relatively the
same size (+/- 30%) to prevent the auto thresholding algorithm from
inadvertently setting the threshold based on three bogus keypoints
  • Loading branch information
dicengine committed Mar 26, 2021
1 parent fd7777f commit 8376f45
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 17 deletions.
21 changes: 19 additions & 2 deletions src/opencv/DICe_Calibration.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,6 +567,8 @@ Calibration::extract_dot_target_points(){
const int_t orig_thresh_start = input_params_.get<int_t>(opencv_server_threshold_start,20);
const int_t orig_thresh_end = input_params_.get<int_t>(opencv_server_threshold_end,250);
const int_t orig_thresh_step = input_params_.get<int_t>(opencv_server_threshold_step,5);
if(!input_params_.isParameter(opencv_server_min_blob_size))
input_params_.set<int_t>(opencv_server_min_blob_size,100);
scalar_t include_image_set_tol = 0.75; //the search must have found at least 75% of the total to be included
for (size_t i_image = 0; i_image < num_images(); i_image++){
//go through each of the camera's images (note only two camera calibration is currently supported)
Expand All @@ -590,13 +592,18 @@ Calibration::extract_dot_target_points(){
int_t return_thresh = orig_thresh_start;
int_t error_code = opencv_dot_targets(img, input_params_,
key_points,img_points,grd_points,return_thresh);

// check to see if the min_blob_size needs to be adjusted, first try 10 (smaller), then try 500 (larger):
if(error_code!=0){
}

// check if extraction failed
if(error_code==0){
input_params_.set(opencv_server_threshold_start,return_thresh);
input_params_.set(opencv_server_threshold_start,return_thresh); // make all the values the same so the auto thresholding is skipped next time
input_params_.set(opencv_server_threshold_end,return_thresh);
input_params_.set(opencv_server_threshold_step,return_thresh);
}else if(i_image!=0&&error_code==1){
input_params_.set(opencv_server_threshold_start,orig_thresh_start);
input_params_.set(opencv_server_threshold_start,orig_thresh_start); // reset the thresholds and re-run the auto thresholding routine
input_params_.set(opencv_server_threshold_end,orig_thresh_end);
input_params_.set(opencv_server_threshold_step,orig_thresh_step);
error_code = opencv_dot_targets(img, input_params_,
Expand All @@ -605,6 +612,16 @@ Calibration::extract_dot_target_points(){
input_params_.set(opencv_server_threshold_start,return_thresh);
input_params_.set(opencv_server_threshold_end,return_thresh);
input_params_.set(opencv_server_threshold_step,return_thresh);
}else{
input_params_.set<int_t>(opencv_server_min_blob_size,10);
DEBUG_MSG("Calibration::extract_dot_target_points(): resetting the min_blob_size to 10 and trying again.");
error_code = opencv_dot_targets(img, input_params_,
key_points,img_points,grd_points,return_thresh);
if(error_code==0){
input_params_.set(opencv_server_threshold_start,return_thresh);
input_params_.set(opencv_server_threshold_end,return_thresh);
input_params_.set(opencv_server_threshold_step,return_thresh);
}
}
}

Expand Down
70 changes: 55 additions & 15 deletions src/opencv/DICe_OpenCVServerUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,20 @@ int_t opencv_dot_targets(cv::Mat & img,
std::vector<cv::KeyPoint> key_points;
std::vector<cv::KeyPoint> img_points;
std::vector<cv::KeyPoint> grd_points;
return opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
if(!options.isParameter(opencv_server_min_blob_size))
options.set<int_t>(opencv_server_min_blob_size,100);
int_t error_code = opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
if(error_code!=0){
DEBUG_MSG("opencv_dot_targets(): resetting the min_blob_size to 10 and trying again.");
options.set<int_t>(opencv_server_min_blob_size,10);
error_code = opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
// if(error_code!=0){
// DEBUG_MSG("opencv_dot_targets(): resetting the min_blob_size to 500 and trying again.");
// options.set<int_t>(opencv_server_min_blob_size,500);
// error_code = opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
// }
}
return error_code;
}

DICE_LIB_DLL_EXPORT
Expand All @@ -602,7 +615,6 @@ int_t opencv_dot_targets(Mat & img,
options.print(std::cout);
#endif


// clone the input image so that we have a copy of the original
Mat img_cpy = img.clone();

Expand Down Expand Up @@ -632,8 +644,8 @@ int_t opencv_dot_targets(Mat & img,
// cv::THRESH_TRIANGLE = 16
int threshold_mode = options.get<int_t>(opencv_server_threshold_mode,0);
//std::cout << "opencv_dot_targets(): option, threshold mode: " << threshold_mode << std::endl;
int min_blob_size = 100;

int min_blob_size = options.get<int_t>(opencv_server_min_blob_size,100);
DEBUG_MSG("using min_blob_size: " << min_blob_size);
// establish the calibration plate properties
TEUCHOS_TEST_FOR_EXCEPTION(!options.isParameter(DICe::num_cal_fiducials_x),std::runtime_error,"");
TEUCHOS_TEST_FOR_EXCEPTION(!options.isParameter(DICe::num_cal_fiducials_y),std::runtime_error,"");
Expand Down Expand Up @@ -698,17 +710,19 @@ int_t opencv_dot_targets(Mat & img,
// chances are that this indicates p thresholding problem to begin with
if (key_points.size() != 3) {
// try again to see if the markers a too small, if so enable smaller blob sizes and try again
min_blob_size = 10;
get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
if(key_points.size() !=3){
// try a larger min blob size
min_blob_size = 500;
get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
if(key_points.size() != 3){
std::cout << "*** warning: unable to identify three keypoints, other points will not be extracted" << std::endl;
keypoints_found = false;
}
}
// min_blob_size = 10;
// get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
// if(key_points.size() !=3){
std::cout << "*** warning: unable to identify three keypoints, other points will not be extracted" << std::endl;
keypoints_found = false;
// // try a larger min blob size
// min_blob_size = 500;
// get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
// if(key_points.size() != 3){
// std::cout << "*** warning: unable to identify three keypoints, other points will not be extracted" << std::endl;
// keypoints_found = false;
// }
// }
}
Point cvpoint;
if(preview_thresh){
Expand Down Expand Up @@ -856,6 +870,7 @@ void get_dot_markers(cv::Mat img,

// setup the blob detector
SimpleBlobDetector::Params params;
params.filterByArea = true;
params.maxArea = 10e4;
params.minArea = min_size;
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create(params);
Expand Down Expand Up @@ -884,7 +899,32 @@ void get_dot_markers(cv::Mat img,
// detect dots on the appropriately inverted image
if (invert) detector->detect(not_src, keypoints);
else detector->detect(bi_src, keypoints);
DEBUG_MSG("get_dot_markers(): preliminary num keypoints " << keypoints.size());
if(keypoints.size()==0) return;
// the diameters of the keypoints should be within 30% of each other
float avg_diameter = 0.0f;
for(size_t i=0;i<keypoints.size();++i){
avg_diameter += keypoints[i].size;
}
avg_diameter /= keypoints.size();
DEBUG_MSG("get_dot_markers(): avg keypoint diameter " << avg_diameter);

size_t i = keypoints.size();
while (i--) {
// DEBUG_MSG("get_dot_markers(): possible keypoint " << i << " diameter " << keypoints[i].size);
// remove the keypoint from the vector
if(keypoints[i].size<=0.0){
// DEBUG_MSG("get_dot_markers(): removing keypoint " << i << " due to keypoint size == 0.0");
keypoints.erase(keypoints.begin() + i);
}
if(std::abs(keypoints[i].size-avg_diameter)/avg_diameter>0.30){
// DEBUG_MSG("get_dot_markers(): removing keypoint " << i << " due to keypoint size >30% difference in diameter from avg");
keypoints.erase(keypoints.begin() + i);
}
}
DEBUG_MSG("get_dot_markers(): num keypoints " << keypoints.size());
// for (size_t i = 0;i<keypoints.size();++i)
// DEBUG_MSG("get_dot_markers(): keypoint " << i << " diameter " << keypoints[i].size);
}

//calculate the transformation coefficients
Expand Down
1 change: 1 addition & 0 deletions src/opencv/DICe_OpenCVServerUtils.h
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ const char* const opencv_server_threshold_start = "threshold_start";
const char* const opencv_server_threshold_end = "threshold_end";
const char* const opencv_server_threshold_step = "threshold_step";
const char* const opencv_server_block_size = "block_size";
const char* const opencv_server_min_blob_size = "min_blob_size";
const char* const opencv_server_binary_constant = "binary_constant";
const char* const opencv_server_dot_tol = "dot_tol";
const char* const opencv_server_use_adaptive_threshold = "use_adaptive_threshold";
Expand Down

0 comments on commit 8376f45

Please sign in to comment.