mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
fix generate of charuco chessboard image, add test
This commit is contained in:
@@ -483,39 +483,44 @@ void CharucoBoardImpl::generateImage(Size outSize, OutputArray img, int marginSi
|
||||
Mat noMarginsImg =
|
||||
out.colRange(marginSize, out.cols - marginSize).rowRange(marginSize, out.rows - marginSize);
|
||||
|
||||
double totalLengthX, totalLengthY;
|
||||
totalLengthX = squareLength * size.width;
|
||||
totalLengthY = squareLength * size.height;
|
||||
|
||||
// proportional transformation
|
||||
double xReduction = totalLengthX / double(noMarginsImg.cols);
|
||||
double yReduction = totalLengthY / double(noMarginsImg.rows);
|
||||
// the size of the chessboard square depends on the location of the chessboard
|
||||
float pixInSquare = 0.f;
|
||||
// the size of the chessboard in pixels
|
||||
Size pixInChessboard(noMarginsImg.cols, noMarginsImg.rows);
|
||||
|
||||
// determine the zone where the chessboard is placed
|
||||
Mat chessboardZoneImg;
|
||||
if(xReduction > yReduction) {
|
||||
int nRows = int(totalLengthY / xReduction);
|
||||
int rowsMargins = (noMarginsImg.rows - nRows) / 2;
|
||||
chessboardZoneImg = noMarginsImg.rowRange(rowsMargins, noMarginsImg.rows - rowsMargins);
|
||||
} else {
|
||||
int nCols = int(totalLengthX / yReduction);
|
||||
int colsMargins = (noMarginsImg.cols - nCols) / 2;
|
||||
chessboardZoneImg = noMarginsImg.colRange(colsMargins, noMarginsImg.cols - colsMargins);
|
||||
float pixInSquareX = (float)noMarginsImg.cols / (float)size.width;
|
||||
float pixInSquareY = (float)noMarginsImg.rows / (float)size.height;
|
||||
Point startChessboard(0, 0);
|
||||
if (pixInSquareX <= pixInSquareY) {
|
||||
// the width of "noMarginsImg" image determines the dimensions of the chessboard
|
||||
pixInSquare = pixInSquareX;
|
||||
pixInChessboard.height = cvRound(pixInSquare*size.height);
|
||||
int rowsMargin = (noMarginsImg.rows - pixInChessboard.height) / 2;
|
||||
startChessboard.y = rowsMargin;
|
||||
}
|
||||
else {
|
||||
// the height of "noMarginsImg" image determines the dimensions of the chessboard
|
||||
pixInSquare = pixInSquareY;
|
||||
pixInChessboard.width = cvRound(pixInSquare*size.width);
|
||||
int colsMargin = (noMarginsImg.cols - pixInChessboard.width) / 2;
|
||||
startChessboard.x = colsMargin;
|
||||
}
|
||||
// determine the zone where the chessboard is located
|
||||
Mat chessboardZoneImg = noMarginsImg(Rect(startChessboard, pixInChessboard));
|
||||
|
||||
// determine the margins to draw only the markers
|
||||
// take the minimum just to be sure
|
||||
double squareSizePixels = min(double(chessboardZoneImg.cols) / double(size.width),
|
||||
double(chessboardZoneImg.rows) / double(size.height));
|
||||
// marker size in pixels
|
||||
const float pixInMarker = markerLength/squareLength*pixInSquare;
|
||||
// the size of the marker margin in pixels
|
||||
const float pixInMarginMarker = 0.5f*(pixInSquare - pixInMarker);
|
||||
|
||||
double diffSquareMarkerLength = (squareLength - markerLength) / 2;
|
||||
int diffSquareMarkerLengthPixels =
|
||||
int(diffSquareMarkerLength * squareSizePixels / squareLength);
|
||||
// determine the zone where the aruco markers are located
|
||||
int endArucoX = cvRound(pixInSquare*(size.width-1)+pixInMarginMarker+pixInMarker);
|
||||
int endArucoY = cvRound(pixInSquare*(size.height-1)+pixInMarginMarker+pixInMarker);
|
||||
Mat arucoZone = chessboardZoneImg(Range(cvRound(pixInMarginMarker), endArucoY), Range(cvRound(pixInMarginMarker), endArucoX));
|
||||
|
||||
// draw markers
|
||||
Mat markersImg;
|
||||
Board::Impl::generateImage(chessboardZoneImg.size(), markersImg, diffSquareMarkerLengthPixels, borderBits);
|
||||
markersImg.copyTo(chessboardZoneImg);
|
||||
Board::Impl::generateImage(arucoZone.size(), arucoZone, 0, borderBits);
|
||||
|
||||
// now draw black squares
|
||||
for(int y = 0; y < size.height; y++) {
|
||||
@@ -527,12 +532,11 @@ void CharucoBoardImpl::generateImage(Size outSize, OutputArray img, int marginSi
|
||||
if(y % 2 != x % 2) continue; // white corner, dont do anything
|
||||
}
|
||||
|
||||
double startX, startY;
|
||||
startX = squareSizePixels * double(x);
|
||||
startY = squareSizePixels * double(y);
|
||||
float startX = pixInSquare * float(x);
|
||||
float startY = pixInSquare * float(y);
|
||||
|
||||
Mat squareZone = chessboardZoneImg.rowRange(int(startY), int(startY + squareSizePixels))
|
||||
.colRange(int(startX), int(startX + squareSizePixels));
|
||||
Mat squareZone = chessboardZoneImg(Range(cvRound(startY), cvRound(startY + pixInSquare)),
|
||||
Range(cvRound(startX), cvRound(startX + pixInSquare)));
|
||||
|
||||
squareZone.setTo(0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user