1. 步骤
1.1 导入OpenCV库:
在您的C++代码中,首先需要导入OpenCV库。您可以使用以下语句导入核心模块:
#include <opencv2/core/core.hpp>
1.2 加载图像
使用OpenCV的 imread 函数加载要搜索的图像和目标图像。例如,假设您要搜索的图像是"search_image.jpg",目标图像是"target_image.jpg",您可以使用以下代码加载它们:
cpp
cv::Mat searchImage = cv::imread("search_image.jpg");
cv::Mat targetImage = cv::imread("target_image.jpg");
1.3 提取特征
使用OpenCV的特征提取方法(如SIFT、SURF或ORB)从目标图像中提取特征。例如,使用SIFT算法可以提取特征,您可以使用以下代码:
cv::Ptr<cv::SIFT> sift = cv::SIFT::create();
cv::Mat targetDescriptors;
std::vector<cv::KeyPoint> targetKeypoints;
sift->detectAndCompute(targetImage, cv::noArray(), targetKeypoints, targetDescriptors);
1.4 匹配特征
使用提取的特征在搜索图像中寻找匹配。您可以使用OpenCV的特征匹配方法(如FLANN或Brute-Force)进行匹配。以下是一个使用Brute-Force匹配器的示例:
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::BRUTEFORCE);
std::vector<cv::DMatch> matches;
matcher->match(searchDescriptors, targetDescriptors, matches);
1.5 显示结果
根据匹配结果,您可以选择在搜索图像上绘制匹配的关键点或边界框。以下是一个简单的示例,用于在搜索图像上绘制匹配的关键点:
cv::Mat outputImage;
cv::drawMatches(searchImage, searchKeypoints, targetImage, targetKeypoints, matches, outputImage);
cv::imshow("Matches", outputImage);
cv::waitKey(0);
2. 完整代码
#include <opencv2/core/core.hpp>
int search_pic_by_pic()
{
// 加载查询图像和目标图像
cv::Mat queryImage = cv::imread("E:\\code\\Yolov5_Tensorrt_Win10-master\\pictures\\search_pic_by_pic\\1.png");
cv::Mat targetImage = cv::imread("E:\\code\\Yolov5_Tensorrt_Win10-master\\pictures\\search_pic_by_pic\\2.png");
// 特征提取
cv::Ptr<cv::Feature2D> featureExtractor = cv::SIFT::create();
cv::Mat queryDescriptors, targetDescriptors;
std::vector<cv::KeyPoint> queryKeypoints, targetKeypoints;
featureExtractor->detectAndCompute(queryImage, cv::noArray(), queryKeypoints, queryDescriptors);
featureExtractor->detectAndCompute(targetImage, cv::noArray(), targetKeypoints, targetDescriptors);
// 特征匹配
cv::Ptr<cv::DescriptorMatcher> matcher = cv::DescriptorMatcher::create(cv::DescriptorMatcher::FLANNBASED);
std::vector<cv::DMatch> matches;
matcher->match(queryDescriptors, targetDescriptors, matches);
// 根据匹配结果进行排序
std::sort(matches.begin(), matches.end(), [](const cv::DMatch& a, const cv::DMatch& b) {
return a.distance < b.distance;
});
float threshold = 200.0;
int numMatches = 0;
int matches_size = matches.size();
vector< cv::DMatch>::iterator it = matches.begin();
for (it; it != matches.end();) {
if (it->distance < threshold) {
numMatches++;
it++;
}
else {
it = matches.erase(it);
}
}
float matchRate = static_cast<float>(numMatches) / matches_size * 100.0;
std::cout << "Match Rate: " << matchRate << "%" << std::endl;
// 显示匹配结果
cv::Mat matchedImage;
cv::drawMatches(queryImage, queryKeypoints, targetImage, targetKeypoints, matches, matchedImage);
cv::imshow("Matched Image", matchedImage);
cv::waitKey(0);
return 0;
}
int main()
{
search_pic_by_pic();
return 0;
}
3. 测试图片及效果
文章来源:https://www.toymoban.com/news/detail-743210.html
文章来源地址https://www.toymoban.com/news/detail-743210.html
到了这里,关于opencv实现以图搜图的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!