摄像头模组自动对焦算法

本算法只用于自己写的测试软件进行模组图像对焦,并不是手机拍照功能的对焦算法。

自动对焦目前我想到的实现方法有两种:

第一种,穷举法,

将VCM马达从0往上推或者从1023往下推,将每个code值所拍到的buffer进行图像清晰度测试,再将产生的数据形成数组,进行最大值计算。

第二种,数据对比,

将VCM马达从0往上推或者从1023往下推,前一个code值所计算的清晰度数据a1和后一个code值所计算的清晰度数据a2进行对比,if(a1<a2),则继续同方向推马达,if(a1>a2),则将步幅减为原步幅的1/3,进行反方向推马达,之后再碰到a1>a2时,跳回前一个code值,这个code值就是对焦值。

实现方法:

第一种:穷举法

 1         //设置步数
 2int   b_test=50 3         if(b_test>=0)
 4         {
 5             int i;
 6            //获取刚开始的步数,即50
 7             i= 50 8 
 9             if(b_test>0)
10             {
11                 try{
12                     double a;
13                     //获取清晰度值,清晰度算法参考opencv清晰度测试
14                     a=GetAFcode(pBuffer);
15                     testArr[i-b_test]=a;
16                     USHORT b;
17                     //读取当前code值
18                     ReadSensorReg(0x1c,0x03,&b,0x02,0);
19                     codeArr[i-b_test]=b;
20                     qDebug()<<""<<i-b_test<<"次,清晰度为:"<<a<<"。code值为:"<<b;
21                     USHORT c=1023/i;
22                     //写入下一个code值,
23                     WriteSensorReg(0x1c,0x03,b-c,0x02,0);
24                     Sleep(10);
25                 }
26                 catch(Exception e){
27                     qDebug()<<"Af错误";
28                 }
29             }
30             else//当b_test==0时,即穷举完成,即将进行数组最大值获取
31             {
32                 //获取数组中最大的数据
33                 int max=max_element(testArr,testArr+i)-testArr;
34                 qDebug()<<"清晰度最高的下标为:"<<max;
35                 //写入图像最清晰时的code值
36                 WriteSensorReg(0x1c,0x03,codeArr[max],0x02,0);
37             }
38             b_test=b_test-1;
39         }

第二种:数据对比法

 1         int bac=0;
 2         double AFval1=0 3         double AFval2=0 4         double AFval3=0 5         if(b_AFtest)
 6         {
 7             if(bac>0)//反向后
 8             {
 9                 USHORT a;
10                 ReadSensorReg(0x1c,0x03,&a,0x02,0);
11                 AFval3=GetAFcode(pBuffer);//当前清晰度获取
12                 if(AFval3>AFval1)//证明没过峰值,继续向前跑
13                 {
14                     WriteSensorReg(0x1c,0x03,a-10,0x02,0);//vcm反向走10步
15                     bac=bac+1;
16                     AFval1=AFval3;
17                     AFval3=0;
18                 }
19                 else if(AFval3<AFval1)//越过峰值,即可认为上一个code值为最佳
20                 {
21                     qDebug()<<"即可认为上一个code值为最佳";
22                     WriteSensorReg(0x1c,0x03,a+10,0x02,0);//vcm反向走10步
23                     b_AFtest=FALSE;//结束自动对焦
24                 }
25             }
26             else if(bac==0)//还没有反向推焦
27             {
28                 if(AFval1==0)//第一次测清晰度
29                 {
30                     qDebug()<<"第一次";
31                     AFval1=GetAFcode(pBuffer);//获取第一个清晰度值
32                     WriteSensorReg(0x1c,0x03,1023-50,0x02,0);//vcm向前50
33                     //                Sleep(5000);
34                     stepNum=stepNum-1;//减少一步
35                     qDebug()<<"AFval1:"<<AFval1;
36                 }
37                 else
38                 {
39                     AFval2=GetAFcode(pBuffer);//获取当前清晰度值
40                     qDebug()<<"AFval2="<<AFval2;
41                     if(AFval2>AFval1)//清晰度在提高,移动方向正确
42                     {
43 
44                         USHORT a;
45                         ReadSensorReg(0x1c,0x03,&a,0x02,0);
46                         WriteSensorReg(0x1c,0x03,a-50,0x02,0);//vcm继续向前50
47                         Sleep(50);
48                         qDebug()<<"AFval1:"<<AFval1;
49                         AFval1=AFval2;//将AFval2传给AFval1
50                         AFval2=0;//清空AFval2
51                         stepNum=stepNum-1;//减少一步
52 
53 
54                         qDebug()<<"向前";
55                         //                    b_AFtest=FALSE;
56                     }
57                     else if(AFval2<AFval1)//AFval2<AFval1,证明越过峰值了
58                     {
59                         qDebug()<<"2<1";
60 
61                         USHORT a;
62                         ReadSensorReg(0x1c,0x03,&a,0x02,0);
63                         WriteSensorReg(0x1c,0x03,a+40,0x02,0);//往回跑40code
64                         Sleep(50);
65 
66                         stepNum=stepNum-1;//减少一步
67                         AFval1=AFval2;//将AFval2传给AFval1
68                         qDebug()<<"AFval1:"<<AFval1;
69                         AFval2=0;
70                         qDebug()<<"应该反向了";
71                         bac=bac+1;
72                     }
73                 }
74             }
75         }

自动对焦逻辑理解:

code值先设置到最大,然后慢慢往后退,检测当前清晰度和前一个清晰度进行大小对比,如果前一个比后一个清晰度要小,证明还没到峰值,继续往后退,如果前一个比后一个要大,证明越过了峰值,要进行反推,步幅减少为之前的1/5,再次判断,如果如果前一个比后一个小,继续反推,否者就判断前一个code值为最佳。该清晰度算法测试不精准且容易受环境影响,迟些再完善。

ps,清晰度数据可以通过OPENCV来获取。

原文地址:https://www.cnblogs.com/zxl971213/p/13640120.html