请告诉我关于这个计算机视觉任务

我有一些磁铁与图像。 只有一小部分不同的图像(可以说20个图像),并且它们将以固定的国际象棋野猪(仍未在图片中显示)对齐。

电脑视觉棋盘游戏yum yum美味

我已经有了一个算法来从板上提取每个磁卡,对原始图像应用透视变换来防止透视失真。

我希望听到您的建议,以检测板上的每个图像,我的意思是检测磁体是否是:熊猫,兔子,狗,胡萝卜......因为我的主要目的是分析图像并提取一个包含所有棋盘元素的矩阵。

我的第一次尝试是非常基本的:根据平均颜色猜测图像。 由于有几张图片具有相似的平均颜色(特别是那些冷冻卡片),而且浅色设计可以改变颜色,所以效果不是很好。

你会如此友善地指出我在正确的方向上提取包含电路板上所有图像的矩阵吗? 我不需要一个具体的实现,而是我应该遵循的步骤的概念,或者是为了获得强大(而不是过于复杂)的算法而应用于主图像的技术。

我将使用OpenCV实现它,但我想这与使用任何其他计算机视觉库是一样的。

非常感谢您的时间!


虽然SIFT或其他功能检测器工作良好并且广泛适用,但我始终会从最简单的事情开始:在您的情况下,这可能是模板匹配。 毕竟,您已经完成了消除透视失真,旋转和不同比例的艰苦工作。

基本思想是将你的20幅模板图像中的每幅图像进行比较,并将其与搜索图像中的每个可能位置进行比较。 由于卷积定理,这是一个相对便宜的操作。


以下是一些示例代码:

void KeypointMatcher::computeMatches(cv::Mat image1, cv::Mat image2) {
        cv::initModule_nonfree();
        //Vector of keypoints   
        std::vector<cv::KeyPoint> keypoints1;
        std::vector<cv::KeyPoint> keypoints2;
        //Detect features
        cv::SiftFeatureDetector detector;
        detector.detect(image1, keypoints1);
        detector.detect(image2, keypoints2);

        //Compute descriptors
        cv::Mat descriptors1, descriptors2;
        cv::SiftDescriptorExtractor extractor;
        extractor.compute(image1, keypoints1, descriptors1);
        extractor.compute(image2, keypoints2, descriptors2);

        //Find matches
        cv::BFMatcher matcher(4, true);
        std::vector<cv::DMatch> matches;
        matcher.match(descriptors1, descriptors2, matches);

        //Find good points for a homography
        std::vector<cv::Point2d> matchingPoints1, matchingPoints2;
        for (cv::DMatch& match : matches) {
            matchingPoints1.push_back(keypoints1[match.queryIdx].pt);
            matchingPoints2.push_back(keypoints2[match.trainIdx].pt);
        }
        cv::Mat mask;
        cv::findHomography(matchingPoints1, matchingPoints2, CV_RANSAC, 3, mask);

        //Just visualisation
        std::vector<char> vectorMask;
        mask.col(0).copyTo(vectorMask);
        cv::Mat result;
        cv::drawMatches(image1, keypoints1, image2, keypoints2, matches, result, cv::Scalar::all(-1), cv::Scalar::all(-1), vectorMask);
        //cv::drawMatches(image1, keypoints1, image2, keypoints2, matches, result);
        cv::imshow("Matches", result);
        cv::waitKey();
    }

它执行以下操作:使用SIFT从两个图像中提取特征点。 然后它找到两个图像的特征之间的匹配。 但是,这仍然会包含很多垃圾比赛。 但我们知道,我们正在比较的两幅图像之间的转换是一个透视图,因此它们之间必须能够计算出它们之间的单应性。 为了找到“好”匹配,现在使用RANSAC异常过滤方法计算单应性。 哪些是RANSAC考虑的异常值和哪些入局值保存在矩阵mask (异常值为0,内部值为1)。 你现在可以例如计算这个矩阵中的那些来获得好匹配的数量。 然后你可以对所有牌的图像进行比较并比较比赛数量(例如选择最匹配的比赛)。

代码的最后部分可视化找到的好匹配项。

希望这可以帮助。

链接地址: http://www.djcxy.com/p/39509.html

上一篇: Please advise me about this Computer Vision task

下一篇: counting objects & better way to filling holes