模拟退火实现跟踪

首先了解什么是模拟退火,模拟退火相比较于爬上算法优点就是从局部最优解突破到全局最优解

可以看一下这篇文章最优化算法之模拟退火算法(SA)

那么使用模拟退火实现跟踪的代码如下:

get_entropy方法用来计算能量,这里是使用的互信息熵值作为能量。

sa就是模拟退火算法。

使用模拟退火进行跟踪只是一次学习的过程,重在学习。跟踪过程一整个胡蹦乱跳的/(ㄒoㄒ)/~~

应该是因为sa中随机扰动值的问题吧。模拟退火用来跟踪是不合理的。

import cv2
import numpy as np
import random
import math
import time
start_time=time.time()
cap=cv2.VideoCapture('m.mp4')
ok,frame=cap.read()
roi=cv2.selectROI(frame,True,False)
width,hight,w,h = roi
img_roi = frame[hight:hight+h , width:width+w]
cv2.imwrite('img_roi.jpg',img_roi)
out=cv2.VideoWriter('draw_mouse.mp4',fourcc=cv2.VideoWriter_fourcc('M', 'P', '4', 'V'),fps=30,frameSize=[720,720])
#选取图片的高宽
img_h,img_w=img_roi.shape[:2]

def get_entropy(h,w,target,template):
    Hd = 0.0
    Pa = np.zeros(256, np.float)
    SumPa = template.shape[0] * template.shape[1]
    # 统计模板图片每个灰度值的数量
    dis_template, _ = np.histogram(template.ravel(), 256, [0, 256])

    # 计算模板图片的信息熵
    for i in range(256):  # 遍历每个灰度值
        if dis_template[i] != 0:
            # 计算每个灰度值的概率
            Pa[i] = dis_template[i] / SumPa
            # 计算每个灰度值的概率的自然对数
            lgPa = math.log(Pa[i], 2)
            # 计算信息熵
            Hd += -(Pa[i] * lgPa)

    # 2.计算目标图片的信息

    HS = 0  # 记录每个候选框信息熵
    Pb = np.zeros(256, np.float)  # 记录每个候选框中每个灰度值的概率
    # 统计模板图片每个灰度值的数量
    target_cut = target[int(h):int(h + template.shape[0]), int(w):int(w + template.shape[1])]
    dis_target, _ = np.histogram(target_cut.ravel(), 256, [0, 256])

    # 计算模板图片的信息熵
    for i in range(256):  # 遍历每个灰度值
        if dis_target[i] != 0:
            # 计算每个灰度值的概率
            Pb[i] = dis_target[i] / SumPa
            # 计算每个灰度值的概率的自然对数
            lgPb = math.log(Pb[i], 2)
            # 计算信息熵
            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, 2)
                    HdS += -(Pab * lgPab)
    # 4.计算互信息熵值
    IdS = Hd + HS - HdS
    return IdS
def sa(target,template):
    T = 150  # 初始值
    t = T
    min = 100  # 最小值
    k = 20  # 内循环迭代次数
    d = 0.9
    # 随机框的范围
    boundary_x = target.shape[0] - template.shape[0]
    boundary_y = target.shape[1] - template.shape[1]
    # 生成随机框的坐标
    x = np.random.randint(0, boundary_x, [k])
    y = np.random.randint(0, boundary_y, [k])
    result = 0
    h, w = 0, 0
    # 外循环
    z = 0
    while t > min:
        # 内循环

        z += 1
        for i in range(k):

            trans = get_entropy(x[i], y[i], target, template)
            x_new = x[i] + t * (random.random() - random.random())*0.01
            y_new = y[i] + t * (random.random() - random.random())*0.01
            if x_new >= 0 and x_new <= boundary_x and y_new >= 0 and y_new <= boundary_y:
                trans_new = get_entropy(x[i], y[i], target, template)
                if trans_new > trans:
                    x[i] = x_new
                    y[i] = y_new
                else:
                    p = 1 / (1 + math.exp(-(trans_new - trans) / T))
                    if random.random() < p:
                        x[i] = x_new
                        y[i] = y_new
        t = t * d  # 每外循环一次迭代,温度降低

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

f_s=1
while cap.isOpened():
    ok,frame=cap.read()
    if not ok:
        break
    print(f_s)
    f_s+=1
    frame_g=cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
    img_g=cv2.cvtColor(img_roi,cv2.COLOR_BGR2GRAY)
    h,w=sa(frame_g,img_g)
    print(h,w)
    draw=cv2.rectangle(frame,(w,h),(w+img_w,h+img_h),color=[0,0,255],thickness=2)
    cv2.imshow('demo',draw)
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break
    out.write(draw)


cap.release()
out.release()
cv2.destroyAllWindows()
end_t=time.time()
print(end_t-start_time)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值