⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 un_autocameracontrol.cpp

📁 用于DSP下摄像机的图像抓取、图像处理和传输、以及与上位机TCP/IP通信的工程文件。基于Texas Instruments Code Composer Studio实现。
💻 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 + -