<h1 style="font-size: 32px; border-bottom: 2px solid rgb(204, 204, 204); padding: 0px 4px 0px 0px; margin: 0px 0px 10px;">寻找已知物体(一)</h1><p><span style=" color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif;">当前系列所有demo下载地址:</span></p><p style="margin-top: 0px; margin-bottom: 10px; text-wrap: wrap; padding: 0px; list-style: none; border: 0px; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; color: rgb(51, 51, 51); box-sizing: border-box;"><a href="https://github.com/GaoRenBao/OpenCv4-Demo" target="_blank" style="margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(0, 102, 0); transition-duration: 0.2s; transition-property: opacity; outline: none; opacity: 0.8;">https://github.com/GaoRenBao/OpenCv4-Demo</a></p><p style="margin-top: 0px; margin-bottom: 10px; text-wrap: wrap; box-sizing: border-box; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; color: rgb(51, 51, 51); "><a target="_blank" href="https://pan.baidu.com/s/1T9xl4KOBvU1g7AyDfPWlpw" style="box-sizing: border-box; color: rgb(0, 102, 0); transition-duration: 0.2s; transition-property: opacity; background-color: transparent; outline: none;"></a></p><p style="text-wrap: wrap;"><br/></p><p style="text-wrap: wrap;">还有一种比较简单的,利用sift寻找已知物体的算法。</p><p style="margin-top: 0px; margin-bottom: 10px; text-wrap: wrap; box-sizing: border-box; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; color: rgb(51, 51, 51); ">源码参考原文:</p><p style="margin-top: 0px; margin-bottom: 10px; text-wrap: wrap; box-sizing: border-box; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; color: rgb(51, 51, 51); "><a href="/api/system/download?file=OpenCV-Python-Tutorial-%E4%B8%AD%E6%96%87%E7%89%88.pdf" target="_blank" title="OpenCV-Python-Tutorial-中文版.pdf (P213)">OpenCV-Python-Tutorial-中文版.pdf (P213)</a><span style="color: rgba(0, 0, 0, 0.85);"> </span></p><p style="margin-top: 0px; margin-bottom: 10px; text-wrap: wrap; padding: 0px; list-style: none; border: 0px; overflow-wrap: break-word; word-break: break-all; line-height: 1.5em; font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; box-sizing: border-box; color: rgb(51, 51, 51);">不同编程语言对应的OpenCv版本以及<span style="">开发环境</span>信息如下:<span style="font-family: Calibri; font-size: 14px;"> </span></p><table border="1" style="border-right: none; border-bottom: none; border-image: initial; border-left: 1px solid rgb(102, 102, 102); border-top: 1px solid rgb(102, 102, 102);"><tbody><tr class="firstRow"><td width="81" valign="top" style="border-color: windowtext rgb(102, 102, 102) rgb(102, 102, 102) windowtext; border-bottom-width: 1px; border-bottom-style: solid; border-right-width: 1px; border-right-style: solid; padding: 5px;"><p style="text-align: center;"><strong><span style="font-family: 宋体; font-size: 14px;">语言</span></strong></p></td><td width="223" valign="top" style="border-color: windowtext rgb(102, 102, 102) rgb(102, 102, 102) windowtext; border-bottom-width: 1px; border-bottom-style: solid; border-right-width: 1px; border-right-style: solid; padding: 5px;"><p style="text-align: center;"><strong><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">OpenCv</span>版本</span></strong></p></td><td width="242" valign="top" style="border-color: windowtext rgb(102, 102, 102) rgb(102, 102, 102) windowtext; border-bottom-width: 1px; border-bottom-style: solid; border-right-width: 1px; border-right-style: solid; padding: 5px;"><p style="text-align: center;"><strong><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">IDE</span></span></strong></p></td></tr><tr><td width="81" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">C#</span></span></p></td><td width="223" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: Calibri; letter-spacing: 0px;">OpenCvSharp4.4.8.0.20230708</span></p></td><td width="242" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">Visual Studio 2022</span></span></p></td></tr><tr><td width="81" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">C++</span></span></p></td><td width="223" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; letter-spacing: 0px;"><span style="font-family: Calibri;">O</span></span><span style="font-family: Calibri; letter-spacing: 0px;">pen</span><span style="font-family: 宋体; letter-spacing: 0px;"><span style="font-family: Calibri;">C</span></span><span style="font-family: Calibri; letter-spacing: 0px;">v-4.5.5-vc14_vc15</span></p></td><td width="242" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">Visual Studio 2022</span></span></p></td></tr><tr><td width="81" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">Python</span></span></p></td><td width="223" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">OpenCv-Python (4.6.0.66)</span></span></p></td><td width="242" valign="top" style="border-top: none; border-left-color: windowtext; border-bottom: 1px solid rgb(102, 102, 102); border-right: 1px solid rgb(102, 102, 102); padding: 5px;"><p><span style="font-family: 宋体; font-size: 14px;"><span style="font-family: Calibri;">PyCharm Community Edition 2022.1.3</span></span></p></td></tr></tbody></table><p><br/></p><p style="text-wrap: wrap;">首先呢,我们需要准备两张测试图片, 这里不推荐使用毛星云的那两张测试图片哈,毛星云的测试图片效果不是很好,所以需要对图片做些裁剪,准备的图片如下,一张是需要查找的图片,另一张是目标图片。</p><p style="text-wrap: wrap;"><img src="/upload/image/6379304803323227495798950.jpg" title="11.jpg" alt="11.jpg"/></p><p style="text-wrap: wrap;"><br/></p><p style="text-wrap: wrap;"><img src="/upload/image/6379304803897483639144214.jpg" title="2.jpg" alt="2.jpg"/></p><p><br/></p><p>Python运行效果如下,这个效果和毛星云的貌似相差不大(python运行效果会好点,其他语言的会差点)</p><p><img src="/upload/image/6383454159049110776283897.jpg" title="out.jpg" alt="out.jpg"/></p><p><br/></p><p><strong style="text-wrap: wrap; margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><span style="font-style: italic; color: rgb(51, 153, 204); line-height: 18px;">C#版本代码如下:</span></strong></p><pre class="brush:c#;toolbar:false">using OpenCvSharp;
using System.Collections.Generic;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
// queryImage
Mat img1 = Cv2.ImRead("../../../images/book_box.jpg");
// trainImage
Mat img2 = Cv2.ImRead("../../../images/book2.jpg");
var Sift = OpenCvSharp.Features2D.SIFT.Create();
KeyPoint[] kp1, kp2;
Mat des1 = new Mat();
Mat des2 = new Mat();
Sift.DetectAndCompute(img1, null, out kp1, des1);
Sift.DetectAndCompute(img2, null, out kp2, des2);
//BFMatcher with default params
BFMatcher bf = new BFMatcher();
DMatch[][] matches = bf.KnnMatch(des1, des2, 2);
List<DMatch[]> good = new List<DMatch[]>();
//Apply ratio test
//比值测试,首先获取与 A距离最近的点 B (最近)和 C (次近),
//只有当 B/C 小于阀值时(0.75)才被认为是匹配,
//因为假设匹配是一一对应的,真正的匹配的理想距离为0
for (int i = 0; i < matches.Length; i++)
{
if (matches[i][0].Distance < 0.75 * matches[i][1].Distance)
good.Add(matches[i]);
}
//cv2.drawMatchesKnn expects list of lists as matches.
Mat img3 = new Mat();
Cv2.DrawMatchesKnn(img1, kp1, img2, kp2, good.ToArray(), img3, flags: DrawMatchesFlags.NotDrawSinglePoints);
Cv2.ImShow("out", img3);
Cv2.WaitKey(0);
}
}
}</pre><p><strong style="text-wrap: wrap; margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "></strong><br/></p><p><strong style="text-wrap: wrap; margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;"><span style="font-style: italic; color: rgb(51, 153, 204); line-height: 18px;">C++版本代码如下:</span></strong></strong></p><p>参考博客:<a href="https://blog.csdn.net/fengweichangzi/article/details/119872074" target="_blank">https://blog.csdn.net/fengweichangzi/article/details/119872074</a></p><pre class="brush:cpp;toolbar:false">#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// queryImage
Mat img1 = cv::imread("../images/book_box.jpg");
// trainImage
Mat img2 = cv::imread("../images/book2.jpg");
Ptr<SIFT> sift = SIFT::create();
vector<KeyPoint> kp1, kp2;
Mat des1, des2;
sift->detectAndCompute(img1, Mat(), kp1, des1);
sift->detectAndCompute(img2, Mat(), kp2, des2);
//BFMatcher with default params
BFMatcher bf;
vector<vector<DMatch>> matches;
bf.knnMatch(des1, des2, matches, 2);
vector<vector<DMatch>> good;
for (int i = 0; i < matches.size(); i++)
{
if (matches[i][0].distance < 0.75 * matches[i][1].distance)
good.push_back(matches[i]);
}
//cv2.drawMatchesKnn expects list of lists as matches.
Mat img3;
drawMatches(img1 = img1, kp1, img2, kp2, good, img3,
Scalar::all(-1), Scalar::all(-1), std::vector<std::vector<char> >(),
DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
cv::imshow("img", img3);
cv::waitKey(0);
}</pre><p><strong style="text-wrap: wrap; margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;"></strong></strong><br/></p><p><strong style="text-wrap: wrap; margin: 0px; padding: 0px; list-style: none; border: 0px; color: rgb(51, 51, 51); font-family: "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "Noto Sans CJK SC", "WenQuanYi Micro Hei", Arial, sans-serif; "><strong style="margin: 0px; padding: 0px; list-style: none; border: 0px;"><span style="font-style: italic; color: rgb(51, 153, 204); line-height: 18px;">Python版本代码如下:</span></strong></strong></p><pre class="brush:python;toolbar:false">import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('../images/book_box.jpg')
# queryImage
img2 = cv2.imread('../images/book2.jpg')
# Initiate SIFT detector
# sift = cv2.SIFT()
sift = cv2.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
# Apply ratio test
# 比值测试,首先获取与 A距离最近的点 B (最近)和 C (次近),
# 只有当 B/C 小于阀值时(0.75)才被认为是匹配,
# 因为假设匹配是一一对应的,真正的匹配的理想距离为0
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append([m])
# cv2.drawMatchesKnn expects list of lists as matches.
# img3 = np.ndarray([2, 2])
# img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good[:10], img3, flags=2)
# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)
cv2.imshow("out", img3)
# cv2.imwrite("out.jpg", img3)
cv2.waitKey(0)</pre><p><br/></p><p><br/></p>
寻找已知物体(一) 当前系列所有demo下载地址:
https://github.com/GaoRenBao/OpenCv4-Demo
还有一种比较简单的,利用sift寻找已知物体的算法。
源码参考原文:
OpenCV-Python-Tutorial-中文版.pdf (P213)
不同编程语言对应的OpenCv版本以及开发环境 信息如下:
语言
OpenCv 版本
IDE
C#
OpenCvSharp4.4.8.0.20230708
Visual Studio 2022
C++
O pen C v-4.5.5-vc14_vc15
Visual Studio 2022
Python
OpenCv-Python (4.6.0.66)
PyCharm Community Edition 2022.1.3
首先呢,我们需要准备两张测试图片, 这里不推荐使用毛星云的那两张测试图片哈,毛星云的测试图片效果不是很好,所以需要对图片做些裁剪,准备的图片如下,一张是需要查找的图片,另一张是目标图片。
Python运行效果如下,这个效果和毛星云的貌似相差不大(python运行效果会好点,其他语言的会差点)
C#版本代码如下:
using OpenCvSharp;
using System.Collections.Generic;
namespace demo
{
internal class Program
{
static void Main(string[] args)
{
// queryImage
Mat img1 = Cv2.ImRead("../../../images/book_box.jpg");
// trainImage
Mat img2 = Cv2.ImRead("../../../images/book2.jpg");
var Sift = OpenCvSharp.Features2D.SIFT.Create();
KeyPoint[] kp1, kp2;
Mat des1 = new Mat();
Mat des2 = new Mat();
Sift.DetectAndCompute(img1, null, out kp1, des1);
Sift.DetectAndCompute(img2, null, out kp2, des2);
//BFMatcher with default params
BFMatcher bf = new BFMatcher();
DMatch[][] matches = bf.KnnMatch(des1, des2, 2);
List<DMatch[]> good = new List<DMatch[]>();
//Apply ratio test
//比值测试,首先获取与 A距离最近的点 B (最近)和 C (次近),
//只有当 B/C 小于阀值时(0.75)才被认为是匹配,
//因为假设匹配是一一对应的,真正的匹配的理想距离为0
for (int i = 0; i < matches.Length; i++)
{
if (matches[i][0].Distance < 0.75 * matches[i][1].Distance)
good.Add(matches[i]);
}
//cv2.drawMatchesKnn expects list of lists as matches.
Mat img3 = new Mat();
Cv2.DrawMatchesKnn(img1, kp1, img2, kp2, good.ToArray(), img3, flags: DrawMatchesFlags.NotDrawSinglePoints);
Cv2.ImShow("out", img3);
Cv2.WaitKey(0);
}
}
}
C++版本代码如下:
参考博客:https://blog.csdn.net/fengweichangzi/article/details/119872074
#include <opencv2/opencv.hpp>
#include <opencv2/features2d.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
// queryImage
Mat img1 = cv::imread("../images/book_box.jpg");
// trainImage
Mat img2 = cv::imread("../images/book2.jpg");
Ptr<SIFT> sift = SIFT::create();
vector<KeyPoint> kp1, kp2;
Mat des1, des2;
sift->detectAndCompute(img1, Mat(), kp1, des1);
sift->detectAndCompute(img2, Mat(), kp2, des2);
//BFMatcher with default params
BFMatcher bf;
vector<vector<DMatch>> matches;
bf.knnMatch(des1, des2, matches, 2);
vector<vector<DMatch>> good;
for (int i = 0; i < matches.size(); i++)
{
if (matches[i][0].distance < 0.75 * matches[i][1].distance)
good.push_back(matches[i]);
}
//cv2.drawMatchesKnn expects list of lists as matches.
Mat img3;
drawMatches(img1 = img1, kp1, img2, kp2, good, img3,
Scalar::all(-1), Scalar::all(-1), std::vector<std::vector<char> >(),
DrawMatchesFlags::NOT_DRAW_SINGLE_POINTS);
cv::imshow("img", img3);
cv::waitKey(0);
}
Python版本代码如下:
import cv2
from matplotlib import pyplot as plt
img1 = cv2.imread('../images/book_box.jpg')
# queryImage
img2 = cv2.imread('../images/book2.jpg')
# Initiate SIFT detector
# sift = cv2.SIFT()
sift = cv2.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1, None)
kp2, des2 = sift.detectAndCompute(img2, None)
# BFMatcher with default params
bf = cv2.BFMatcher()
matches = bf.knnMatch(des1, des2, k=2)
# Apply ratio test
# 比值测试,首先获取与 A距离最近的点 B (最近)和 C (次近),
# 只有当 B/C 小于阀值时(0.75)才被认为是匹配,
# 因为假设匹配是一一对应的,真正的匹配的理想距离为0
good = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good.append([m])
# cv2.drawMatchesKnn expects list of lists as matches.
# img3 = np.ndarray([2, 2])
# img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good[:10], img3, flags=2)
# cv2.drawMatchesKnn expects list of lists as matches.
img3 = cv2.drawMatchesKnn(img1, kp1, img2, kp2, good, None, flags=2)
cv2.imshow("out", img3)
# cv2.imwrite("out.jpg", img3)
cv2.waitKey(0)