python 新的随机爬山算法,一起交流~

前言

最近在做聚焦算法,需要找到无参考图像中图像质量最好的,其中用到了随机爬山算法,
最开始采用三轮爬山,三轮步长不同,寻找最优解,但是发现精度不够,有的时候因为步长原因会跳过最佳点
后采用新的随机爬山算法

原理介绍

本算法第一轮采用大步长爬山算法确定范围值,如果找到局部峰值后,再向前继续找一步,如果同为下降趋势则停止
后几轮采用小步长迭代方法寻找最优解,最优解结果范围:±最后一轮步长,如果对迭代次数没有要求,最后步长为1迭代会更精确
流程图如下所示
爬山算法流程图

爬山算法示意图

如图根据三轮后选择峰值点。
在这里插入图片描述

核心代码

class AutoFEL():

	def run_procedure(self,img,cur_fel):
	
        if  self.curCircle == 1: # 1轮采用爬山
            self.x_list.append(int(cur_fel))
            var = self.img_var(img)
            focus_v = self.focus_value(img, 3, 64, 5, 5)
            scharr_v = self.scharr_demo(img)
            result_v = np.average((var, focus_v, scharr_v), weights=[4, 3, 3])
            # print('value = ',result_v)
            self.result_list.append(result_v)
					
			#先处理前两张图像分辨前进方向 
            if self.imageCount < 2:
                if self.imageCount == 0:
                    if cur_fel + self.stepsize <= 200:
                        nextFel = cur_fel + self.stepsize * self.direction
                        self.ret_status = 0
                        self.imageCount += 1
                        return nextFel, self.ret_status
                    else:
                        self.direction = -1
                        nextFel = cur_fel + self.stepsize * self.direction
                        self.ret_status = 0
                        self.imageCount += 1
                        return nextFel, self.ret_status
                else:
                    # check the direction
                    if self.result_list[0] >= self.result_list[1] and cur_fel - self.stepsize * 2 > -200:
                        self.direction = -1
                        self.result_list.pop(0)
                        self.x_list.pop(0)

                    nextFel = cur_fel + self.stepsize * self.direction
                    self.ret_status = 0
                    self.imageCount += 1
                    return nextFel, self.ret_status
            else:

                if self.isToPeak :

                    if self.result_list[-1] < self.result_list[-2]:
                        # 连续下降,找到峰值,以及当前爬坡结束,
                        nextFel = self.peakFel - 2 * self.stepsize
                        print("nextFel = ",nextFel)
                        self.small_range = self.peakFel + self.stepsize * 2
                        print("small_range = ",self.small_range)
                        self.stepsize = int(self.stepsize / 2)
                        self.x_list = []
                        self.result_list = []
                        self.curCircle += 1
                        self.ret_status = 0
                        return nextFel, self.ret_status
                    else:
                        # 非连续下降,isToPeak = False, 继续沿着原来的方向走
                        nextFel = cur_fel + self.stepsize * self.direction
                        self.ret_status = 0
                        self.isToPeak = False
                        return nextFel, self.ret_status

                else:
                    state_flag, max_x = self.jugde_max(self.x_list, self.result_list)
                    if state_flag == 1:
                        self.peakFel = max_x
                        print("p = ",self.peakFel)
                        nextFel = cur_fel + self.stepsize * self.direction
                        self.isToPeak = True
                        self.ret_status = 0
                        return nextFel, self.ret_status
                    else:
                        nextFel = cur_fel + self.stepsize * self.direction
                        self.ret_status = 0
                        return nextFel, self.ret_status
                        
        else: # 2, 3轮根据固定步长遍历

            if cur_fel < self.small_range:
                self.x_list.append(int(cur_fel))
                var = self.img_var(img)
                focus_v = self.focus_value(img, 3, 64, 5, 5)
                scharr_v = self.scharr_demo(img)
                result_v = np.average((var, focus_v, scharr_v), weights=[4, 3, 3])
                # print('value = ',result_v)
                self.result_list.append(result_v)
                nextFel = cur_fel + self.stepsize
                self.ret_status = 0
                return nextFel, self.ret_status
            else:

                max_value = max(self.result_list)
                max_t = self.result_list.index(max_value)
                max_x = self.x_list[max_t]
                self.peakFel = max_x
                if self.curCircle != 3:
                    nextFel = self.peakFel - 2 * self.stepsize

                    self.x_list = []
                    self.result_list = []
                    self.curCircle += 1
                    self.ret_status = 0
                    self.small_range = self.peakFel + 2 * self.stepsize
                    self.stepsize = 4
                    return nextFel, self.ret_status
                else:
                    self.ret_status = 1
                    return self.peakFel,self.ret_status

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
下面是一个 Python 自动对焦爬山算法的代码实现: ```python import numpy as np import cv2 # 定义目标函数 def objective_function(img, x, y): # 截取以 x, y 为中心的 32x32 的图像 h, w = img.shape[:2] x = np.clip(int(x), 16, w - 16) y = np.clip(int(y), 16, h - 16) patch = img[y-16:y+16, x-16:x+16] # 计算图像的方差,作为目标函数值 return np.var(patch) # 定义爬山算法 def hill_climbing(objective_function, bounds, img, max_iter): # 初始化当前解 current = [np.mean(bounds[i]) for i in range(len(bounds))] # 迭代 for i in range(max_iter): # 计算当前解的目标函数值 current_cost = objective_function(img, *current) # 随机选择一个邻居 neighbor = [np.clip(np.random.normal(current[i], 5), *bounds[i]) for i in range(len(bounds))] # 计算邻居的目标函数值 neighbor_cost = objective_function(img, *neighbor) # 如果邻居的目标函数值更好,则更当前解 if neighbor_cost > current_cost: current = neighbor current_cost = neighbor_cost return current # 测试 img = cv2.imread('test.jpg', cv2.IMREAD_GRAYSCALE) bounds = [(0, img.shape[1]), (0, img.shape[0])] best = hill_climbing(objective_function, bounds, img, 100) print('最优解:', best) ``` 这个实现中,目标函数是图像方差,bounds 是搜索范围,max_iter 是最大迭代次数。hill_climbing 函数接受这些参数,并返回最优解。算法的实现很简单,每次随机选择一个邻居并计算目标函数值,如果邻居的目标函数值更好,则更当前解。在这个例子中,邻居是以当前解为中心,随机扰动一定的距离得到的。最后返回当前解即可。这个算法可以用于自动对焦,找到图像中最清晰的区域。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

五岁能抬头s

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

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

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

打赏作者

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

抵扣说明:

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

余额充值