首页 > 解决方案 > OpenCV FAST 算法仅在图像的一部分上创建倾斜的关键点

问题描述

我正在尝试使用 OpenCV 的FAST角点检测算法来获取球图像的轮廓(不是我的最终项目,我将其用作一个简单的示例)。出于某种原因,它仅适用于输入 Mat 的三分之一,并在图像上拉伸关键点。我不确定这里可能出了什么问题以使 FAST 算法不适用于整个 Mat。

代码:

void featureDetection(const Mat& imgIn, std::vector<KeyPoint>& pointsOut)   { 
    int fast_threshold = 20;
    bool nonmaxSuppression = true;
    FAST(imgIn, pointsOut, fast_threshold, nonmaxSuppression);
}

int main(int argc, char** argv) {

    Mat out = imread("ball.jpg", IMREAD_COLOR);

    // Detect features 
    std::vector<KeyPoint> keypoints;
    featureDetection(out.clone(), keypoints);
    Mat out2 = out.clone();

    // Draw features (Normal, missing right side)
    for(KeyPoint p : keypoints) {
        drawMarker(out, Point(p.pt.x / 3, p.pt.y), Scalar(0, 255, 0));
    }

    imwrite("out.jpg", out, std::vector<int>(0));
    
    // Draw features (Stretched)
    for(KeyPoint p : keypoints) {
        drawMarker(out2, Point(p.pt.x, p.pt.y), Scalar(127, 0, 255));
    }

    imwrite("out2.jpg", out2, std::vector<int>(0));
}

输入图像

球.jpg

输出 1(keypoint.x 乘以 1/3,但缺少右侧

出.jpg

输出 2(坐标不变

out2.jpg

我在 MinGW 上使用 OpenCV 4.5.4。

标签: c++opencv

解决方案


大多数关键点检测器使用灰度图像作为输入。如果您将 bgr 图像的内存解释为灰度,您将拥有 3 倍的像素数。如果算法使用每行的宽度偏移量,Y 轴仍然可以,大多数算法都会这样做(因为这在使用子图像或填充时很有用)。

我不知道这是错误还是功能,FAST 不检查通道数,如果给出错误的通道数,则不会抛出异常。

您可以通过带有标志 cv::COLOR_BGR2GRAY 的 cv::cvtColor 将图像转换为灰度


推荐阅读