微信公众号:OpenCV学堂
关注获取更多计算机视觉与深度学习知识
OpenCV SIFT特征算法详解与使用
01
创建SIFT特征提取器
// 创建SIFT特征提取
auto detector = SIFT::create();
vector keypoints_obj, keypoints_sence;
Mat descriptors_box, descriptors_sence;
detector->detectAndCompute(box, Mat(), keypoints_obj, descriptors_box);
detector->detectAndCompute(scene, Mat(), keypoints_sence, descriptors_sence);
std::cout << "box keypoints:" << keypoints_obj.size() << std::endl;
std::cout << "scene keypoints:" << keypoints_sence.size() << std::endl;
运行打印出来的关键点数目分别如下:
02
特征描述子匹配
// 初始化flann匹配
vector matches;
Ptr matcher = FlannBasedMatcher::create();
matcher->match(descriptors_box, descriptors_sence, matches);
// 发现高质量匹配
std::cout << "total matches:" << matches.size() <<std::endl;
int numOfGood = matches.size() * 0.15;
std::sort(matches.begin(), matches.end());
matches.erase(matches.begin() + numOfGood, matches.end());
std::cout << "good matches:" << matches.size() << std::endl;
Mat dst;
drawMatches(box, keypoints_obj, scene, keypoints_sence, matches, dst);
imshow("output", dst);
imwrite("D:/matches.png", dst);
运行结果如下:
03
单应性矩阵求解与透视变换
OpenCV单应性矩阵发现参数估算方法详解
单应性矩阵应用-基于特征的图像拼接
利用单应性矩阵实现文档对齐显示
这里不再赘述,这部分的代码实现如下:
// 抽取匹配描述子对应的关键点
std::vector obj_pts;
std::vector scene_pts;
for (size_t i = 0; i < matches.size(); i++)
{
obj_pts.push_back(keypoints_obj[matches[i].queryIdx].pt);
scene_pts.push_back(keypoints_sence[matches[i].trainIdx].pt);
}
// 对象对齐与单应性矩阵求解
Mat H = findHomography(obj_pts, scene_pts, RANSAC);
std::vector obj_corners(4);
obj_corners[0] = Point(0, 0); obj_corners[1] = Point(box.cols, 0);
obj_corners[2] = Point(box.cols, box.rows); obj_corners[3] = Point(0, box.rows);
std::vector scene_corners(4);
perspectiveTransform(obj_corners, scene_corners, H);
04
BOX矩形框绘制
求得最终的位置信息,根据得到四个点坐标通过多边形绘制函数,完成绘制,这个其中有必要重点解释一下多边形绘制函数
void cv::polylines (
InputOutputArray img,
InputArrayOfArrays pts,
bool isClosed,
const Scalar & color,
int thickness = 1,
int lineType = LINE_8,
int shift = 0
)
参数解释如下
img表示输入图像
pts表示绘制的多边形顶点集合,必须是int类型CV_32SC
isClosed表示是否闭合
color表示多边形颜色
thickness表示线宽,注意:必须大于等于零,如果想要填充它,请用drawContours
lineType表示对线的渲染方式
shift表示迁移,默认为0。这个在ROI上绘制时候有用
实现代码如下:
// 绘制发现的对象
std::vector pts;
for (int i = 0; i < scene_corners.size(); i++) {
pts.push_back(scene_corners[i]);
}
polylines(scene, pts, true, Scalar(0, 0, 255), 2, 8, 0);
// 显示匹配对象
imshow("Good Matches & Object detection", scene);
imwrite("D:/findobject.png", scene);
运行结果如下:
扫码查看OpenCV+OpenVIO+Pytorch系统化学习路线图
推荐阅读
CV全栈开发者说 - 从传统算法到深度学习怎么修炼
2022入坑深度学习,我选择Pytorch框架!
Pytorch轻松实现经典视觉任务
教程推荐 | Pytorch框架CV开发-从入门到实战
OpenCV4 C++学习 必备基础语法知识三
OpenCV4 C++学习 必备基础语法知识二
OpenCV4.5.4 人脸检测+五点landmark新功能测试
OpenCV4.5.4人脸识别详解与代码演示
OpenCV二值图象分析之Blob分析找圆
OpenCV4.5.x DNN + YOLOv5 C++推理
OpenCV4.5.4 直接支持YOLOv5 6.1版本模型推理
OpenVINO2021.4+YOLOX目标检测模型部署测试
比YOLOv5还厉害的YOLOX来了,官方支持OpenVINO推理