CN110855878A - 一种改进的自动对焦爬山搜索算法 - Google Patents

一种改进的自动对焦爬山搜索算法 Download PDF

Info

Publication number
CN110855878A
CN110855878A CN201910774916.5A CN201910774916A CN110855878A CN 110855878 A CN110855878 A CN 110855878A CN 201910774916 A CN201910774916 A CN 201910774916A CN 110855878 A CN110855878 A CN 110855878A
Authority
CN
China
Prior art keywords
mtf
motor
rect
focusing
szinifilepath
Prior art date
Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
Pending
Application number
CN201910774916.5A
Other languages
English (en)
Inventor
强剑博
Current Assignee (The listed assignees may be inaccurate. Google has not performed a legal analysis and makes no representation or warranty as to the accuracy of the list.)
Alex Hua Tian Hui Chuang Technology (xi'an) Co Ltd
Original Assignee
Alex Hua Tian Hui Chuang Technology (xi'an) Co Ltd
Priority date (The priority date is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the date listed.)
Filing date
Publication date
Application filed by Alex Hua Tian Hui Chuang Technology (xi'an) Co Ltd filed Critical Alex Hua Tian Hui Chuang Technology (xi'an) Co Ltd
Priority to CN201910774916.5A priority Critical patent/CN110855878A/zh
Publication of CN110855878A publication Critical patent/CN110855878A/zh
Pending legal-status Critical Current

Links

Images

Classifications

    • HELECTRICITY
    • H04ELECTRIC COMMUNICATION TECHNIQUE
    • H04NPICTORIAL COMMUNICATION, e.g. TELEVISION
    • H04N23/00Cameras or camera modules comprising electronic image sensors; Control thereof
    • H04N23/60Control of cameras or camera modules
    • H04N23/67Focus control based on electronic image sensor signals
    • H04N23/673Focus control based on electronic image sensor signals based on contrast or high frequency components of image signals, e.g. hill climbing method

Landscapes

  • Engineering & Computer Science (AREA)
  • Multimedia (AREA)
  • Signal Processing (AREA)
  • Studio Devices (AREA)

Abstract

本发明提供一种改进的自动对焦爬山搜索算法,包括以下步骤:步骤一:预设一马达搜索范围,采用固定步长驱动马达得到该搜索范围内MTF的最大值和对应的马达位置;步骤二:驱动马达到步骤一中MTF最大值的前一个位置,以该位置为起点,减小马达步长到精度要求并重新进行搜索,得到MTF最大值和相应马达位置;步骤三:将马达推动到步骤二MTF最大值对应的马达位置,此位置即为对焦最佳位置。本发明的技术方案,不需要再频繁的反转马达驱动镜头来回搜寻调焦最佳位置所带来的镜头来回晃动,使对焦容错率降低,并且大大降低了远离最佳调焦位置的区域内极值对调焦结果的影响,保证了对焦准确性。马达搜索范围的缩小更有利于实现快速对焦。

Description

一种改进的自动对焦爬山搜索算法
技术领域
本发明涉及摄像技术自动对焦领域,尤其涉及一种改进的自动对焦爬山搜索算法。
背景技术
所谓的爬山算法即是模拟爬山的过程,随机选择一个位置爬山,每次朝着更高的方向移动,直到到达山顶。即每次都在邻近的空间中选择最优解作为当前解,直到局部最优解。具体描述为从当前节点开始,和周围相邻节点值进行比较,如果当前节点是最大的,那么返回当前节点作为最大值。反之,就用相邻的节点来替换当前节点,从而实现向山峰高处攀爬的目的,如此循环直到达到最高点。现有的对焦算法利用ROI对焦区域内的亮度反差来计算当前画面是否处于清晰状态,在寻找清晰点的过程中马达的所处的位置和ROI亮度反差会形成一条调焦曲线,对焦实质就是寻找该曲线极大值。图1中纵轴MTF代表当前画面清晰度,横轴代表马达所处位置。
自动对焦就是算法实现获取MTF最大值的过程,因整个对焦过程生成的曲线是类似于正态分布的单峰曲线,故而目前主要使用爬山搜索法来寻找最佳对焦点。应用到对焦过程其原理如图2所示。
从起始位置出发,以固定步长驱动马达进而推动镜头运动,每推动一次马达相应计算一次MTF数值。在马达前进过程中,若MTF数值逐渐增大说明马达驱动方向正确,此时画面会逐渐由模糊变清晰。随着马达的继续驱动,当MTF数值开始减小且画面由清晰变模糊,则证明马达已经越过了对焦的最佳位置,完成了对焦第一步。
第一步对焦完成后,反向驱动马达并适当减小马达驱动步长,往回寻找最佳对焦位置。与第一步同理当MTF数值减小时候,证明马达已经越过了对焦的最佳位置,此时再次反转马达减小驱动步长,往回寻找最佳对焦位置。如此反复操作和搜索,最终马达步进减小到要求精度时停止搜索,该位置即为对焦最佳位置。
然而在实际对焦过程中,在远离最佳调焦位置的区域内,马达步进和MTF生成的几乎是一条平坦而略带起伏的曲线,此时MTF数值变化几乎很小或者不变化。当处在此区域时候,马达的下一步转动方向就很难确定,当遇到一个局部极值时候就会错误的判断为最佳对焦位置,无法正确进行对焦。
除此而外频繁的反转马达驱动镜头,不仅会使得镜头来回震荡找不到准确的对焦位置而且易使马达出现损坏。
“自动对焦中的优化爬山搜索算法”,郑玉珍,浙江科技学院学报,第17卷第3期,第171-174页,2005年9月,公开了一种优化爬山搜索算法,其缺点在于从第二次搜索开始,以上一次搜索对焦评价函数最大值位置的后一站为终点,当减小电机的步长后,搜索行程相对较长,由其优化的爬山搜索算法示意图可知,第二次搜索的结束处距离此次搜索所得的对焦评价函数最大值M2处,镜头移动步数至少为四步,自动对焦过程中搜索次数过多,效率降低。
发明内容
为了解决现有技术中存在的上述问题,本发明提供一种改进的自动对焦爬山搜索算法,包括以下步骤:
步骤一:预设一马达搜索范围,采用固定步长驱动马达得到该搜索范围内MTF的最大值和对应的马达位置。
步骤二:驱动马达到步骤一中MTF最大值的前一个位置,以该位置为起点,减小马达步长到精度要求并重新进行搜索,得到MTF最大值和相应马达位置。
步骤三:将马达推动到步骤二MTF最大值对应的马达位置,此位置即为对焦最佳位置。
进一步的,步骤一中,马达被设置在一个预设位置,以一个固定步长驱动镜头。马达每带动镜头运动一步,计算并保留相应MTF数值和马达所在位置,当马达运动次数大于两次,则记录当下MTF数据与前一次MTF数据两者之间较大的一个的数值和马达位置。以此类推当马达走完全程到达结束位置时,将会得到MTF最大值和对应的马达位置。
进一步的,步骤二中,以步骤一中MTF最大值的前一个位置为新的起点,减小马达驱动步长到精度要求,同样记录马达驱动镜头每一步相应的MTF数值和马达位置,当MTF数值开始减小且连续减小两次时,执行步骤三。
本发明所提供的改进的自动对焦爬山搜索算法,会在设置的某一搜索范围内以固定大步长搜索MTF最大值,基本可以排除远离最大点的局部极值的影响,且大步长必定能找到一个粗略的对焦最佳位置,再以小步精度找寻最终必然会找到对焦点的最佳清晰位置。并且大大减少了马达的反转次数,确保不会因镜头来回晃动致使找不到最佳对焦位置,使对焦容错率降低,进而提高对焦准确性。马达搜索范围的缩小更有利于实现快速对焦,提高效率。
本发明的技术方案极大地提高了自动对焦的速度和可靠性,此外马达的步进、搜索范围、次数都可以自行调节,因而对于实际对焦具有很大的灵活性和便捷性。
附图说明
图1为现有技术爬山搜索算法调焦曲线图。
图2为现有技术爬山搜索算法对焦过程示意图。
图3为本发明实施例的改进的自动对焦爬山搜索算法对焦过程示意图。
图4为本发明实施例的改进的自动对焦爬山搜索算法软件实现流程图。
具体实施方式
为使本发明实施例的目的、技术方案和优点更加清楚,下面将结合本发明实施例中的附图,对本发明实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例是本发明一部分实施例,而非全部的实施例。基于本发明中的实施例,本领域普通技术人员在没有做出创造性劳动的前提下所获得的所有其他实施例,都属于本发明保护的范围。
本发明提出的改进的自动对焦爬山搜索算法,原理如图3所示,具体包括以下步骤:
步骤一:预设一马达搜索范围,马达被设置在一预设位置,以一个固定步长驱动镜头。马达每带动镜头运动一步,计算并保留相应MTF数值和马达所在位置,当马达运动次数大于两次,则记录当下MTF数据与前一次MTF数据两者之间较大的一个的数值和马达位置。以此类推当马达走完全程,到达结束位置时,结束第一阶段行程,将会得到MTF最大值和对应的马达位置。
步骤二:驱动马达到步骤一中MTF最大值的前一个位置,以该位置为起点,减小马达步长到精度要求,重新进行搜索,同样记录马达驱动镜头每一步相应的MTF数值和马达位置,当MTF数值开始减小且连续减小两次时,结束第二阶段行程,得到该阶段行程MTF最大值和相应马达位置。
步骤三:将马达推动到当前位置的前两个位置,即步骤二MTF最大值对应的马达位置,此位置即为对焦最佳位置。
图4是本发明实施例的改进的自动对焦爬山搜索算法软件实现流程图,具体程序代码如下:
BOOLCDialog::MTF_Scan()
{
/* DWORD Starttime=GetTickCount();*/
ZeroMemory(Result, sizeof(double) * 128);
CommonFunction cf;
intnIdxRst = 0 ;
BOOLendFlag = FALSE;
DWORD WriteTime = 0;
boolresult_flag_MTF_FAR = false;
int qImageBytes = (videotype.Width / 2) * (videotype.Height /2);
SIZE ImgSize;
TCHAR BayerTypeChar[5];
cfType CFType;
float MTFValue_STEP[17]; // 算出來的MTF值
float STD_FAR_TL_8F_Spec =0.0 , STD_FAR_TR_8F_Spec =0.0;
float STD_FAR_TL_V_75F_Spec =0.0 , STD_FAR_TL_H_75F_Spec =0.0;
float STD_FAR_TR_V_75F_Spec =0.0 , STD_FAR_TR_H_75F_Spec =0.0;
float STD_FAR_CC_Spec =0.0;
float STD_FAR_CL_V_3F_Spec =0.0 , STD_FAR_CL_H_3F_Spec =0.0;
float STD_FAR_CR_V_3F_Spec =0.0 , STD_FAR_CR_H_3F_Spec =0.0;
float STD_FAR_BL_V_75F_Spec =0.0 , STD_FAR_BL_H_75F_Spec =0.0;
float STD_FAR_BR_V_75F_Spec =0.0 , STD_FAR_BR_H_75F_Spec =0.0;
float STD_FAR_BL_8F_Spec =0.0 , STD_FAR_BR_8F_Spec =0.0;
intSTD_FocusDac_High_Spec=0,STD_FocusDac_Low_Spec=0;
TCHAR tcSTDFar_TL_8F_MTF[10];
TCHAR tcSTDFar_TR_8F_MTF[10];
TCHAR tcSTDFar_TL_V_75F_MTF[10];
TCHAR tcSTDFar_TL_H_75F_MTF[10];
TCHAR tcSTDFar_TR_V_75F_MTF[10];
TCHAR tcSTDFar_TR_H_75F_MTF[10];
TCHAR tcSTDFar_CC_MTF[10];
TCHAR tcSTDFar_CL_V_3F_MTF[10];
TCHAR tcSTDFar_CL_H_3F_MTF[10];
TCHAR tcSTDFar_CR_V_3F_MTF[10];
TCHAR tcSTDFar_CR_H_3F_MTF[10];
TCHAR tcSTDFar_BL_V_75F_MTF[10];
TCHAR tcSTDFar_BL_H_75F_MTF[10];
TCHAR tcSTDFar_BR_V_75F_MTF[10];
TCHAR tcSTDFar_BR_H_75F_MTF[10];
TCHAR tcSTDFar_BL_8F_MTF[10];
TCHAR tcSTDFar_BR_8F_MTF[10];
ImgSize.cx = videotype.Width;
ImgSize.cy = videotype.Height;
floatMTF_pre0[17] = {0.0};
floatMTF_pre1[17] = {0.0};
floatMTF_pre2[17] = {0.0};
//==============================================
intMTF_DAC_BEGIN_FAR;
intMTF_DAC_END_FAR;
floatMTFTHFloat;
int Read_Write_EEPROM;
int Write_Sum=0;
int Read_Sum=0;
//迭代
intpixelcounter = 0;
inti = 0;
//處理buffer用到的參數
int BMP_IDX;
int ColorChannelSel;
int RGB_BytesPerPixel = 3;
intnColorMode;
int DAC_Min_Spec = 0;
int DAC_Max_Spec = 0;
PUSHORT rBuffer = NULL;
PUSHORT g1Buffer = NULL;
PUSHORT g2Buffer = NULL;
PUSHORT ggBuffer = NULL;
PUSHORT bBuffer = NULL;
//PUCHAR Raw8Buffer = NULL;
PUCHAR BitMapImgBuffer = NULL;
//read ini
charSectionName[100];
charIniFilePath[1000];
charchTmp[10];
//read from ini
intScanCount = 0; //掃描次數
intScanMode = 0; //1:五點全看,0 只看中心
intScanRange = 0; //兩邊擴大範圍
floatScanSub[10]; //MTF差值
intScanGap[10]; //掃描間距
intThroughFocus = 0;
intFocusOffset = 0; //減小Focus Dac
charVCMSlaveAddr[32]; //vcm driver ic address
charTempBuffer[32];
::ZeroMemory(SectionName,sizeof(SectionName));
::ZeroMemory(IniFilePath,sizeof(IniFilePath));
::ZeroMemory(VCMSlaveAddr, sizeof(char)*32);
::ZeroMemory(TempBuffer, sizeof(char)*32);
sprintf_s(IniFilePath,"%s",cf.TransferWCHARToCHAR(szIniFilePath));
sprintf_s(SectionName,"%s",cf.TransferWCHARToCHAR(szSectionName));
nColorMode = GetPrivateProfileIntA(SectionName, "nColorMode", 0,IniFilePath);
BMP_IDX = GetPrivateProfileIntA(SectionName,"BMP_IDX",0, IniFilePath);
ColorChannelSel = GetPrivateProfileIntA(SectionName,"CHANNEL_SELECT",0,IniFilePath);
GetPrivateProfileString(szSectionName,_T("BayerType"),_T("NULL"),BayerTypeChar,5,szIniFilePath);
GetPrivateProfileStringA(SectionName,"DEVICEADDRESS_DRIVERIC","NULL",VCMSlaveAddr,32,IniFilePath);
MTF_DAC_BEGIN_FAR = GetPrivateProfileIntA(SectionName,"MTF_DAC_BEGIN_FAR",-1, IniFilePath);
MTF_DAC_END_FAR = GetPrivateProfileIntA(SectionName,"MTF_DAC_END_FAR",-1, IniFilePath);
Read_Write_EEPROM = GetPrivateProfileInt(szSectionName,_T("Read_Write_EEPROM"),0,szIniFilePath);
//farMTF
ScanCount = GetPrivateProfileInt(szSectionName,_T("ScanCount"),-1,szIniFilePath);
ScanMode = GetPrivateProfileInt(szSectionName,_T("ScanMode"),-1,szIniFilePath);
ScanRange = GetPrivateProfileInt(szSectionName,_T("ScanRange"),-1,szIniFilePath);
ThroughFocus = GetPrivateProfileInt(szSectionName,_T("ThroughFocus"),-1,szIniFilePath);
FocusOffset = GetPrivateProfileInt(szSectionName,_T("FocusOffset"),-1,szIniFilePath);
DAC_Min_Spec = GetPrivateProfileInt(szSectionName,_T("DAC_Min_Spec"),200,szIniFilePath);
DAC_Max_Spec = GetPrivateProfileInt(szSectionName,_T("DAC_Max_Spec"),300,szIniFilePath);
if (ScanCount == -1 || ScanMode == -1 || ScanRange == -1 || ThroughFocus== -1 ||
MTF_DAC_BEGIN_FAR == -1 || MTF_DAC_END_FAR == -1 || FocusOffset == -1)
{
::MessageBox(g_hwndWhale, _T("ini read fail !!"), _T("Error"), MB_ ICONERROR);
}
ZeroMemory(TempBuffer, sizeof(char) * 10);
GetPrivateProfileStringA(SectionName,"MTF_TH","NULL",TempBuffer,10,IniFilePath);
MTFTHFloat = (float)atof(TempBuffer);
for(i=0;i<2;i++)
{
ScanGap[i] = 0;
ScanSub[i] = 0.0;
}
charwKeytemp[100];
charwKeytemp1[100];
for (i = 0;i<ScanCount;i++)
{
sprintf_s(wKeytemp,"ScanGap%d",i+1);
sprintf_s(wKeytemp1,"ScanSub%d",i+1);
ScanGap[i] = GetPrivateProfileIntA(SectionName,wKeytemp,-1,IniFilePath);
GetPrivateProfileStringA(SectionName,wKeytemp1,"NULL",TempBuffer,sizeof(TempBuffer),IniFilePath);
sscanf_s(TempBuffer,"%f",&ScanSub[i]);
}
if(_tcscmp(BayerTypeChar, _T("RGGB")) == 0)
CFType = RGGB;
elseif(_tcscmp(BayerTypeChar, _T("BGGR")) == 0)
CFType = BGGR;
elseif(_tcscmp(BayerTypeChar, _T("GBRG")) == 0)
CFType = GBRG;
elseif(_tcscmp(BayerTypeChar, _T("GRBG")) == 0)
CFType = GRBG;
rBuffer = (PUSHORT)malloc(sizeof(PUSHORT)*qImageBytes); //r
g1Buffer = (PUSHORT)malloc(sizeof(PUSHORT)*qImageBytes); //g1
g2Buffer = (PUSHORT)malloc(sizeof(PUSHORT)*qImageBytes); //g2
ggBuffer = (PUSHORT)malloc(sizeof(PUSHORT)*qImageBytes); //gg
bBuffer = (PUSHORT)malloc(sizeof(PUSHORT)*qImageBytes); //b
//Raw8Buffer = (PUCHAR)malloc(sizeof(PUCHAR)*qImageBytes*4);
BitMapImgBuffer=(PUCHAR)malloc(sizeof(PUCHAR)*qImageBytes*4*3);
/*
* Lex**: This is to get the five ROI
*/
ImgSize.cx =videotype.Width ;
ImgSize.cy = videotype.Height ;
MTF_STEP_RECT[0].left = GetPrivateProfileInt(szSectionName,_T("MTF_TLV_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[0].top = GetPrivateProfileInt(szSectionName,_T("MTF_TLV_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[0].right = GetPrivateProfileInt(szSectionName,_T("MTF_TLV_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[0].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_TLV_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[1].left = GetPrivateProfileInt(szSectionName,_T("MTF_TRV_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[1].top = GetPrivateProfileInt(szSectionName,_T("MTF_TRV_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[1].right = GetPrivateProfileInt(szSectionName,_T("MTF_TRV_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[1].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_TRV_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[2].left = GetPrivateProfileInt(szSectionName,_T("MTF_C_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[2].top = GetPrivateProfileInt(szSectionName,_T("MTF_C_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[2].right = GetPrivateProfileInt(szSectionName,_T("MTF_C_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[2].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_C_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[3].left = GetPrivateProfileInt(szSectionName,_T("MTF_BLV_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[3].top = GetPrivateProfileInt(szSectionName,_T("MTF_BLV_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[3].right = GetPrivateProfileInt(szSectionName,_T("MTF_BLV_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[3].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_BLV_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[4].left = GetPrivateProfileInt(szSectionName,_T("MTF_BRV_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[4].top = GetPrivateProfileInt(szSectionName,_T("MTF_BRV_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[4].right = GetPrivateProfileInt(szSectionName,_T("MTF_BRV_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[4].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_BRV_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[5].left = GetPrivateProfileInt(szSectionName,_T("MTF_TLH_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[5].top = GetPrivateProfileInt(szSectionName,_T("MTF_TLH_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[5].right = GetPrivateProfileInt(szSectionName,_T("MTF_TLH_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[5].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_TLH_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[6].left = GetPrivateProfileInt(szSectionName,_T("MTF_TRH_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[6].top = GetPrivateProfileInt(szSectionName,_T("MTF_TRH_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[6].right = GetPrivateProfileInt(szSectionName,_T("MTF_TRH_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[6].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_TRH_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[7].left = GetPrivateProfileInt(szSectionName,_T("MTF_CLV_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[7].top = GetPrivateProfileInt(szSectionName,_T("MTF_CLV_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[7].right = GetPrivateProfileInt(szSectionName,_T("MTF_CLV_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[7].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_CLV_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[8].left = GetPrivateProfileInt(szSectionName,_T("MTF_CLH_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[8].top = GetPrivateProfileInt(szSectionName,_T("MTF_CLH_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[8].right = GetPrivateProfileInt(szSectionName,_T("MTF_CLH_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[8].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_CLH_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[9].left = GetPrivateProfileInt(szSectionName,_T("MTF_CRV_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[9].top = GetPrivateProfileInt(szSectionName,_T("MTF_CRV_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[9].right = GetPrivateProfileInt(szSectionName,_T("MTF_CRV_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[9].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_CRV_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[10].left = GetPrivateProfileInt(szSectionName,_T("MTF_CRH_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[10].top = GetPrivateProfileInt(szSectionName,_T("MTF_CRH_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[10].right = GetPrivateProfileInt(szSectionName,_T("MTF_CRH_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[10].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_CRH_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[11].left = GetPrivateProfileInt(szSectionName,_T("MTF_BLH_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[11].top = GetPrivateProfileInt(szSectionName,_T("MTF_BLH_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[11].right = GetPrivateProfileInt(szSectionName,_T("MTF_BLH_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[11].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_BLH_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[12].left = GetPrivateProfileInt(szSectionName,_T("MTF_BRH_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[12].top = GetPrivateProfileInt(szSectionName,_T("MTF_BRH_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[12].right = GetPrivateProfileInt(szSectionName,_T("MTF_BRH_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[12].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_BRH_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[13].left = GetPrivateProfileInt(szSectionName,_T("MTF_TL_FIELD8_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[13].top = GetPrivateProfileInt(szSectionName,_T("MTF_TL_FIELD8_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[13].right = GetPrivateProfileInt(szSectionName,_T("MTF_TL_FIELD8_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[13].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_TL_FIELD8_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[14].left = GetPrivateProfileInt(szSectionName,_T("MTF_TR_FIELD8_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[14].top = GetPrivateProfileInt(szSectionName,_T("MTF_TR_FIELD8_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[14].right = GetPrivateProfileInt(szSectionName,_T("MTF_TR_FIELD8_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[14].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_TR_FIELD8_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[15].left = GetPrivateProfileInt(szSectionName,_T("MTF_BL_FIELD8_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[15].top = GetPrivateProfileInt(szSectionName,_T("MTF_BL_FIELD8_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[15].right = GetPrivateProfileInt(szSectionName,_T("MTF_BL_FIELD8_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[15].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_BL_FIELD8_TEST_RECT_BOTTOM"),0, szIniFilePath);
MTF_STEP_RECT[16].left = GetPrivateProfileInt(szSectionName,_T("MTF_BR_FIELD8_TEST_RECT_LEFT"),0, szIniFilePath);
MTF_STEP_RECT[16].top = GetPrivateProfileInt(szSectionName,_T("MTF_BR_FIELD8_TEST_RECT_TOP"),0, szIniFilePath);
MTF_STEP_RECT[16].right = GetPrivateProfileInt(szSectionName,_T("MTF_BR_FIELD8_TEST_RECT_RIGHT"),0, szIniFilePath);
MTF_STEP_RECT[16].bottom = GetPrivateProfileInt(szSectionName,_T("MTF_BR_FIELD8_TEST_RECT_BOTTOM"),0, szIniFilePath);
/*
* This is to get Specification
*/
TCHARtcSpec[256] ;
swprintf_s(tcSpec, _T("%s_Spec"), szSectionName);
GetPrivateProfileString(tcSpec,_T("STD_FAR_TL_8F_Spec"),_T("NULL"),tcSTDFar_TL_8F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_TR_8F_Spec"),_T("NULL"),tcSTDFar_TR_8F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_TL_V_75F_Spec"),_T("NULL"),tcSTDFar_TL_V_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_TL_H_75F_Spec"),_T("NULL"),tcSTDFar_TL_H_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_TR_V_75F_Spec"),_T("NULL"),tcSTDFar_TR_V_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_TR_H_75F_Spec"),_T("NULL"),tcSTDFar_TR_H_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_CC_Spec"),_T("NULL"),tcSTDFar_CC_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_CL_V_3F_Spec"),_T("NULL"),tcSTDFar_CL_V_3F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_CL_H_3F_Spec"),_T("NULL"),tcSTDFar_CL_H_3F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_CR_V_3F_Spec"),_T("NULL"),tcSTDFar_CR_V_3F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_CR_H_3F_Spec"),_T("NULL"),tcSTDFar_CR_H_3F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_BL_V_75F_Spec"),_T("NULL"),tcSTDFar_BL_V_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_BL_H_75F_Spec"),_T("NULL"),tcSTDFar_BL_H_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_BR_V_75F_Spec"),_T("NULL"),tcSTDFar_BR_V_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_BR_H_75F_Spec"),_T("NULL"),tcSTDFar_BR_H_75F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_BL_8F_Spec"),_T("NULL"),tcSTDFar_BL_8F_MTF,10,szIniFilePath);
GetPrivateProfileString(tcSpec,_T("STD_FAR_BR_8F_Spec"),_T("NULL"),tcSTDFar_BR_8F_MTF,10,szIniFilePath);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_TL_8F_MTF, wcslen(tcSTDFar_TL_8F_MTF));
STD_FAR_TL_8F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_TR_8F_MTF, wcslen(tcSTDFar_TR_8F_MTF));
STD_FAR_TR_8F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_TL_V_75F_MTF, wcslen(tcSTDFar_TL_V_75F_MTF));
STD_FAR_TL_V_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_TL_H_75F_MTF, wcslen(tcSTDFar_TL_H_75F_MTF));
STD_FAR_TL_H_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_TR_V_75F_MTF, wcslen(tcSTDFar_TR_V_75F_MTF));
STD_FAR_TR_V_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_TR_H_75F_MTF, wcslen(tcSTDFar_TR_H_75F_MTF));
STD_FAR_TR_H_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_CC_MTF, wcslen(tcSTDFar_CC_MTF));
STD_FAR_CC_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_CL_V_3F_MTF, wcslen(tcSTDFar_CL_V_3F_MTF));
STD_FAR_CL_V_3F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_CL_H_3F_MTF, wcslen(tcSTDFar_CL_H_3F_MTF));
STD_FAR_CL_H_3F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_CR_V_3F_MTF, wcslen(tcSTDFar_CR_V_3F_MTF));
STD_FAR_CR_V_3F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_CR_H_3F_MTF, wcslen(tcSTDFar_CR_H_3F_MTF));
STD_FAR_CR_H_3F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_BL_V_75F_MTF, wcslen(tcSTDFar_BL_V_75F_MTF));
STD_FAR_BL_V_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_BL_H_75F_MTF, wcslen(tcSTDFar_BL_H_75F_MTF));
STD_FAR_BL_H_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_BL_H_75F_MTF, wcslen(tcSTDFar_BL_H_75F_MTF));
STD_FAR_BL_H_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_BR_V_75F_MTF, wcslen(tcSTDFar_BR_V_75F_MTF));
STD_FAR_BR_V_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_BR_H_75F_MTF, wcslen(tcSTDFar_BR_H_75F_MTF));
STD_FAR_BR_H_75F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_BL_8F_MTF, wcslen(tcSTDFar_BL_8F_MTF));
STD_FAR_BL_8F_Spec = atof(chTmp);
ZeroMemory(chTmp, sizeof(char) * 10);
wcstombs(chTmp, tcSTDFar_BR_8F_MTF, wcslen(tcSTDFar_BR_8F_MTF));
STD_FAR_BR_8F_Spec = atof(chTmp);
STD_STEP_MTFVALUE[0] = STD_FAR_TL_V_75F_Spec;
STD_STEP_MTFVALUE[1] = STD_FAR_TR_V_75F_Spec;
STD_STEP_MTFVALUE[2] = STD_FAR_CC_Spec;
STD_STEP_MTFVALUE[3] = STD_FAR_BL_V_75F_Spec;
STD_STEP_MTFVALUE[4] = STD_FAR_BR_V_75F_Spec;
STD_STEP_MTFVALUE[5] = STD_FAR_TL_H_75F_Spec;
STD_STEP_MTFVALUE[6] = STD_FAR_TR_H_75F_Spec;
STD_STEP_MTFVALUE[7] = STD_FAR_CL_V_3F_Spec;
STD_STEP_MTFVALUE[8] = STD_FAR_CL_H_3F_Spec;
STD_STEP_MTFVALUE[9] = STD_FAR_CR_V_3F_Spec;
STD_STEP_MTFVALUE[10] = STD_FAR_CR_H_3F_Spec;
STD_STEP_MTFVALUE[11] = STD_FAR_BL_H_75F_Spec;
STD_STEP_MTFVALUE[12] = STD_FAR_BR_H_75F_Spec;
STD_STEP_MTFVALUE[13] = STD_FAR_TL_8F_Spec;
STD_STEP_MTFVALUE[14] = STD_FAR_TR_8F_Spec;
STD_STEP_MTFVALUE[15] = STD_FAR_BL_8F_Spec;
STD_STEP_MTFVALUE[16] = STD_FAR_BR_8F_Spec;
if (ColorChannelSel != 3)
{
cf.SplitColor_RAW10(ImgSize, lpDibBits, rBuffer, g1Buffer, g2Buffer,bBuffer, CFType);
}
cf.CheckImgBuffer(ColorChannelSel,BMP_IDX,lpDibBits,rBuffer,g1Buffer,g2Buffer,ggBuffer,bBuffer,BitMapImgBuffer,videotype.Width,videotype.Height,CFType);
if (state_flag_Far_ScanStep == 0)
{
//跑
ScanIndex = 1; //掃描到第幾層
::ZeroMemory(DacValue,sizeof(DacValue));
::ZeroMemory(MTF_Curve_STEP,sizeof(MTF_Curve_STEP));
::ZeroMemory(MTFValue_STEP,sizeof(MTFValue_STEP));
::ZeroMemory(StepBegin,sizeof(StepBegin));
::ZeroMemory(StepEnd,sizeof(StepEnd));
// LET VCM GO TO BEGIN POINT TO START TEST
g_DAC_Step = MTF_DAC_BEGIN_FAR;
Vcm_Control(g_DAC_Step,VCMSlaveAddr);
Sleep(100);
state_flag_Far_ScanStep = 1;
// if(ScanIndex == 1)
// {
AFStart = MTF_DAC_BEGIN_FAR;
AFEnd = MTF_DAC_END_FAR;
DAC_GAP = ScanGap[0];
// }
}// end of read data
elseif (state_flag_Far_ScanStep == 1)
{
CStringAnsStr_MTF = _T("");
CStringDacStr_MTF = _T("");
if(ScanIndex == 2 &&ModeChange)
{
ModeChange = false;
AFStart = DAC_pre2-ScanRange;
AFEnd = DAC_pre1+ScanRange;
DAC_GAP = ScanGap[1];
}elseif(ScanIndex>ScanCount) //jump out
{
boolSpecFlag = false;
//get ResultDAC
for (i = FocusStep ;i>0;i--)
{
SpecFlag = true;
intblockNum = 0;
for(blockNum = 0; blockNum<17; blockNum++) //left
{
if (MTF_Curve_STEP[blockNum][i] <STD_STEP_MTFVALUE[blockNum])
{
SpecFlag = false;
}
}
if (SpecFlag)
{
ResultDAC = DacValue[i];
ResultStep = i;
break;
}
if ((2*FocusStep - i) <= StepEnd[2])
{
SpecFlag = true;
for(blockNum = 0; blockNum<17; blockNum++)
{
if(MTF_Curve_STEP[blockNum][2*FocusStep - i] <STD_STEP_MTFVALUE[blockNum])
{
SpecFlag = false;
}
}
if (SpecFlag)
{
ResultDAC = DacValue[2*FocusStep - i];
ResultStep = 2*FocusStep - i;
break;
}
}
}
Vcm_Control(FocusDAC,VCMSlaveAddr);
Sleep(100);
state_flag_Far_ScanStep = 2;
}
//only change AFStartAFEndgap , run different scan method
if(g_DAC_Step>= AFStart&&g_DAC_Step<= AFEnd)
{
// CALCULATE MTF VALUE
for(i=0; i<17; i++)
{
if ( ColorChannelSel == 0 )
{
MTF_Curve_STEP[i][StepNum] = GetMTFDataOneChannel_RAW10_QSort(MTF_STEP_RECT[i], rBuffer, videotype.Width, videotype.Height,MTFTHFloat) ;
}
elseif ( ColorChannelSel == 1 )
{
MTF_Curve_STEP[i][StepNum] = GetMTFDataOneChannel_RAW10_QSort(MTF_STEP_RECT[i], ggBuffer, videotype.Width, videotype.Height,MTFTHFloat) ;
}
elseif ( ColorChannelSel == 2 )
{
MTF_Curve_STEP[i][StepNum] = GetMTFDataOneChannel_RAW10_QSort(MTF_STEP_RECT[i], bBuffer, videotype.Width, videotype.Height,MTFTHFloat) ;
}
else//if ( CHANNEL_SELECT == eYChannel )
{
MTF_Curve_STEP[i][StepNum] = GetMTFData(BitMapImgBuffer,MTF_STEP_RECT[i], videotype.Width, videotype.Height, MTFTHFloat, RGB_BytesPerPixel) ; // Original Y-MTF
}
//MTFValue_STEP[i] = MTF_Curve_STEP[i][StepNum] ;
if (g_DAC_Step>AFStart + DAC_GAP*2)
{
MTF_pre0[i] = MTF_Curve_STEP[i][StepNum];
MTF_pre1[i] = MTF_Curve_STEP[i][StepNum - 1];
MTF_pre2[i] = MTF_Curve_STEP[i][StepNum - 2];
}
cf.DrawDoubleOnUI(g_hdcWhale, g_DAC_Step, (MTF_STEP_RECT[i].left+30), (MTF_STEP_RECT[i].top+20), videotype.Width, videotype.Height);
cf.DrawDoubleOnUI(g_hdcWhale, (double)MTF_Curve_STEP[i][StepNum], (MTF_STEP_RECT[i].left+30), (MTF_STEP_RECT[i].top+90),videotype.Width, videotype.Height);
cf.DrawingRAWRect10(ImgSize, lpDibBits, MTF_STEP_RECT[i], 8,255);
}
DacValue[StepNum] = g_DAC_Step;
intIterateStart = 0;
intIterateEnd = 0;
if (ScanMode == 1)
{
IterateStart = 0;
IterateEnd = 16;
}
else
{
IterateStart = 2;
IterateEnd = 2;
}
for (i=IterateStart;i<=IterateEnd;i++)
{
if ( g_DAC_Step> (AFStart + DAC_GAP*2) &&MTF_pre0[i]!=0 &&MTF_pre1[i]!=0 &&MTF_pre2[i]!=0
&&(MTF_pre1[i]-MTF_pre0[i]) >ScanSub[ScanIndex-1] &&(MTF_pre2[i]-MTF_pre1[i]) >ScanSub[ScanIndex-1] && !ModeChange) //MTF_DAC_GAP_SUB = 0.01
{
//MTF_DAC_GAP_FAR = 5;
DAC_pre0=g_DAC_Step;
DAC_pre1=g_DAC_Step-DAC_GAP;
DAC_pre2=g_DAC_Step-DAC_GAP*2;
StepEnd[ScanIndex] = StepNum;
FocusDAC = DAC_pre2;
FocusStep = StepNum - 2;
g_DAC_Step = DAC_pre2-ScanRange;
StepNum++;
Vcm_Control(g_DAC_Step,VCMSlaveAddr);
Sleep(100);
if (ThroughFocus != 1)
{
ScanIndex++;
ModeChange = true;
}
StepBegin[ScanIndex] = StepNum;
break;
}
}
if (!ModeChange)
{
g_DAC_Step = g_DAC_Step + DAC_GAP; //MTF_DAC_GAP_FAR = 20
StepNum++;
Vcm_Control(g_DAC_Step,VCMSlaveAddr);
Sleep(100);
}
}else
{
ScanIndex = ScanCount+1; //jump out
}
}
elseif (state_flag_Far_ScanStep == 2)
{
intSaveLog = GetPrivateProfileInt(szSectionName,_T("SaveLog"),-1,szIniFilePath);
FocusDAC = FocusDAC - FocusOffset;
for(i=0; i<17; i++)
{
MTFValue_STEP[i] = MTF_Curve_STEP[i][ResultStep];
}
for (i = 0;i<17;i++)
{
if ( (FocusDAC>= DAC_Min_Spec) && (FocusDAC<= DAC_Max_Spec) &&
(MTFValue_STEP[i] >= STD_STEP_MTFVALUE[i]) )
{
result_flag_MTF_FAR = true;
}else
{
result_flag_MTF_FAR = false;
break;
}
}
if (SaveLog)
{
charWhalePath[1024] ; ::ZeroMemory(WhalePath, sizeof(WhalePath));
charcSerialNum[1024] ; ::ZeroMemory(cSerialNum, sizeof(cSerialNum)) ;
sprintf_s(WhalePath, "%s\\Whale.dat",cf.GetModulePathA());
GetPrivateProfileStringA("TesterData","Label","0",cSerialNum,32,WhalePath);
SaveMTFCurve(cSerialNum,DacValue,MTF_Curve_STEP,StepNum);
}
*(Result+ nIdxRst++) = MTFValue_STEP[0];
*(Result+ nIdxRst++) = MTFValue_STEP[5];
*(Result+ nIdxRst++) = MTFValue_STEP[1];
*(Result+ nIdxRst++) = MTFValue_STEP[6];
*(Result+ nIdxRst++) = MTFValue_STEP[2];
*(Result+ nIdxRst++) = MTFValue_STEP[7];
*(Result+ nIdxRst++) = MTFValue_STEP[8];
*(Result+ nIdxRst++) = MTFValue_STEP[9];
*(Result+ nIdxRst++) = MTFValue_STEP[10];
*(Result+ nIdxRst++) = MTFValue_STEP[3];
*(Result+ nIdxRst++) = MTFValue_STEP[11];
*(Result+ nIdxRst++) = MTFValue_STEP[4];
*(Result+ nIdxRst++) = MTFValue_STEP[12];
*(Result+ nIdxRst++) = MTFValue_STEP[13];
*(Result+ nIdxRst++) = MTFValue_STEP[14];
*(Result+ nIdxRst++) = MTFValue_STEP[15];
*(Result+ nIdxRst++) = MTFValue_STEP[16];
*(Result+ nIdxRst++) = float(FocusDAC); // 下述二項其中之一,如果gnUpCornerDAC存在:nFoundCornerDAC = gnUpCornerDAC
*(Result+ nIdxRst++) = float(ResultDAC);
endFlag = TRUE;
state_flag_Far_StartCurrent = 0;
FocusDAC = 0;
DAC_pre0 = 0;
DAC_pre1 = 0;
DAC_pre2 = 0;
StepNum = 0;
FocusStep = 0;
ModeChange = false;
//测试完毕进行参数复位
ScanIndex = 1; //下一次从第一层继续扫描
AFStart = 0;
AFEnd = 999;
}
*(AllocateReturnResult+ nIdxRst++) = result_flag_MTF_FAR;
*BackResult = AllocateReturnResult;
m_nIdxRst = nIdxRst - 1 ;
if(rBuffer)
free(rBuffer);
if(g1Buffer)
free(g1Buffer);
if(g2Buffer)
free(g2Buffer);
if(ggBuffer)
free(ggBuffer);
if(bBuffer)
free(bBuffer);
// if(Raw8Buffer)
// free(Raw8Buffer);
if(BitMapImgBuffer)
free(BitMapImgBuffer);
returnendFlag;
}
本发明实施例所提供的改进的自动对焦爬山搜索算法,不需要再频繁的反转马达驱动镜头来回搜寻调焦最佳位置所带来的镜头来回晃动,使对焦容错率降低,并且大大降低了远离最佳调焦位置的区域内极值对调焦结果的影响,保证了对焦准确性。
以上所述仅为本发明的优选实施例而已,并不用于限制本发明,对于本领域的技术人员来说,本发明可以有各种更改和变化。凡在本发明的精神和原则之内,所作的任何修改、等同替换、改进等,均应包含在本发明的保护范围之内。

Claims (3)

1.一种改进的自动对焦爬山搜索算法,包括以下步骤:
步骤一:预设一马达搜索范围,采用固定步长驱动马达得到该搜索范围内MTF的最大值和对应的马达位置;
步骤二:驱动马达到步骤一中MTF最大值的前一个位置,以该位置为起点,减小马达步长到精度要求并重新进行搜索,得到MTF最大值和相应马达位置;
步骤三:将马达推动到步骤二MTF最大值对应的马达位置,此位置即为对焦最佳位置。
2.根据权利要求1所述的一种改进的自动对焦爬山搜索算法,其特征在于,步骤一中,马达被设置在一个预设位置,以一个固定步长驱动镜头;马达每带动镜头运动一步,计算并保留相应MTF数值和马达所在位置,当马达运动次数大于两次,则记录当下MTF数据与前一次MTF数据两者之间较大的一个的数值和马达位置;以此类推当马达走完全程到达结束位置时,会得到MTF最大值和对应的马达位置。
3.根据权利要求1或2所述的一种改进的自动对焦爬山搜索算法,其特征在于,步骤二中,以步骤一中MTF最大值的前一个位置为新的起点,减小马达驱动步长到精度要求,记录马达驱动镜头每一步相应的MTF数值和马达位置,当MTF数值开始减小且连续减小两次时,执行步骤三。
CN201910774916.5A 2019-08-21 2019-08-21 一种改进的自动对焦爬山搜索算法 Pending CN110855878A (zh)

Priority Applications (1)

Application Number Priority Date Filing Date Title
CN201910774916.5A CN110855878A (zh) 2019-08-21 2019-08-21 一种改进的自动对焦爬山搜索算法

Applications Claiming Priority (1)

Application Number Priority Date Filing Date Title
CN201910774916.5A CN110855878A (zh) 2019-08-21 2019-08-21 一种改进的自动对焦爬山搜索算法

Publications (1)

Publication Number Publication Date
CN110855878A true CN110855878A (zh) 2020-02-28

Family

ID=69594860

Family Applications (1)

Application Number Title Priority Date Filing Date
CN201910774916.5A Pending CN110855878A (zh) 2019-08-21 2019-08-21 一种改进的自动对焦爬山搜索算法

Country Status (1)

Country Link
CN (1) CN110855878A (zh)

Cited By (1)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111711759A (zh) * 2020-06-29 2020-09-25 重庆紫光华山智安科技有限公司 一种聚焦方法、装置、存储介质及电子设备

Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20140368724A1 (en) * 2013-06-12 2014-12-18 Nvidia Corporation Methods for enhancing camera focusing performance using camera orientation
CN105578029A (zh) * 2015-09-01 2016-05-11 闽南师范大学 一种多尺度变步长的自动对焦搜索算法据传输装置和方法
CN106707462A (zh) * 2015-07-30 2017-05-24 炬芯(珠海)科技有限公司 一种自动对焦的方法及装置
CN109696788A (zh) * 2019-01-08 2019-04-30 武汉精立电子技术有限公司 一种基于显示面板的快速自动对焦方法

Patent Citations (4)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
US20140368724A1 (en) * 2013-06-12 2014-12-18 Nvidia Corporation Methods for enhancing camera focusing performance using camera orientation
CN106707462A (zh) * 2015-07-30 2017-05-24 炬芯(珠海)科技有限公司 一种自动对焦的方法及装置
CN105578029A (zh) * 2015-09-01 2016-05-11 闽南师范大学 一种多尺度变步长的自动对焦搜索算法据传输装置和方法
CN109696788A (zh) * 2019-01-08 2019-04-30 武汉精立电子技术有限公司 一种基于显示面板的快速自动对焦方法

Cited By (2)

* Cited by examiner, † Cited by third party
Publication number Priority date Publication date Assignee Title
CN111711759A (zh) * 2020-06-29 2020-09-25 重庆紫光华山智安科技有限公司 一种聚焦方法、装置、存储介质及电子设备
CN111711759B (zh) * 2020-06-29 2022-02-01 重庆紫光华山智安科技有限公司 一种聚焦方法、装置、存储介质及电子设备

Similar Documents

Publication Publication Date Title
CN101494737B (zh) 一种一体化摄像机装置及自适应自动聚焦方法
EP3236648B1 (en) Focusing for point light source scene
US7738024B2 (en) Image processing method, imaging apparatus, and storage medium storing control program of image processing method executable by computer
US7801432B2 (en) Imaging apparatus and method for controlling the same
CN110381261B (zh) 聚焦方法、装置、计算机可读存储介质及电子设备
CN1856021A (zh) 摄像装置及焦点调节方法
US8004597B2 (en) Focusing control apparatus and method
CN101031033A (zh) 摄像装置以及摄像方法
CN1511412A (zh) 自动聚焦设备、电子照相机和自动聚焦方法
CN112601008B (zh) 一种摄像头切换方法、终端、装置及计算机可读存储介质
CN112203012B (zh) 一种图像清晰度计算方法、自动聚焦方法及系统
US20200106948A1 (en) Focusing method, computer readable storage medium and mobile phone
CN109151328B (zh) 镜头对焦方法、装置及变焦镜头
TWI524107B (zh) 自動對焦方法
CN110855878A (zh) 一种改进的自动对焦爬山搜索算法
CN109714581B (zh) 投影机的自动对焦方法
CN113923347A (zh) 自动对焦方法、装置、拍摄终端及计算机可读存储介质
CN111556247A (zh) Dcc的获取方法、对焦方法及系统、摄像模组及终端
US7844172B1 (en) Adaptive autofocus lens positioning
CN111199536B (zh) 一种聚焦评价方法及其装置
CN111432129B (zh) 一种基于阈值法和局部最大值的自动对焦爬山搜索方法
CN1886759A (zh) 对视频信号中的局部视觉时空细节的检测
CN111161221B (zh) 一种聚焦评价方法、装置及系统
US8189012B2 (en) Digital image composition method
CN109151319B (zh) 一种多标记点目标物标记点对焦顺序的处理方法及装置

Legal Events

Date Code Title Description
PB01 Publication
PB01 Publication
SE01 Entry into force of request for substantive examination
SE01 Entry into force of request for substantive examination
WD01 Invention patent application deemed withdrawn after publication

Application publication date: 20200228

WD01 Invention patent application deemed withdrawn after publication