cv2.minMaxLoc()基础使用与目标匹配检测结合实践

cv2.minMaxLoc() 是 OpenCV 库中的一个函数,用于在给定的数组(通常是图像)中找到最小值和最大值,并返回它们的位置。这个函数在图像处理中非常有用,特别是在需要找到图像中的极值点时。

函数定义:

minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(src, mask=None)

参数

  • src:输入数组(通常是单通道图像)。

  • mask(可选):掩码数组,用于指定在哪些区域中查找最小值和最大值。如果为 None,则在整个数组中查找。

返回值

  • minVal:数组中的最小值。

  • maxVal:数组中的最大值。

  • minLoc:最小值的位置(以元组形式返回,例如 (x, y))。

  • maxLoc:最大值的位置(以元组形式返回,例如 (x, y))。

示例

以下是一个简单的示例,展示如何使用 cv2.minMaxLoc() 函数:

import cv2
import numpy as np

# 创建一个示例图像
image = np.array([
    [10, 20, 30],
    [40, 50, 60],
    [70, 80, 90]
], dtype=np.uint8)

# 使用 cv2.minMaxLoc() 查找最小值和最大值及其位置
minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(image)

print(f"最小值: {minVal} 位置: {minLoc}")
print(f"最大值: {maxVal} 位置: {maxLoc}")

结果输出如下:

最小值: 10 位置: (0, 0)
最大值: 90 位置: (2, 2)

借助于cv2.minMaxLoc()的这个功能特性可以实现非常有用的功能,比如:挖掘图像的最亮区域、挖掘波峰最大最小极值等等,在实际的项目开发中,可以整合cv2.minMaxLoc()方法来帮助我们完成yolo系列模型目标检测推理的计算操作。

实例如下:

row = output_data[i]
confidence = row[4]
if confidence >= 0.4:
    classes_scores = row[5:]
    print("classes_scores_shape: ", classes_scores.shape)
    _, _, _, max_indx = cv2.minMaxLoc(classes_scores)
    print("_, _, _, max_indx: ", _, _, _, max_indx)
    class_id = max_indx[1]
    print("class_id: ", class_id)

实例输出如下:

classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 49) (0, 49) (0, 49) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 49) (0, 49) (0, 49) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 49) (0, 49) (0, 49) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 49) (0, 49) (0, 49) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 49) (0, 49) (0, 49) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 49) (0, 49) (0, 49) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 18) (0, 18) (0, 18) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 9) (0, 9) (0, 9) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 9) (0, 9) (0, 9) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 9) (0, 9) (0, 9) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 9) (0, 9) (0, 9) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 9) (0, 9) (0, 9) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 9) (0, 9) (0, 9) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 9) (0, 9) (0, 9) (0, 30)
class_id:  30
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17
classes_scores_shape:  (50,)
_, _, _, max_indx:  (0, 3) (0, 3) (0, 3) (0, 17)
class_id:  17

上述推理处理核心是基于onnx完成推理计算得到模型的输出之后,利用cv2.minMaxLoc()方法来帮助我们实现最大值、最小值的提取以及对应坐标位置的提取。

yolo系列模型是现代化的目标检测解除的算法模型,在早期的时候非常基础简单的目标检测实现方式可以借助于cv2.matchTemplate()方法来做基础的实现。

cv2.matchTemplate() 是 OpenCV 库中的一个函数,用于在输入图像中搜索模板图像。该函数通过滑动模板图像在输入图像上的方式,计算每个位置的匹配程度,从而找到最佳匹配位置。这在对象检测和图像匹配任务中非常有用。

OpenCV提供了6种模板匹配算法。

method    名称    含义
TM_SQDIFF    平方差匹配    
计算模板与目标图像的方差,由于是像素值差值的平方的和,所以值越小匹配程度越高。

TM_CCORR     相关匹配    该方法采用乘法操作;数值越大表名匹配程度越好。
TM_CCOEFF     相关系数匹配    计算相关系数,1表示完美匹配;-1表示最差匹配。
TM_SQDIFF_NORMED     归一化平方差匹配    计算归一化平方差,计算出来的值越接近0,越相关。
TM_CCORR_NORMED     归一化相关匹配    计算归一化相关性,计算出来的值越接近1,越相关。
TM_CCOEFF_NORMED     归一化相关系数匹配    计算归一化相关系数,计算出来的值越接近1,越相关。

函数定义实现:

result = cv2.matchTemplate(image, templ, method[, result[, mask]])

参数

  • image:输入图像(通常是灰度图像),在其中搜索模板。

  • templ:模板图像(通常是灰度图像),其大小不应超过输入图像,并且数据类型应与输入图像相同。

  • method:匹配方法,可以是以下之一:

    • cv2.TM_SQDIFF

    • cv2.TM_SQDIFF_NORMED

    • cv2.TM_CCORR

    • cv2.TM_CCORR_NORMED

    • cv2.TM_CCOEFF

    • cv2.TM_CCOEFF_NORMED

  • result(可选):输出匹配结果的矩阵。如果未指定,函数会自动创建一个。

  • mask(可选):掩码图像,用于指定模板图像中哪些像素参与匹配。仅当 method 为 cv2.TM_SQDIFF 或 cv2.TM_CCORR 时有效。

返回值

  • result:匹配结果矩阵,其大小为 (W-w+1, H-h+1),其中 W 和 H 是输入图像的宽度和高度,w 和 h 是模板图像的宽度和高度。

示例

以下是一个简单的示例,展示如何使用 cv2.matchTemplate() 函数:

import cv2
import numpy as np
from matplotlib import pyplot as plt

# 读取输入图像和模板图像
image = cv2.imread('input_image.jpg', cv2.IMREAD_GRAYSCALE)
template = cv2.imread('template_image.jpg', cv2.IMREAD_GRAYSCALE)

# 使用 cv2.matchTemplate() 进行模板匹配
result = cv2.matchTemplate(image, template, cv2.TM_CCOEFF_NORMED)

# 找到最佳匹配位置
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(result)

# 绘制匹配结果
top_left = max_loc
bottom_right = (top_left[0] + template.shape[1], top_left[1] + template.shape[0])
cv2.rectangle(image, top_left, bottom_right, 255, 2)

# 显示结果
plt.subplot(121), plt.imshow(result, cmap='gray')
plt.title('Matching Result'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(image, cmap='gray')
plt.title('Detected Point'), plt.xticks([]), plt.yticks([])
plt.show()

代码逻辑解释

  1. 读取输入图像和模板图像。

  2. 使用 cv2.matchTemplate() 函数进行模板匹配,选择 cv2.TM_CCOEFF_NORMED 方法。

  3. 使用 cv2.minMaxLoc() 函数找到最佳匹配位置。

  4. 在输入图像上绘制矩形框,标记出匹配位置。

  5. 使用 matplotlib 显示匹配结果和标记后的输入图像。

通过这种方式,可以在输入图像中找到模板图像的最佳匹配位置,并进行可视化展示。

接下来我们来做一个有趣的实践,代码实现如下所示:

#!usr/bin/env python
# encoding:utf-8
from __future__ import division


"""
__Author__:沂水寒城
功能: 基于OpenCV实现目标检测
"""


import cv2 as cv2
import numpy as np
from matplotlib import pyplot as plt



def baseObjectDetection(template="00a0ca4c278335a01727bdae64b0cc92.jpg", son="son.png"):
    """
    简单目标检测实例
    """
    template = cv2.imread(template)
    son = cv2.imread(son)
    h, w = son.shape[:2]
    # 检测匹配
    res = cv2.matchTemplate(template, son, cv2.TM_CCOEFF_NORMED)
    # 挖掘位置区域坐标
    minVal, maxVal, minLoc, maxLoc = cv2.minMaxLoc(res)
    top, left = maxLoc
    bottom, right = top + w, left + h
    # 可视化
    cv2.rectangle(template, (top, left), (bottom, right), (255, 0, 0), 5)
    # 存储
    cv2.imwrite("res.jpg", template)



if __name__ == "__main__":


    baseObjectDetection(template="00a0ca4c278335a01727bdae64b0cc92.jpg", son="son.png")

其中:
00a0ca4c278335a01727bdae64b0cc92.jpg如下所示:

son.png是我们从原图中随意crop出来的目标对象,接下来我们依次来看下实验效果:

可以看到:我们人工crop出来的子目标作为son.png来进行检测匹配,无一例外都非常好的检测出来了。

接下来我们想看下实际汉字能否想上面的子目标一样完成检测,理论上感觉应该是可以的,这里哦我们实验结果如下:

稳稳命中,还是非常不错的。

感兴趣的话也可以自行动手实践下!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Together_CZ

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

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

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

打赏作者

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

抵扣说明:

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

余额充值