Skip to content

Commit 8376f45

Browse files
committed
fix issues with calibration for large images
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
1 parent fd7777f commit 8376f45

File tree

3 files changed

+75
-17
lines changed

3 files changed

+75
-17
lines changed

src/opencv/DICe_Calibration.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ Calibration::extract_dot_target_points(){
567567
const int_t orig_thresh_start = input_params_.get<int_t>(opencv_server_threshold_start,20);
568568
const int_t orig_thresh_end = input_params_.get<int_t>(opencv_server_threshold_end,250);
569569
const int_t orig_thresh_step = input_params_.get<int_t>(opencv_server_threshold_step,5);
570+
if(!input_params_.isParameter(opencv_server_min_blob_size))
571+
input_params_.set<int_t>(opencv_server_min_blob_size,100);
570572
scalar_t include_image_set_tol = 0.75; //the search must have found at least 75% of the total to be included
571573
for (size_t i_image = 0; i_image < num_images(); i_image++){
572574
//go through each of the camera's images (note only two camera calibration is currently supported)
@@ -590,13 +592,18 @@ Calibration::extract_dot_target_points(){
590592
int_t return_thresh = orig_thresh_start;
591593
int_t error_code = opencv_dot_targets(img, input_params_,
592594
key_points,img_points,grd_points,return_thresh);
595+
596+
// check to see if the min_blob_size needs to be adjusted, first try 10 (smaller), then try 500 (larger):
597+
if(error_code!=0){
598+
}
599+
593600
// check if extraction failed
594601
if(error_code==0){
595-
input_params_.set(opencv_server_threshold_start,return_thresh);
602+
input_params_.set(opencv_server_threshold_start,return_thresh); // make all the values the same so the auto thresholding is skipped next time
596603
input_params_.set(opencv_server_threshold_end,return_thresh);
597604
input_params_.set(opencv_server_threshold_step,return_thresh);
598605
}else if(i_image!=0&&error_code==1){
599-
input_params_.set(opencv_server_threshold_start,orig_thresh_start);
606+
input_params_.set(opencv_server_threshold_start,orig_thresh_start); // reset the thresholds and re-run the auto thresholding routine
600607
input_params_.set(opencv_server_threshold_end,orig_thresh_end);
601608
input_params_.set(opencv_server_threshold_step,orig_thresh_step);
602609
error_code = opencv_dot_targets(img, input_params_,
@@ -605,6 +612,16 @@ Calibration::extract_dot_target_points(){
605612
input_params_.set(opencv_server_threshold_start,return_thresh);
606613
input_params_.set(opencv_server_threshold_end,return_thresh);
607614
input_params_.set(opencv_server_threshold_step,return_thresh);
615+
}else{
616+
input_params_.set<int_t>(opencv_server_min_blob_size,10);
617+
DEBUG_MSG("Calibration::extract_dot_target_points(): resetting the min_blob_size to 10 and trying again.");
618+
error_code = opencv_dot_targets(img, input_params_,
619+
key_points,img_points,grd_points,return_thresh);
620+
if(error_code==0){
621+
input_params_.set(opencv_server_threshold_start,return_thresh);
622+
input_params_.set(opencv_server_threshold_end,return_thresh);
623+
input_params_.set(opencv_server_threshold_step,return_thresh);
624+
}
608625
}
609626
}
610627

src/opencv/DICe_OpenCVServerUtils.cpp

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -583,7 +583,20 @@ int_t opencv_dot_targets(cv::Mat & img,
583583
std::vector<cv::KeyPoint> key_points;
584584
std::vector<cv::KeyPoint> img_points;
585585
std::vector<cv::KeyPoint> grd_points;
586-
return opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
586+
if(!options.isParameter(opencv_server_min_blob_size))
587+
options.set<int_t>(opencv_server_min_blob_size,100);
588+
int_t error_code = opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
589+
if(error_code!=0){
590+
DEBUG_MSG("opencv_dot_targets(): resetting the min_blob_size to 10 and trying again.");
591+
options.set<int_t>(opencv_server_min_blob_size,10);
592+
error_code = opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
593+
// if(error_code!=0){
594+
// DEBUG_MSG("opencv_dot_targets(): resetting the min_blob_size to 500 and trying again.");
595+
// options.set<int_t>(opencv_server_min_blob_size,500);
596+
// error_code = opencv_dot_targets(img,options,key_points,img_points,grd_points, return_thresh);
597+
// }
598+
}
599+
return error_code;
587600
}
588601

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

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

@@ -632,8 +644,8 @@ int_t opencv_dot_targets(Mat & img,
632644
// cv::THRESH_TRIANGLE = 16
633645
int threshold_mode = options.get<int_t>(opencv_server_threshold_mode,0);
634646
//std::cout << "opencv_dot_targets(): option, threshold mode: " << threshold_mode << std::endl;
635-
int min_blob_size = 100;
636-
647+
int min_blob_size = options.get<int_t>(opencv_server_min_blob_size,100);
648+
DEBUG_MSG("using min_blob_size: " << min_blob_size);
637649
// establish the calibration plate properties
638650
TEUCHOS_TEST_FOR_EXCEPTION(!options.isParameter(DICe::num_cal_fiducials_x),std::runtime_error,"");
639651
TEUCHOS_TEST_FOR_EXCEPTION(!options.isParameter(DICe::num_cal_fiducials_y),std::runtime_error,"");
@@ -698,17 +710,19 @@ int_t opencv_dot_targets(Mat & img,
698710
// chances are that this indicates p thresholding problem to begin with
699711
if (key_points.size() != 3) {
700712
// try again to see if the markers a too small, if so enable smaller blob sizes and try again
701-
min_blob_size = 10;
702-
get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
703-
if(key_points.size() !=3){
704-
// try a larger min blob size
705-
min_blob_size = 500;
706-
get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
707-
if(key_points.size() != 3){
708-
std::cout << "*** warning: unable to identify three keypoints, other points will not be extracted" << std::endl;
709-
keypoints_found = false;
710-
}
711-
}
713+
// min_blob_size = 10;
714+
// get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
715+
// if(key_points.size() !=3){
716+
std::cout << "*** warning: unable to identify three keypoints, other points will not be extracted" << std::endl;
717+
keypoints_found = false;
718+
// // try a larger min blob size
719+
// min_blob_size = 500;
720+
// get_dot_markers(img_cpy,key_points,i_thresh,invert,options,min_blob_size);
721+
// if(key_points.size() != 3){
722+
// std::cout << "*** warning: unable to identify three keypoints, other points will not be extracted" << std::endl;
723+
// keypoints_found = false;
724+
// }
725+
// }
712726
}
713727
Point cvpoint;
714728
if(preview_thresh){
@@ -856,6 +870,7 @@ void get_dot_markers(cv::Mat img,
856870

857871
// setup the blob detector
858872
SimpleBlobDetector::Params params;
873+
params.filterByArea = true;
859874
params.maxArea = 10e4;
860875
params.minArea = min_size;
861876
cv::Ptr<cv::SimpleBlobDetector> detector = cv::SimpleBlobDetector::create(params);
@@ -884,7 +899,32 @@ void get_dot_markers(cv::Mat img,
884899
// detect dots on the appropriately inverted image
885900
if (invert) detector->detect(not_src, keypoints);
886901
else detector->detect(bi_src, keypoints);
902+
DEBUG_MSG("get_dot_markers(): preliminary num keypoints " << keypoints.size());
903+
if(keypoints.size()==0) return;
904+
// the diameters of the keypoints should be within 30% of each other
905+
float avg_diameter = 0.0f;
906+
for(size_t i=0;i<keypoints.size();++i){
907+
avg_diameter += keypoints[i].size;
908+
}
909+
avg_diameter /= keypoints.size();
910+
DEBUG_MSG("get_dot_markers(): avg keypoint diameter " << avg_diameter);
911+
912+
size_t i = keypoints.size();
913+
while (i--) {
914+
// DEBUG_MSG("get_dot_markers(): possible keypoint " << i << " diameter " << keypoints[i].size);
915+
// remove the keypoint from the vector
916+
if(keypoints[i].size<=0.0){
917+
// DEBUG_MSG("get_dot_markers(): removing keypoint " << i << " due to keypoint size == 0.0");
918+
keypoints.erase(keypoints.begin() + i);
919+
}
920+
if(std::abs(keypoints[i].size-avg_diameter)/avg_diameter>0.30){
921+
// DEBUG_MSG("get_dot_markers(): removing keypoint " << i << " due to keypoint size >30% difference in diameter from avg");
922+
keypoints.erase(keypoints.begin() + i);
923+
}
924+
}
887925
DEBUG_MSG("get_dot_markers(): num keypoints " << keypoints.size());
926+
// for (size_t i = 0;i<keypoints.size();++i)
927+
// DEBUG_MSG("get_dot_markers(): keypoint " << i << " diameter " << keypoints[i].size);
888928
}
889929

890930
//calculate the transformation coefficients

src/opencv/DICe_OpenCVServerUtils.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ const char* const opencv_server_threshold_start = "threshold_start";
7878
const char* const opencv_server_threshold_end = "threshold_end";
7979
const char* const opencv_server_threshold_step = "threshold_step";
8080
const char* const opencv_server_block_size = "block_size";
81+
const char* const opencv_server_min_blob_size = "min_blob_size";
8182
const char* const opencv_server_binary_constant = "binary_constant";
8283
const char* const opencv_server_dot_tol = "dot_tol";
8384
const char* const opencv_server_use_adaptive_threshold = "use_adaptive_threshold";

0 commit comments

Comments
 (0)