📄 un_autocameracontrol.cpp
字号:
/******************************************************************************
COPYRIGHTS (C), 2008, UNIC Technologies, Inc.
FILE NAME: UN_AutoCameraControl.cpp
AUTHOR: Steve Tang
COMMENTS: auto exposure control
HISTORY: 11-29-2008, v0.5, first version
12-01-2008, v0.6, added single step AGC, AEC functions
*******************************************************************************/
#include "UN_AutoCameraControl.h"
#include <stdlib.h>
#include <math.h>
static int max(int a, int b)
{
if(a > b)
{
return a;
}
else
{
return b;
}
}
static int min(int a, int b)
{
if(a < b)
{
return a;
}
else
{
return b;
}
}
/************************************************************************/
/* Some definitions */
/************************************************************************/
/*macro for converting RGB-triple to gray level*/
#ifndef UAGE_RGB2GRAY
#define UAGE_RGB2GRAY(r,g,b) (((b)*117 + (g)*601 + (r)*306) >> 10)
#endif
/*constant related to characteristics of AGC amplifier*/
#define UAGE_GAIN_CONST 0.0351f
//--------------------------------------------------------------------
// NAME: UAGE_AutoGain
// PARAMS: stParam - parameters
// nBrightness - image mean brightness
// nGain - gain
// RETURN:
// FUNCTION: automatic gain control
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
void UAGE_AutoGain(UAGE_PARAM &stParam, int nBrightness, unsigned int &nGain)
{
int nGainStep;
nGainStep = max(1, min(stParam.nMaxGain - stParam.nMinGain, stParam.nGainStep));
if (nBrightness + stParam.nBrightnessTh < stParam.nTargetBrightness)
{
nGain += nGainStep;
nGain = min(stParam.nMaxGain, nGain);
}
else if (nBrightness - stParam.nBrightnessTh > stParam.nTargetBrightness)
{
nGain -= nGainStep;
nGain = max(stParam.nMinGain, nGain);
}
return;
}
//--------------------------------------------------------------------
// NAME: UAGE_AutoExposure
// PARAMS: stParam - parameters
// nBrightness - image mean brightness
// nExposure - exposure time
// RETURN:
// FUNCTION: automatic exposure control
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
void UAGE_AutoExposure(UAGE_PARAM &stParam, int nBrightness, unsigned int &nExposure)
{
int nExposureStep;
nExposureStep = max(1, min(stParam.nMaxExposure - stParam.nMinExposure, stParam.nExposureStep));
if (nBrightness + stParam.nBrightnessTh < stParam.nTargetBrightness)
{
nExposure += nExposureStep;
nExposure = min(stParam.nMaxExposure, nExposure);
}
else if (nBrightness - stParam.nBrightnessTh > stParam.nTargetBrightness)
{
nExposure -= nExposureStep;
nExposure = max(stParam.nMinExposure, nExposure);
}
return;
}
//--------------------------------------------------------------------
// NAME: AutoExposureAndGain
// PARAMS: stParam - parameters
// nBrightness - image mean brightness
// nGain - gain
// nExposure - exposure time
// RETURN:
// FUNCTION: combined automatic exposure and gain control
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
void UAGE_AutoExposureAndGain(UAGE_PARAM &stParam, int nBrightness, unsigned int &nGain, unsigned int &nExposure)
{
if (nGain > stParam.nMinGain && nExposure != stParam.nMaxExposure)
{
nGain = stParam.nMinGain;
nExposure = stParam.nMaxExposure;
}
else if (nBrightness + stParam.nBrightnessTh < stParam.nTargetBrightness)
{
if (nExposure >= stParam.nMaxExposure)
UAGE_AutoGain(stParam, nBrightness, nGain);
else
UAGE_AutoExposure(stParam, nBrightness, nExposure);
}
else if (nBrightness - stParam.nBrightnessTh > stParam.nTargetBrightness)
{
if (nGain > stParam.nMinGain)
UAGE_AutoGain(stParam, nBrightness, nGain);
else
UAGE_AutoExposure(stParam, nBrightness, nExposure);
}
return;
}
//--------------------------------------------------------------------
// NAME: UAGE_AutoGain_Fast
// PARAMS: stParam - parameters
// nBrightness - image mean brightness
// nGain - gain
// RETURN:
// FUNCTION: automatic gain control
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
void UAGE_AutoGain_Fast(UAGE_PARAM &stParam, int nBrightness, unsigned int &nGain)
{
if (abs(nBrightness - stParam.nTargetBrightness) > stParam.nBrightnessTh)
{
nGain = nGain + 20*log10(float(stParam.nTargetBrightness) / (nBrightness + 1)) / UAGE_GAIN_CONST;
nGain = max(stParam.nMinGain, min(stParam.nMaxGain, nGain));
}
return;
}
//--------------------------------------------------------------------
// NAME: UAGE_AutoExposure
// PARAMS: stParam - parameters
// nBrightness - image mean brightness
// nExposure - exposure time
// RETURN:
// FUNCTION: automatic exposure control
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
void UAGE_AutoExposure_Fast(UAGE_PARAM &stParam, int nBrightness, unsigned int &nExposure)
{
if (abs(nBrightness - stParam.nTargetBrightness) > stParam.nBrightnessTh)
{
nExposure = nExposure * stParam.nTargetBrightness / (nBrightness+1);
nExposure = max(stParam.nMinExposure, min(stParam.nMaxExposure, nExposure));
}
return;
}
//--------------------------------------------------------------------
// NAME: AutoExposureAndGain
// PARAMS: stParam - parameters
// nBrightness - image mean brightness
// nGain - gain
// nExposure - exposure time
// RETURN:
// FUNCTION: combined automatic exposure and gain control
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
void UAGE_AutoExposureAndGain_Fast(UAGE_PARAM &stParam, int nBrightness, unsigned int &nGain, unsigned int &nExposure)
{
//if (abs(nBrightness - stParam.nTargetBrightness) <= stParam.nBrightnessTh)
// return;
//if (nBrightness < stParam.nTargetBrightness) // increase exposure time or gain
//{
// int nMaxShutterBrightness;
// nMaxShutterBrightness = nBrightness * stParam.nMaxExposure / nExposure;
// if (nMaxShutterBrightness >= stParam.nTargetBrightness)
// {
// nExposure = stParam.nTargetBrightness * nExposure / (nBrightness + 1);
// }
// else
// {
// nGain = nGain + 10*log10((float)stParam.nTargetBrightness/nMaxShutterBrightness)/UAGE_GAIN_CONST;
// nExposure = stParam.nMaxExposure;
// }
//}
//else if (nBrightness > stParam.nTargetBrightness) // decrease exposure time or gain
//{
// int nMinGainBrightness;
// nMinGainBrightness = nBrightness * pow(10.0f, UAGE_GAIN_CONST*(stParam.nMinGain - nGain)/10);
// if (nMinGainBrightness <= stParam.nTargetBrightness)
// {
// nGain = nGain + 10*log10((float)stParam.nTargetBrightness/nBrightness)/UAGE_GAIN_CONST;
// }
// else
// {
// nGain = stParam.nMinGain;
// nExposure = nExposure * stParam.nTargetBrightness / (nMinGainBrightness+1);
// }
//}
//nGain = min(stParam.nMaxGain, max(stParam.nMinGain, nGain));
//nExposure = min(stParam.nMaxExposure, max(stParam.nMinExposure, nExposure));
if (nGain > stParam.nMinGain && nExposure != stParam.nMaxExposure)
{
nGain = stParam.nMinGain;
nExposure = stParam.nMaxExposure;
}
else if (nBrightness + stParam.nBrightnessTh < stParam.nTargetBrightness)
{
if (nExposure >= stParam.nMaxExposure)
UAGE_AutoGain_Fast(stParam, nBrightness, nGain);
else
UAGE_AutoExposure_Fast(stParam, nBrightness, nExposure);
}
else if (nBrightness - stParam.nBrightnessTh > stParam.nTargetBrightness)
{
if (nGain > stParam.nMinGain)
UAGE_AutoGain_Fast(stParam, nBrightness, nGain);
else
UAGE_AutoExposure_Fast(stParam, nBrightness, nExposure);
}
return;
}
//--------------------------------------------------------------------
// NAME: UAGE_GetMeanBrightness
// PARAMS: pImgBuf - image buffer
// nImgWidth - image width
// nImgHeight - image height
// nColorMode - image color mode
// nBrightness - image mean brightness
// RETURN: true for success
// FUNCTION: get mean brightness
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
bool UAGE_GetMeanBrightness(unsigned char *pImgBuf, int nImgWidth, int nImgHeight,
UAGE_COLOR_MODE nColorMode, int &nBrightness)
{
if (pImgBuf == NULL || nImgWidth < 1 || nImgHeight < 1)
return false;
int i, j;
int nImgSize = nImgWidth * nImgHeight;
unsigned long nSum = 0;
unsigned long nSumB = 0, nSumR = 0, nSumG = 0;
int nCount = 0;
unsigned char *pTmp;
if (nColorMode == UAGE_COLOR_MODE_GRAY)
{
pTmp = pImgBuf;
nSum = 0;
for (i = 0; i < nImgSize; i++)
nSum += *(pTmp++);
nBrightness = nSum / nImgSize;
return true;
}
else if (nColorMode == UAGE_COLOR_MODE_RGB)
{
pTmp = pImgBuf;
for (i = 0; i < nImgSize; i++)
{
nSumR += *(pTmp++);
nSumG += *(pTmp++);
nSumB += *(pTmp++);
}
nCount = nImgSize;
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_GBGR)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *(pTmp + 1);
nSumG += (*pTmp + *(pTmp + nImgWidth + 1)) >> 1;
nSumR += *(pTmp + nImgWidth);
nCount++;
}
}
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_GRGB)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *(pTmp + nImgWidth);
nSumG += (*pTmp + *(pTmp + nImgWidth + 1)) >> 1;
nSumR += *(pTmp + 1);
nCount++;
}
}
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_RGBG)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *(pTmp + nImgWidth + 1);
nSumG += (*(pTmp + 1) + *(pTmp + nImgWidth)) >> 1;
nSumR += *(pTmp);
nCount++;
}
}
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_BGRG)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *pTmp;
nSumG += (*(pTmp + 1) + *(pTmp + nImgWidth)) >> 1;
nSumR += *(pTmp + nImgWidth + 1);
nCount++;
}
}
}
else if (nColorMode == UAGE_COLOR_MODE_YUYV)
{
pTmp = pImgBuf;
nSum = 0;
for (i = 0; i < nImgSize; i++)
{
nSum += *pTmp;
pTmp += 2;
}
nBrightness = nSum / nImgSize;
return true;
}
else
return false;
nBrightness = UAGE_RGB2GRAY(nSumR/nCount, nSumG/nCount, nSumB/nCount);
return true;
}
//--------------------------------------------------------------------
// NAME: UAGE_GetMeanBrightness
// PARAMS: pImgBuf - image buffer
// nImgWidth - image width
// nImgHeight - image height
// nROIStartX - roi start x
// nROIStartY - roi start y
// nROIWidth - roi width
// nROIHeight - roi height
// nColorMode - image color mode
// nBrightness - image mean brightness
// RETURN: true for success
// FUNCTION: get mean brightness
// AUTHOR: Steve Tang
//---------------------------------------------------------------------
bool UAGE_GetMeanBrightness(unsigned char *pImgBuf, int nImgWidth, int nImgHeight,
int nROIStartX, int nROIStartY, int nROIWidth, int nROIHeight,
UAGE_COLOR_MODE nColorMode, int &nBrightness)
{
if (pImgBuf == NULL || nImgWidth < 1 || nImgHeight < 1)
return false;
int i, j;
int nImgSize = nImgWidth * nImgHeight;
unsigned long nSum = 0;
unsigned long nSumB = 0, nSumR = 0, nSumG = 0;
int nCount = 0;
unsigned char *pTmp;
if (nColorMode == UAGE_COLOR_MODE_GRAY)
{
pTmp = pImgBuf;
nSum = 0;
for (i = 0; i < nImgSize; i++)
nSum += *(pTmp++);
nBrightness = nSum / nImgSize;
return true;
}
else if (nColorMode == UAGE_COLOR_MODE_RGB)
{
pTmp = pImgBuf;
for (i = 0; i < nImgSize; i++)
{
nSumR += *(pTmp++);
nSumG += *(pTmp++);
nSumB += *(pTmp++);
}
nCount = nImgSize;
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_GBGR)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *(pTmp + 1);
nSumG += (*pTmp + *(pTmp + nImgWidth + 1)) >> 1;
nSumR += *(pTmp + nImgWidth);
nCount++;
}
}
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_GRGB)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *(pTmp + nImgWidth);
nSumG += (*pTmp + *(pTmp + nImgWidth + 1)) >> 1;
nSumR += *(pTmp + 1);
nCount++;
}
}
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_RGBG)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *(pTmp + nImgWidth + 1);
nSumG += (*(pTmp + 1) + *(pTmp + nImgWidth)) >> 1;
nSumR += *(pTmp);
nCount++;
}
}
}
else if (nColorMode == UAGE_COLOR_MODE_BAYER_BGRG)
{
for (i = 0; i < nImgHeight; i += 2)
{
pTmp = pImgBuf + i * nImgWidth;
for (j = 0; j < nImgWidth; j += 2, pTmp += 2)
{
nSumB += *pTmp;
nSumG += (*(pTmp + 1) + *(pTmp + nImgWidth)) >> 1;
nSumR += *(pTmp + nImgWidth + 1);
nCount++;
}
}
}
else
return false;
nBrightness = UAGE_RGB2GRAY(nSumR/nCount, nSumG/nCount, nSumB/nCount);
return true;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -