前言
最近在做聚焦算法,需要找到无参考图像中图像质量最好的,其中用到了随机爬山算法,
最开始采用三轮爬山,三轮步长不同,寻找最优解,但是发现精度不够,有的时候因为步长原因会跳过最佳点
后采用新的随机爬山算法
原理介绍
本算法第一轮采用大步长爬山算法确定范围值,如果找到局部峰值后,再向前继续找一步,如果同为下降趋势则停止
后几轮采用小步长迭代方法寻找最优解,最优解结果范围:±最后一轮步长,如果对迭代次数没有要求,最后步长为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