基于模拟退火的图像匹配算法

import math
import random

import cv2
import numpy as np


def getLoss(m, n, target, template):
    """
    得到损失函数的值
    :param m: 图像的x坐标
    :param n: 图像的y坐标
    :return:目标值
    """
    # 1.计算模板图片的信息
    dis_template = np.zeros(256, np.int)
    Hd = 0.0
    Pa = np.zeros(256, np.float)
    SumPa = template.shape[0] * template.shape[1]
    # 统计模板图片每个灰度值的数量
    for i in range(template.shape[0]):
        for j in range(template.shape[1]):
            dis_template[template[i, j]] = dis_template[template[i, j]] + 1
    # 计算模板图片的信息熵
    for i in range(256):  # 遍历每个灰度值
        if dis_template[i] != 0:
            # 计算每个灰度值的概率
            Pa[i] = dis_template[i] / SumPa
            # 计算每个灰度值的概率的自然对数
            lgPa = math.log(Pa[i], math.e)
            # 计算信息熵
            Hd += -(Pa[i] * lgPa)

    # 2.计算目标图片的信息
    dis_target = np.zeros(256, np.int)  # 记录每个候选框概率分布
    HS = 0  # 记录每个候选框信息熵
    Pb = np.zeros(256, np.float)  # 记录每个候选框中每个灰度值的概率
    # 统计模板图片每个灰度值的数量
    for i in range(template.shape[0]):
        for j in range(template.shape[1]):
            dis_target[target[m + i, n + j]] = dis_target[target[m + i, n + j]] + 1
    # 计算模板图片的信息熵
    for i in range(256):  # 遍历每个灰度值
        if dis_target[i] != 0:
            # 计算每个灰度值的概率
            Pb[i] = dis_target[i] / SumPa
            # 计算每个灰度值的概率的自然对数
            lgPb = math.log(Pb[i], math.e)
            # 计算信息熵
            HS += -(Pb[i] * lgPb)
    # 3. 计算联合概率分布
    HdS = 0
    for a in range(256):
        if dis_template[a] != 0:
            for b in range(256):
                if dis_target[b] != 0:
                    Pab = Pa[a] * Pb[b]
                    lgPab = math.log(Pab)
                    HdS += -(Pab * lgPab)
    # 4.计算互信息熵值
    IdS = Hd + HS - HdS
    return IdS


def getSA(T, T_min, k, delta, target, template):
    """
    模拟退火算法过程
    :param T:初始温度
    :param T_min:最小温度
    :param k:初始种群数
    :param delta:
    :param target:
    :param template:
    :return:
    """
    conditate_x = target.shape[0] - template.shape[0]
    conditate_y = target.shape[1] - template.shape[1]

    result = 0
    resultLocation = (0, 0)
    t = T
    # 随机数初始化种群
    x = np.random.randint(0, conditate_x, size=(k))
    y = np.random.randint(0, conditate_y, size=(k))
    # 迭代过程
    while t > T_min:
        for i in range(k):
            funTmp = getLoss(x[i], y[i], target, template)
            x_new = x[i] + (random.random() * 2 - 1) * t
            y_new = y[i] + (random.random() * 2 - 1) * t

            if x_new >= 0 and x_new <= conditate_x and y_new >= 0 and y_new <= conditate_y:
                funTmp_new = getLoss(x[i], y[i], target, template)  # 计算函数结果
                if funTmp_new - funTmp > 0:
                    x[i] = x_new
                    y[i] = y_new
                else:
                    p = 1 / (1 + math.exp(-(funTmp_new - funTmp) / T))
                    if random.random() < p:
                        x[i] = x_new
                        y[i] = y_new
        t = t * delta  # 温度下降一次

    for i in range(k):
        if result < getLoss(x[i], y[i], target, template):
            resultLocation = (x[i], y[i])
            result = getLoss(x[i], y[i], target, template)
    return result, resultLocation


def imgMatching(target, template):
    """
    图像匹配
    :param target:目标图像
    :param template: 模板图像
    :return: 匹配之后的图像
    """
    T = 200  # 初始温度
    T_min = 100  # 温度的下限
    k = 10  # 初始种群数量
    delta = 0.98  # 温度的下降率

    result, resultLocation = getSA(T, T_min, k, delta, target, template)
    return resultLocation

if __name__ == '__main__':
    target = cv2.imread('Resources/target3.jpg')
    template = cv2.imread('Resources/template2.jpg')
    target_gary = cv2.cvtColor(target, cv2.COLOR_BGR2GRAY)
    template_gary = cv2.cvtColor(template, cv2.COLOR_BGR2GRAY)
    loc = imgMatching(target_gary, template_gary)
    cv2.rectangle(target, loc, (loc[0] + template.shape[1], loc[1] + template.shape[0]), (0, 255, 255), 2)
    cv2.imshow('result', target)
    cv2.waitKey()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值