📄 whitebalancer.cpp
字号:
//-----------------------------------------------------------------------------
// (c) 2002 by Basler Vision Technologies
// Section: Vision Components
// Project: BCAM
// $Header: WhiteBalancer.cpp, 4, 02.10.2002 14:31:30, Nebelung, H.$
//-----------------------------------------------------------------------------
/**
\file WhiteBalancer.cpp
*
\brief Implementation of the CWhiteBalancer class.
*/
//-----------------------------------------------------------------------------
#include "stdafx.h"
#include "WhiteBalancer.h"
#include "float.h"
const int CWhiteBalancer::MAX_ITERATIONS = 24;
const double CWhiteBalancer::CBisection::THRESH_HIT = 0.5;
const double CWhiteBalancer::CBisection::THRESH_ACCEPT = 4.0;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CWhiteBalancer::CWhiteBalancer(CBcam& device)
: m_Camera(device),
m_fConverged(true),
m_Min(0),
m_Max(0),
m_UB(0),
m_VR(0)
{
}
CWhiteBalancer::~CWhiteBalancer()
{
}
void CWhiteBalancer::Init(int ub, int vr)
{
m_nIterations = 0;
m_fConverged = false;
DCSVideoFormat videoFormat;
DCSVideoMode videoMode;
m_Camera.GetVideoMode(&videoFormat, &videoMode, NULL);
DCSColorCode colorCode = videoFormat == DCS_Format7 ?
m_Camera.FormatSeven[videoMode].ColorCoding() : BcamUtility::ColorCode(videoFormat, videoMode);
m_fBayerImage = colorCode == DCSColor_Mono8;
if ( ! m_fBayerImage )
{
assert(m_Camera.WhiteBalance.IsSupported());
m_Min = m_Camera.WhiteBalance.Raw.Min();
m_Max = m_Camera.WhiteBalance.Raw.Max();
}
else
{
m_Min = 50;
m_Max = 1000;
}
m_UB = ub;
m_VR = vr;
m_bestUB = ub;
m_bestVR = vr;
m_minError = DBL_MAX;
m_VBisection.Init(m_Min, m_Max);
m_UBisection.Init(m_Min, m_Max);
}
bool CWhiteBalancer::Next(PBYTE imgBuffer, const CSize& imgSize)
{
if ( m_fConverged )
return true;
double meanr, meang, meanb;
GetMeans(imgBuffer, imgSize, meanr, meang, meanb);
double deltar = meanr - meang;
double deltab = meanb - meang;
double error = deltar * deltar + deltab * deltab;
ATLTRACE("vr: %d, ub: %d error: %f\n", m_VR, m_UB, error);
if ( error < m_minError )
{
m_minError = error;
m_bestUB = m_UB;
m_bestVR = m_VR;
}
long oldUB = m_UB;
long oldVR = m_VR;
if ( m_fBayerImage )
{
m_UB = ( m_UB / 100.0 ) * ( meang / meanb ) * 100 + 0.5;
if ( m_UB < m_Min ) m_UB = m_Min;
if ( m_UB > m_Max ) m_UB = m_Max;
m_VR = ( m_VR / 100.0 ) * ( meang / meanr ) * 100 + 0.5;
if ( m_VR < m_Min ) m_VR = m_Min;
if ( m_VR > m_Max ) m_VR = m_Max;
m_fConverged = ( m_nIterations++ >= MAX_ITERATIONS || oldUB == m_UB && oldVR == m_VR ) ;
}
else
{
if ( m_nIterations == 0 )
{
m_UB = 0.5 * ( m_Min + m_Max );
m_VR = 0.5 * ( m_Min + m_Max );
m_nIterations++;
return false;
}
boolean fConvergedVR = m_VBisection.Next(m_VR, meanr, meang, m_VR);
boolean fConvergedUB = m_UBisection.Next(m_UB, meanb, meang, m_UB);
m_fConverged = ( ( fConvergedUB && fConvergedVR) || m_nIterations++ >= MAX_ITERATIONS );
}
if ( m_fConverged )
{
// If there was an iteration yielding a better error, take these values instead
if ( m_minError < error )
{
m_UB = m_bestUB;
m_VR = m_bestVR;
ATLTRACE("Corrected: m_UB %d, m_VR %d\n", m_UB, m_VR);
}
}
return m_fConverged;
}
void CWhiteBalancer::GetMeans(PBYTE imgBuffer, const CSize& imgSize, double& meanr, double& meang, double& meanb )
{
double sumr = 0;
double sumb = 0;
double sumg = 0;
RGBTRIPLE* pRGB = (RGBTRIPLE*) imgBuffer;
for ( int j = 0; j < imgSize.cy; ++j )
for ( int i = 0; i < imgSize.cx; ++i )
{
sumr += pRGB->rgbtRed;
sumb += pRGB->rgbtBlue;
sumg += pRGB->rgbtGreen;
pRGB++;
}
long nPixels = imgSize.cx * imgSize.cy;
meanr = sumr / nPixels;
meang = sumg / nPixels;
meanb = sumb / nPixels;
ATLTRACE("meanr %f, meang %f, meanb %f\n", meanr, meang, meanb);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -