<h2>检测最相似的图像</h2>
<h3>代码</h3>
<p>您可以使用<a href="https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_template_matching/py_template_matching.html" rel="nofollow noreferrer">template matching</a>,其中要检测是否在其他图像中的图像是模板。我在{<cd1>}中保存了那个小图像,在{<cd2>}、{<cd3>}和{<cd4>}中保存了其他三个图像</p>
<p>我定义了一个函数,它利用<code>cv2.matchTemplate</code>来计算模板是否在图像中的置信度。在每个图像上使用该函数,可获得最高置信度的图像是包含模板的图像:</p>
<pre><code>import cv2
template = cv2.imread("template.png", 0)
files = ["img1.png", "img2.png", "img3.png"]
for name in files:
img = cv2.imread(name, 0)
print(f"Confidence for {name}:")
print(cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED).max())
</code></pre>
<h3>输出:</h3>
<pre><code>Confidence for img1.png:
0.8906427
Confidence for img2.png:
0.4427919
Confidence for img3.png:
0.5933967
</code></pre>
<h3>解释:</h3>
<ol>
<li>导入opencv模块,并通过将<code>cv2.imread</code>方法的第二个参数设置为<code>0</code>,以灰度形式读取模板图像:</li>
</ol>
<pre><code>import cv2
template = cv2.imread("template.png", 0)
</code></pre>
<ol start=“2”>
<li>定义要确定包含模板的图像的列表:</li>
</ol>
<pre><code>files = ["img1.png", "img2.png", "img3.png"]
</code></pre>
<ol start=“3”>
<li>循环浏览文件名,并将每个文件名作为灰度图像读入:</li>
</ol>
<pre><code>for name in files:
img = cv2.imread(name, 0)
</code></pre>
<ol start=“4”>
<li>最后,您可以使用<code>cv2.matchTemplate</code>来检测每个图像中的模板。有<a href="https://docs.opencv.org/master/df/dfb/group__imgproc__object.html#ga3a7850640f1fe1f58fe91a2d7583695d" rel="nofollow noreferrer">many detection methods</a>可以使用,但为此,我决定使用<code>cv2.TM_CCOEFF_NORMED</code>方法:</li>
</ol>
<pre><code> print(f"Confidence for {name}:")
print(cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED).max())
</code></pre>
<p>函数的输出范围介于<code>0</code>和<code>1</code>之间,如您所见,它成功地检测到第一个图像最有可能包含模板图像<em>(其置信度最高)</em></p>
<hr/>
<h2>可视化</h2>
<h3>代码</h3>
<p>如果仅检测包含模板的图像是不够的,并且需要可视化,可以尝试以下代码:</p>
<pre><code>import cv2
import numpy as np
def confidence(img, template):
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
conf = res.max()
return np.where(res == conf), conf
files = ["img1.png", "img2.png", "img3.png"]
template = cv2.imread("template.png")
h, w, _ = template.shape
for name in files:
img = cv2.imread(name)
([y], [x]), conf = confidence(img, template)
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
text = f'Confidence: {round(float(conf), 2)}'
cv2.putText(img, text, (x, y), 1, cv2.FONT_HERSHEY_PLAIN, (0, 0, 0), 2)
cv2.imshow(name, img)
cv2.imshow('Template', template)
cv2.waitKey(0)
</code></pre>
<h3>输出:</h3>
<p><a href="https://i.stack.imgur.com/GYazs.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/GYazs.png" alt="enter image description here"/></a></p>
<h3>解释:</h3>
<ol>
<li>导入必要的库:</li>
</ol>
<pre><code>import cv2
import numpy as np
</code></pre>
<ol start=“2”>
<li>定义将接收完整图像和模板图像的函数。由于<code>cv2.matchTemplate</code>方法需要灰度图像,请将这两幅图像转换为灰度:</li>
</ol>
<pre><code>def confidence(img, template):
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
template = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
</code></pre>
<ol start=“3”>
<li>使用<code>cv2.matchTemplate</code>方法检测图像中的模板,并返回具有最高置信度的点的位置,然后返回最高置信度:</li>
</ol>
<pre><code> res = cv2.matchTemplate(img, template, cv2.TM_CCOEFF_NORMED)
conf = res.max()
return np.where(res == conf), conf
</code></pre>
<ol start=“4”>
<li>定义要确定哪个图像包含模板的图像列表,并读入模板图像:</li>
</ol>
<pre><code>files = ["img1.png", "img2.png", "img3.png"]
template = cv2.imread("template.png")
</code></pre>
<ol start=“5”>
<li>获取模板图像的大小,以便以后在图像上绘制矩形时使用:</li>
</ol>
<pre><code>h, w, _ = template.shape
</code></pre>
<ol start=“6”>
<li>循环遍历文件名并读入每个图像。使用前面定义的<code>confidence</code>函数,获取检测到的模板左上角的x-y位置和检测的置信度:</li>
</ol>
<pre><code>for name in files:
img = cv2.imread(name)
([y], [x]), conf = confidence(img, template)
</code></pre>
<ol start=“7”>
<li>在拐角处的图像上绘制一个矩形,并将文本放在图像上。最后,显示图像:</li>
</ol>
<pre><code> cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
text = f'Confidence: {round(float(conf), 2)}'
cv2.putText(img, text, (x, y), 1, cv2.FONT_HERSHEY_PLAIN, (0, 0, 0), 2)
cv2.imshow(name, img)
</code></pre>
<ol start=“8”>
<li>另外,显示模板以进行比较:</li>
</ol>
<pre><code>cv2.imshow('Template', template)
cv2.waitKey(0)
</code></pre>