9.2.2 Python图像处理之图像数学形态学-二值形态学应用-目标检测

9.2.2 Python图像处理之图像数学形态学-二值形态学应用-目标检测(击中与击不中)

1 算法原理

采用击中与击不中来进行目标检测

击中击不中变换定义

击中击不中变换(HMT)需要两个结构元素B1和B2,合成一个结构元素对B=(B1,B2)。一个用于探测图像内部,作为击中部分;另一个用于探测图像外部,作为击不中部分。显然,B1和B2是不应该相连接的,即B1∩B2=Φ。击中击不中变换的数学表达式为:

g(x, y)=hitmiss[f(x, y), B]=erode[f(x, y), B1]AND erode[fc(x, y), B2]

其中,fc(x,y)表示的是f(x,y)的补集。

Hit-miss示意图

已知A,B:在A图中寻找B图所示的图像目标的位置。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FX6fPUZi-1629254063009)(file:///C:\Users\mgboy\AppData\Local\Temp\ksohtml11668\wps7.jpg)]

4步

1 确定结构元素

既然是寻找图B所示形状,选取H为图B所示的形状。再选一个小窗口W,W包含H,M=W-H。如下图所示:

image-20210808173653941

2,求H对待检测A的腐蚀

image-20210808174044024

image-20210808173818185

3、求M对A补集的腐蚀

image-20210808174036188

image-20210808173902018

4、求2,3步结果的交集得到目标图案的位置

image-20210808174030227

image-20210808173949590

2 代码

运行代码说明

1.要改变代码中的图片地址(地址不能有中文)

更改65-66行的图片地址

2.注意最后的plt.savefig('1.new.jpg')是保存plt图像,如果不使用可以注释掉

代码依赖包:

matplotlib  3.4.2
numpy  1.20.3
opencv-python  4.1.2.30
# pip安装
pip install matplotlib numpy opencv-python
import cv2
import matplotlib.pyplot as plt
import numpy as np
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

def plt_show_opcv(title, image):
    '''
    显示结果图像,只有一个图像
    :param title:
    :param image:
    :return:
    '''
    if image.shape.__len__() == 3:
        plt.imshow(image[:, :, ::-1])
    else:
        plt.imshow(image, cmap='gray')
    plt.title(title)
    plt.savefig(title + "Target_Detection.jpg")
    plt.show()

def pme(titles, images, rc=None):
    '''
    显示多张图像在一个画布
    :param titles:
    :param images:要显示图像的列表
    :param rc:
    :return:
    '''
    row = None
    col = None
    if rc is None:
        length = len(titles)
        row = int(np.sqrt(length))
        col = int(length / row)
        if length - row - col > 0:
            row += 1
    else:
        row = rc[0]
        col = rc[1]

    for i in range(len(titles)):
        plt.subplot(row, col, i + 1), plt.imshow(images[i], 'gray')
        plt.title(titles[i])
    plt.savefig(titles[1]+"Target_Detection.jpg")
    plt.show()


def hmt(a, b):
    b1 = ~b  # 补集
    b2 = b
    a1 = ~a
    a2 = a
    pme(["原图补集", "原图", "目标图形补集", "目标图形原图"],[a1, a2,b1, b2])


    x1_erode_b1 = cv2.erode(a1, b1)# 补集腐蚀
    x2_erode_b2 = cv2.erode(a2, b2)  # 正常腐蚀

    r = cv2.bitwise_and(x1_erode_b1, x2_erode_b2)
    pme(['补集之间腐蚀', '正常图像腐蚀',"最后腐蚀结果"], [x1_erode_b1, x2_erode_b2,r])
    return r


image_X = cv2.imread("jiance2.png", 0)  # 待检测的图像
image_B = cv2.imread("shuzi2.png", 0)  # 模板图像


ret1, image_X = cv2.threshold(image_X, 127, 255, cv2.THRESH_BINARY)
ret2, image_B = cv2.threshold(image_B, 127, 255, cv2.THRESH_BINARY)

re = hmt(image_X, image_B)

targets = []
for i in range(re.shape[0]):
    for j in range(re.shape[1]):
        if re[i][j]:
            targets.append((j, i))
            print(i, j)

for target in targets:
    image_X = cv2.drawMarker(image_X, target, 125, markerType=cv2.MARKER_CROSS, markerSize=20, thickness=3)
plt_show_opcv("十字标记目标", image_X)

3 效果

使用击中与击不中原理来检测目标,这个我只在方方正正的目标和图像中实现了,其他复杂图像没能成功。

我实验的待检测的图片,左上角的黑色正方形是要检测的目标图案

image-20210808173156451

模板图案:

image-20210808173307407


结果图像

原图Target_Detection.jpg

image-20210808172846091

正常图像腐蚀Target_Detection.jpg

image-20210808172914012

目标结果图像

image-20210808174333130

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值