Fix charuco algo when an image spanns the break between ends of the board
up board size a bit
This commit is contained in:
		
							parent
							
								
									8b643b03d3
								
							
						
					
					
						commit
						2e3d0d2938
					
				
					 2 changed files with 65 additions and 6 deletions
				
			
		| 
						 | 
					@ -20,9 +20,10 @@
 | 
				
			||||||
#include "uvosunwrap/charuco.h"
 | 
					#include "uvosunwrap/charuco.h"
 | 
				
			||||||
#include <opencv2/aruco/charuco.hpp>
 | 
					#include <opencv2/aruco/charuco.hpp>
 | 
				
			||||||
#include <opencv2/highgui.hpp>
 | 
					#include <opencv2/highgui.hpp>
 | 
				
			||||||
 | 
					#include "uvosunwrap/log.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static constexpr unsigned int X_BOARD_SIZE = 18;
 | 
					static constexpr unsigned int X_BOARD_SIZE = 20;
 | 
				
			||||||
static constexpr unsigned int Y_BOARD_SIZE = 10;
 | 
					static constexpr unsigned int Y_BOARD_SIZE = 12;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void createCharucoBoard(unsigned int size, const std::string& fileName)
 | 
					void createCharucoBoard(unsigned int size, const std::string& fileName)
 | 
				
			||||||
| 
						 | 
					@ -30,9 +31,65 @@ void createCharucoBoard(unsigned int size, const std::string& fileName)
 | 
				
			||||||
    cv::Ptr<cv::aruco::CharucoBoard> board = 
 | 
					    cv::Ptr<cv::aruco::CharucoBoard> board = 
 | 
				
			||||||
			cv::aruco::CharucoBoard::create(X_BOARD_SIZE, Y_BOARD_SIZE, 0.03f, 0.02f, 
 | 
								cv::aruco::CharucoBoard::create(X_BOARD_SIZE, Y_BOARD_SIZE, 0.03f, 0.02f, 
 | 
				
			||||||
											cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250 ));
 | 
																cv::aruco::getPredefinedDictionary(cv::aruco::DICT_4X4_250 ));
 | 
				
			||||||
    cv::Mat charucoImage;
 | 
						cv::Mat charucoImage;
 | 
				
			||||||
    board->draw(cv::Size((size*18)/10, size), charucoImage, 0, 1);
 | 
						double cellSize = size/(double)Y_BOARD_SIZE;
 | 
				
			||||||
    cv::imwrite(fileName, charucoImage);
 | 
						board->draw(cv::Size((size*X_BOARD_SIZE)/Y_BOARD_SIZE, size), charucoImage, 0, 1);
 | 
				
			||||||
 | 
						cv::Mat charucoImageWithBorder = 
 | 
				
			||||||
 | 
							cv::Mat::zeros(cv::Size(cellSize*(X_BOARD_SIZE+2), cellSize*(Y_BOARD_SIZE+2)), CV_8UC1);
 | 
				
			||||||
 | 
						cv::Rect roi(cellSize, cellSize, charucoImage.cols, charucoImage.rows);
 | 
				
			||||||
 | 
						charucoImage.copyTo(charucoImageWithBorder(roi));
 | 
				
			||||||
 | 
						cv::imwrite(fileName, charucoImageWithBorder);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void seamAjust(std::vector<DetectedPoint>& detections)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						int xMin = std::numeric_limits<int>::max();
 | 
				
			||||||
 | 
						int xMax = std::numeric_limits<int>::min();
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for(auto& point : detections)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if(point.coordinate.x > xMax) 
 | 
				
			||||||
 | 
								xMax = point.coordinate.x;
 | 
				
			||||||
 | 
							else if(point.coordinate.x < xMin)
 | 
				
			||||||
 | 
								xMin = point.coordinate.x;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						if(xMax - xMin < static_cast<int>(X_BOARD_SIZE/2))
 | 
				
			||||||
 | 
							return;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						Log(Log::DEBUG)<<"Image contains seam";
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						bool extantCol[X_BOARD_SIZE] = {0};
 | 
				
			||||||
 | 
						for(auto& point : detections)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if(!extantCol[point.coordinate.x])
 | 
				
			||||||
 | 
								extantCol[point.coordinate.x] = true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						int leftCoordinate = 0;
 | 
				
			||||||
 | 
						int maxDeadrange = 0;
 | 
				
			||||||
 | 
						int deadRange = 0;
 | 
				
			||||||
 | 
						for(unsigned int i = 0; i < X_BOARD_SIZE-1; ++i)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if(!extantCol[i])
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								++deadRange;
 | 
				
			||||||
 | 
								if(extantCol[i+1] && maxDeadrange < deadRange)
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
 | 
									leftCoordinate = i+1;
 | 
				
			||||||
 | 
									maxDeadrange = deadRange;
 | 
				
			||||||
 | 
									deadRange = 0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						Log(Log::DEBUG)<<"Left coordinate before seam "<<leftCoordinate;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
 | 
						for(auto& point : detections)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
							if(point.coordinate.x < leftCoordinate)
 | 
				
			||||||
 | 
								point.coordinate.x = point.coordinate.x + X_BOARD_SIZE;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose)
 | 
					std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose)
 | 
				
			||||||
| 
						 | 
					@ -86,6 +143,8 @@ std::vector<DetectedPoint> detectCharucoPoints(cv::Mat image, bool verbose)
 | 
				
			||||||
			detections.push_back(DetectedPoint(charucoCorners[i], coordiante));
 | 
								detections.push_back(DetectedPoint(charucoCorners[i], coordiante));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		
 | 
							
 | 
				
			||||||
 | 
							seamAjust(detections);
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		return detections;
 | 
							return detections;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return std::vector<DetectedPoint>();
 | 
						return std::vector<DetectedPoint>();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -143,7 +143,7 @@ int perfromOperation(int operation, char** fileNames, const Config& config)
 | 
				
			||||||
	if(operation == CREATE_CHARUCO)
 | 
						if(operation == CREATE_CHARUCO)
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		std::string fileName = config.output.empty() ? "out.png" : config.output;
 | 
							std::string fileName = config.output.empty() ? "out.png" : config.output;
 | 
				
			||||||
		createCharucoBoard(config.size*14, fileName);
 | 
							createCharucoBoard(config.size*42, fileName);
 | 
				
			||||||
		Log(Log::INFO)<<"Exported charuco map of size "<<config.size*14<<" to "<<fileName;
 | 
							Log(Log::INFO)<<"Exported charuco map of size "<<config.size*14<<" to "<<fileName;
 | 
				
			||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue