攝像頭模組自動對焦算法


本算法只用於自己寫的測試軟件進行模組圖像對焦,並不是手機拍照功能的對焦算法。

 

自動對焦目前我想到的實現方法有兩種:

第一種,窮舉法,

將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來獲取。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM