自动对焦算法

自动对焦算法

    • 算法
    • 步骤
    • 代码
    • 后记

算法

图像清晰度参考 https://blog.csdn.net/dcrmg/article/details/53543341

在实际应用中,清晰度随着对焦点的移动,呈以下图像的趋势。说白了就是有一个波峰,我们进行对焦的时候会经过这个波峰,那怎么知道这个波峰在哪呢?
自动对焦算法_第1张图片

步骤

1、首先我们一开始是不知道图像是否在对焦点的,因为清晰度这玩意儿,变化非常大,分辨率,亮度等都会影响,所以是没办法定一个死的峰值来判断,这就需要我们随机往一个方向进行对焦(这里我用的是垂直电机对焦)。
2、第二张图你就会知道,清晰度是增加了,还是减少了,就可以知道我们应该往哪个方向进行对焦。当然这一步也有可能因为步幅太大,直接越过波峰和同等清晰度的点,但是实际应用中这种情况比较少见,因为我们可以手动修改步幅,尽可能避免这种情况。
3、知道方向之后我们一直运动清晰度是一直增加的,跑到越过波峰的时候,我们的清晰度会比前一次的低。这时候我们可以判断我们越过了波峰。
4‘、这时候我们可以往反方向进行小步幅进行精对焦,知道第二次越过波峰(这里我们可以进行第三次更小步幅对焦,但是清晰度这东西很玄学,这么小的步幅很有可能会出现清晰度理应增加的方向,清晰度降低了,自行判断即可,实际应用中两轮就可以了,如果是合适的步幅运动一轮也已经可以达到不错的效果)。

注意:不能用全图进行对焦,所以ROI很重要。

代码

    public void AutoFocus()
    {
    label:
        List focusL = new List();
        int Round=2;
        int T=1;
        while (true)
        {
            //获取当前清晰度
            Bitmap currentBmp=GetImage();   //这里是获取相机的图片,每个人都有自己的方法,这里不详说,懂意思就行
            Rectangle Roi=new Rectangle();     //需要对焦的区域
            double currentArticulation = GetArticulation(currentBmp,roi);  //这里参考上面的连接,

            focusL.Add(currentArticulation);
            if (focusL.Count == 1) //这里是第一次运动
            {
                RunPulse(pulse); //对焦的运动方法,自己换成自己的
                continue;
            }
            //前两张确认调焦方向
            if (focusL.Count == 2)
            {
                if (currentArticulation > focusL[focusL.Count - 2]) //判断是否跑对方向
                {
                    pulse *= 1; //对的方向
                    RunPulse(pulse);  
                }
                else
                {
                    pulse *= -1; //不对的方向我们相反就可以了
                    RunPulse(pulse*1.5);   //这里不是跑回原来的位置,而是更过去一些,节约时间
                }
                
                continue;
            }
            //清晰度大于前一张图
            if (currentArticulation > focusL[focusL.Count - 2])
            {
                RunPulse(pulse);
            }
            else
            {
                ////返回峰值,跳出循环
                
	               if(T==Round)
	               {
	               		break; //两轮结束了,跳出循环
	               }
                goto label;
                
            }
        }
    }

后记

这里只提供思路。用什么语言都无所谓的。我这用的是C井

你可能感兴趣的:(技术)