10

我正在使用 OpenCV 2.2。

如果我cvFindChessboardCorners用来查找棋盘的角,那么角以什么顺序存储在变量中corners(例如,首先是左上角,然后是行,然后是列)?

文档(帮助不大)。

4

2 回答 2

2

在我看来,文档缺乏这种细节。

对于 3.2.0-dev,在我看来,这取决于棋盘的旋转角度。有了这个片段:

cv::Size patternsize(4,3); //number of centers
cv::Mat cal = cv::imread(cal_name);
std::vector<cv::Point2f> centers; //this will be filled by the detected centers

bool found = cv::findChessboardCorners( cal, patternsize, centers, cv::CALIB_CB_ADAPTIVE_THRESH );

std::cout << found << "\n";
if(found){      
    cv::drawChessboardCorners(cal,patternsize,centers,found);

你会得到这些结果:

第一张图片: 在此处输入图像描述

旋转 180 度的第一张图片: 在此处输入图像描述

注意

用线条连接的彩色角落

由 绘制drawChessboardCorners,它们仅在颜色上有所不同:在原始图像中,红线在底部,在旋转图像中,红线在图像顶部。如果您传递给drawChessboardCorners灰度图像,您将丢失这条信息。

如果我需要图像左上角的第一个角并且我可以假设:

  1. 场景中棋盘的角度只会接近0或接近180;
  2. 相机的倾斜可以忽略不计;

然后如果需要,以下代码段将重新排列角落:

cv::Size patternsize(4,3); //number of centers
cv::Mat cal = cv::imread(cal_name);
std::vector<cv::Point2f> centers; //this will be filled by the detected centers

bool found = cv::findChessboardCorners( cal, patternsize, centers, cv::CALIB_CB_ADAPTIVE_THRESH );

std::cout << found << "\n";
if(found){      
    cv::drawChessboardCorners(cal,patternsize,centers,found);
    // I need the first corner at top-left
    if(centers.front().y > centers.back().y){
        std::cout << "Reverse order\n";
        std::reverse(centers.begin(),centers.end());
    }
    for(size_t r=0;r<patternsize.height;r++){
        for(size_t c=0;c<patternsize.width;c++){
            std::ostringstream oss;
            oss << "("<<r<<","<<c<<")";
            cv::putText(cal, oss.str(), centers[r*patternsize.width+c], cv::FONT_HERSHEY_PLAIN, 3, CV_RGB(0, 255, 0), 3);
        }
    }
}

在此处输入图像描述 在此处输入图像描述

于 2020-09-13T12:47:36.783 回答
0

我很确定它按行排列棋盘角,从最靠近图像左上角的那个开始。

棋盘图案没有指定的原点(该校准设备的缺陷之一),因此如果将其旋转 90 度或 180 度,则返回的角将不会以相同的顺序排列。

确保的方法是查看您返回的实际点值,看看它们是否符合您的预期。

编辑:至少在 OpenCV 3.3.1 和 5x3 棋盘的情况下,棋盘角可以从左上角或右下角开始返回,具体取决于旋转。

于 2013-10-04T21:59:36.097 回答