zoukankan      html  css  js  c++  java
  • 摄像头模组自动对焦算法

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

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

    第一种,穷举法,

    将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来获取。

  • 相关阅读:
    成为明星程序员的10个提示
    使用命令时一些快捷的方法
    mysql字符串截取
    MFGTool2批量操作
    busybox microcom Segmentation fault
    Linux 定制X86平台操作系统
    Buildroot MariaDB替代MySQL
    arcotg_udc: exports duplicate symbol imx_usb_create_charger (owned by kernel)
    create newline in Github Bio
    BusyBox ifup udhcpc后台运行
  • 原文地址:https://www.cnblogs.com/zxl971213/p/13640120.html
Copyright © 2011-2022 走看看