opencv寻找已知物体

37 篇文章 10 订阅
25 篇文章 6 订阅

 

源代码

#include <opencv/cv.hpp>
#include<opencv2/core.hpp>
#include<opencv2/highgui.hpp>
#include<opencv2/features2d.hpp>
#include<opencv2/cudafeatures2d.hpp>
#include<opencv2/calib3d.hpp>
 
#include<iostream>
#include<vector>
 
using namespace cv;
using namespace std;
using namespace xfeatures2d;
 
int main()
{   
    double t = (double)getTickCount();
Mat image_1 = imread("src.jpg",CV_LOAD_IMAGE_COLOR);
Mat image_2 = imread("dst.jpg",CV_LOAD_IMAGE_COLOR);
//首先对两幅图像进行特征点的检测
//先准备参数
vector<KeyPoint> keyPoints_1;
vector<KeyPoint> keyPoints_2;
    int minHessian = 400;
    Ptr<SIFT> detector = SIFT::create(minHessian);
detector->detect(image_1, keyPoints_1);
detector->detect(image_2, keyPoints_2);
 
//利用得到的特征点计算特征描述子
//目的:对得到的每个特征点进行特征描述,整合到Mat类型的矩阵中(计算结果是Mat类型的)
//该得到的结果矩阵的行数就是特征点的个数,因为是对每个点进行描述,所以每行都会有一个描述的字子向量,共同构成Mat矩阵
    Ptr<SIFT> extractor = SIFT::create();
Mat descriptor_1, descriptor_2;
extractor->compute(image_1, keyPoints_1, descriptor_1);
extractor->compute(image_2, keyPoints_2, descriptor_2);
 
//正式开始在两幅图像中进行匹配
//先得到一个匹配向量
    Ptr<DescriptorMatcher> FLMatcher = DescriptorMatcher::create("FlannBased");
vector<DMatch> matches;
//matches就是得到的匹配向量
FLMatcher->match(descriptor_1, descriptor_2, matches);
 
//用找最大最小值的方式找到 两幅图像中匹配的点的距离的最大值和最小值
//这里的 keyPoint1.size() 和 descriptor_1.rows是一样的值,因为descriptor_1的行数就是检测到的特征点的个数
double minDistance = matches[0].distance, maxDistance = matches[0].distance;
for (size_t i = 0; i < keyPoints_1.size(); i++)
{
double currDistance = matches[i].distance;
if (currDistance < minDistance)
minDistance = currDistance;
if (currDistance > maxDistance)
maxDistance = currDistance;
}
 
//定义一个新的变量,用来存储 通过距离检测后  通过阀值的点
vector<DMatch> goodMatches;
for (size_t i = 0; i < keyPoints_1.size(); i++)
{
if (matches[i].distance < 3 * minDistance)
goodMatches.push_back(matches[i]);
}
 
//用绘制函数对匹配向量进行绘制
Mat dstImage;
drawMatches(image_1, keyPoints_1, image_2, keyPoints_2, goodMatches, dstImage
, Scalar(0, 255, 255)
, Scalar(0, 255, 255), Mat(), 2);
 
imshow("特征提取后的图像", dstImage);
    t = ((double)getTickCount() - t)/getTickFrequency();
/*****************************************************正式开始寻找已知物体*************************************************/
//为了调用 得到H矩阵findHomography函数,所以需要得到 匹配点所对应的特征点   然后作为参数传递给计算H矩阵的函数
//所以首先是进行 匹配点和对应的特征点的转换步骤
//将得到的点放入新的容器中,所以需要定义新的容器
vector<Point2f> g_vSrcPoint2f1;
vector<Point2f> g_vSrcPoint2f2;
for (size_t i = 0; i < goodMatches.size(); i++)
{
g_vSrcPoint2f1.push_back(keyPoints_1[goodMatches[i].queryIdx].pt);
g_vSrcPoint2f2.push_back(keyPoints_2[goodMatches[i].trainIdx].pt);
}
 
//将得到的对应的特征点  计算H矩阵
Mat H = findHomography(g_vSrcPoint2f1, g_vSrcPoint2f2, CV_LMEDS);
    cout<<H<<endl;
用得到的H矩阵  来进行透视矩阵变换  用到的是perspectiveTransform函数
vector<Point2f> g_vCorners1(4);
vector<Point2f> g_vCorners2(4);
g_vCorners1[0] = Point2f(24, 12);
g_vCorners1[1] = Point2f(312, 20);
g_vCorners1[2] = Point2f(300, 417);
g_vCorners1[3] = Point2f(25, 413);
 
perspectiveTransform(g_vCorners1, g_vCorners2, H);
 
在得到的两幅图像的合成图中绘制检测到的物体的直线
line(dstImage, (Point)g_vCorners2[0] + Point(image_1.cols, 0), (Point)g_vCorners2[1] + Point(image_1.cols, 0)
, Scalar(0, 0, 255), 2);
line(dstImage, (Point)g_vCorners2[1] + Point(image_1.cols, 0), (Point)g_vCorners2[2] + Point(image_1.cols, 0)
, Scalar(0, 0, 255), 2);
line(dstImage, (Point)g_vCorners2[2] + Point(image_1.cols, 0), (Point)g_vCorners2[3] + Point(image_1.cols, 0)
, Scalar(0, 0, 255), 2);
line(dstImage, (Point)g_vCorners2[3] + Point(image_1.cols, 0), (Point)g_vCorners2[0] + Point(image_1.cols, 0)
, Scalar(0, 0, 255), 2);
 
imshow("检测物体后的图像", dstImage);
waitKey(0);
    Mat bak = image_1.clone();
    warpPerspective(image_1, bak, H, Size(image_1.cols, image_1.rows));
    imwrite("new.jpg", bak);
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

NineDays66

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值