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()
基于模拟退火的图像匹配算法
最新推荐文章于 2023-01-18 18:47:08 发布