我有一些带有图像的磁铁。只有一小组不同的图像(比方说20张图像),它们将在固定的国际象棋中对齐(图中仍未显示)。
我已经有一个算法从电路板上提取每个单磁卡,对原始图像应用透视变换以防止透视失真。
我想听听你的意见,以便检测电路板上的每个图像,我的意思是,检测磁铁是否:熊猫,兔子,狗,胡萝卜...因为我的主要目标是分析图像并提取包含所有板元素的矩阵。
我的第一次尝试非常基本:根据平均颜色猜测图像。它不是很强大,因为有几个图像具有相似的平均颜色(特别是那些冷冻卡),浅色调可以改变颜色。
您是否会如此友好地指出我正确的方向来提取包含电路板上所有图像的矩阵?我不需要特定的实现,而是需要遵循的步骤的概念或者应用于主图像的技术,以获得稳健(并且不太复杂)的算法。
我将使用OpenCV实现它,但我想使用任何其他计算机视觉库都是一样的。
非常感谢你的时间!
答案 0 :(得分:1)
虽然SIFT或其他功能检测器运行良好且广泛适用,但我总是从最简单的方法开始:在您的情况下,这可能是template matching。毕竟,你已经完成了去除透视失真,旋转和不同比例的艰苦工作。
基本思想是拍摄20个模板图像中的每一个,并将其与搜索图像中的每个可能位置进行比较。由于卷积定理,这是一个相对便宜的操作。
答案 1 :(得分:0)
以下是一些示例代码:
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从两个图像中提取特征点。然后它找到两个图像的特征之间的匹配。但是,这仍然会包含很多垃圾比赛。但我们知道,我们要比较的两幅图像之间的转换是一个视角,因此必须能够计算它们之间的单应性。找到好的&#34;匹配它现在使用RANSAC异常值过滤方法计算单应性。哪些RANSAC认为异常值和哪些inlieres保存在矩阵mask
内(0表示异常值,1表示异常值)。你现在可以,例如计算此矩阵内的数量以获得良好匹配的数量。然后你可以为所有卡的图像执行此操作并比较匹配计数(例如选择匹配最多的一个)。
代码的最后一部分可视化找到的好匹配。
希望这有帮助。