📄 camera.cpp
字号:
m_DisplayThread.SetBuffer(NULL);
m_DisplayThread.WaitUntilIdle();
m_MainFrame.UpdateUI();
if ( error && error != ERROR_DEVICE_REMOVED )
throw BcamException(error, "CCamera::GrabCancel()");
}
//------------------------------------------------------------------------------
// void CCamera::GetFrameRate(double& acquired, double& displayed)
// Author:
//------------------------------------------------------------------------------
/**
* Retrieve actual frame rate
*
* \param acquired
* \param displayed
* \return
*
*/
//------------------------------------------------------------------------------
void CCamera::GetFrameRate(double& acquired, double& displayed)
{
assert ( IsContinuousGrabActive() );
double avg = m_AcquisitionAvg.Avg();
acquired = avg == 0 ? 0.0 : 1.0 / avg;
avg = m_DisplayAvg.Avg();
displayed = avg == 0 ? 0.0 : 1.0 / avg;
m_AcquisitionAvg.Reset();
m_DisplayAvg.Reset();
}
//------------------------------------------------------------------------------
// bool CCamera::ReconfigurationRequest()
// Author:
//------------------------------------------------------------------------------
/**
* To be called before reconfiguring the camera
* Call this function before the camera is to be reparametrized.
* The function will suspend an active grab.
* After configuring the camera call CCamera::ConfigurationChanged to resume the grab.
*
* \return bool
*
* returns true if succeeded
*
*/
//------------------------------------------------------------------------------
bool CCamera::ReconfigurationRequest()
{
ATLTRACE("ReconfigurationReqest()\n");
if ( ! IsGrabActive() )
return true;
CAutoLock<CCriticalSection> lock(m_csAcquisition);
if ( IsSingleGrabActive() || IsAutoWhiteBalanceActive() )
{
// a pending single grab will be terminated
m_State = sIdle;
}
else if ( IsContinuousGrabActive() )
{
m_State = sContinuousGrabSuspended;
ContinuousShot = false; // stop camera
}
else
{
assert ( false && "This point should never be reached" );
}
// cancel pending I/O requests
Cancel();
// tell the display thread to suspend processing of buffers
DWORD result = m_DisplayThread.WaitUntilIdle();
if ( result != 0 )
return false;
// now all buffers are processed and we may free the resources
try
{
if ( IsBandwidthAllocated() )
FreeResources();
}
catch ( BcamException& e )
{
m_MainFrame.ReportError(e);
assert(false);
return false;
}
// now we are ready for a reconfiguration
return true;
}
//------------------------------------------------------------------------------
// void CCamera::ConfigurationChanged()
// Author:
//------------------------------------------------------------------------------
/**
* The client informs the camera object that the reconfiguration is done.
* A suspended grab will be resumed.
*
* \return void
*
*/
//------------------------------------------------------------------------------
void CCamera::ConfigurationChanged()
{
assert ( m_State == sIdle || m_State == sContinuousGrabSuspended );
if ( IsContinuousGrabActive() )
{
CAutoLock<CCriticalSection> lock(m_csAcquisition);
try
{
PrepareContinuousGrab();
m_State = sContinuousGrab;
ContinuousShot = true;
}
catch ( BcamException& e )
{
m_MainFrame.ReportError(e);
GrabCancel();
}
}
}
//------------------------------------------------------------------------------
// void CCamera::Refresh(bool force /* = false*/)
// Author:
//------------------------------------------------------------------------------
/**
* Refresh the cached information. If the video mode, video format etc.
* have changed, clients will be informed
*
* \param force if set to true, the rest will be informed even if the cached
* information has not been changed
* \return
*
* <type Return description here>
*
*/
//------------------------------------------------------------------------------
void CCamera::Refresh(bool force /* = false*/)
{
DCSVideoFormat format;
DCSVideoMode mode;
DCSVideoFrameRate rate;
GetVideoMode(&format, &mode, &rate);
DCSColorCode code = format == DCS_Format7 ? FormatSeven[mode].ColorCoding() : BcamUtility::ColorCode(format, mode);
CSize imageSize = format == DCS_Format7 ? FormatSeven[mode].Size() : BcamUtility::ImageSize(format, mode);
CSize sensorSize = format == DCS_Format7 ? FormatSeven[mode].MaxSize() : BcamUtility::ImageSize(format, mode);
CPoint position = format == DCS_Format7 ? FormatSeven[mode].Position() : CPoint(0,0);
if ( force || m_VideoFormat != format || m_VideoMode != mode || m_SensorSize != sensorSize || m_ImageSize != imageSize || m_Origin != position || m_ColorCode != code )
{
// The configuration of the device has been changed. Update the cache
m_VideoFormat = format;
m_VideoMode = mode;
m_VideoFrameRate = rate;
m_SensorSize = sensorSize;
m_ImageSize = imageSize;
if ( format == DCS_Format7 )
{
CSize aligned(imageSize);
AlignAOI(aligned, mode);
if ( aligned != imageSize )
{
m_ImageSize = aligned;
FormatSeven[mode].Size = aligned;
}
}
m_Origin = position;
m_ColorCode = code;
m_Bpp = BcamUtility::BitsPerPixel(code);
m_fBitmapValid = ! IsContinuousGrabActive() && m_pBitmap != NULL && m_SensorSize == m_pBitmap->GetSensorSize();
m_fIsWhiteBalanceSupported = ( WhiteBalance.IsSupported() && WhiteBalance.IsSupported(inqManual) ) ;
CString strCameraName = Info.ModelName();
// Special treatment for A101fc and A301fc.
// Although these camerase claim to support the white balance feature, the white balance feature is without effect in
// monochrome mode.
if ( m_ColorCode == DCSColor_Mono8 && ( strCameraName.Find(_T("A101fc")) != -1 || strCameraName.Find(_T("A302fc")) != -1 ) )
{
m_fIsWhiteBalanceSupported = false;
}
//inform a child frame that the configuration has changed
if ( m_pChildFrame != NULL )
m_pChildFrame->m_View.ConfigurationChanged(m_VideoFormat, m_VideoMode, m_SensorSize, m_ImageSize, m_Origin);
// inform the main frame that the configuration has changed
m_MainFrame.ConfigurationChanged(this, format, mode, rate, code);
}
}
//------------------------------------------------------------------------------
// void CCamera::SetAOI(CRect AOI)
// Author:
//------------------------------------------------------------------------------
/**
* Set new AOI
*
* \param AOI
* \return void
*/
//------------------------------------------------------------------------------
void CCamera::SetAOI(CRect AOI)
{
assert ( m_VideoFormat == DCS_Format7 );
if ( ReconfigurationRequest() )
{
CPoint Origin;
Origin.x = AOI.left;
Origin.y = AOI.top;
CSize Size;
Size.cx = AOI.Width();
Size.cy = AOI.Height();
int bpp = FormatSeven[m_VideoMode].BytePerPacket();
InternalParametrizeCamera(m_VideoFormat, m_VideoMode, m_VideoFrameRate, m_ColorCode, Origin, Size, bpp);
ConfigurationChanged();
}
}
//------------------------------------------------------------------------------
// void CCamera::MaximizeAOI()
// Author:
//------------------------------------------------------------------------------
/**
* Maximize AOI
*
* \return void
*/
//------------------------------------------------------------------------------
void CCamera::MaximizeAOI()
{
CSize Size = FormatSeven[m_VideoMode].MaxSize();
AlignAOI(Size, m_VideoMode);
CPoint Origin = CPoint(0,0);
ParametrizeCamera(m_VideoMode, m_ColorCode, Origin, Size, -1);
}
//------------------------------------------------------------------------------
// void CCamera::SetBayerToRGBConversion( int mode )
// Author:
//------------------------------------------------------------------------------
/**
* Enable or disable the Bayer to RGB conversion
*
* \param mode
* \return
*
* void
*
*/
//------------------------------------------------------------------------------
void CCamera::SetBayerToRGBConversion( int mode )
{
assert ( mode >= 0 && mode < 5);
if ( ReconfigurationRequest() ) // suspend grabbing
{
m_ConvertMono8ToRGB = mode;
}
Refresh(true);
ConfigurationChanged(); // resume grabbing
}
//------------------------------------------------------------------------------
// void CCamera::SetBGain(double gain)
// Author:
//------------------------------------------------------------------------------
/**
* Set the gain for the blue channel and recalculate the according LUT for the conversion
* routine
*
* \param gain
* \return
*
*/
//------------------------------------------------------------------------------
void CCamera::SetBGain(double gain)
{
assert ( gain > 0 );
for ( int i = 0; i < 256; i++ )
{
m_pLutB[i] = min(255, i * gain ) ;
}
m_GainB = gain;
}
//------------------------------------------------------------------------------
// void CCamera::SetRGain(double gain)
// Author:
//------------------------------------------------------------------------------
/**
* Set the gain for the red channel and recalculate the according LUT for the conversion
* routine
*
* \param gain
* \return
*
*/
//------------------------------------------------------------------------------
void CCamera::SetRGain(double gain)
{
assert ( gain > 0 );
for ( int i = 0; i < 256; i++ )
{
m_pLutR[i] = min(255, i * gain ) ;
}
m_GainR = gain;
}
//------------------------------------------------------------------------------
// void CCamera::ParametrizeCamera(DCSVideoFormat format, DCSVideoMode mode, DCSVideoFrameRate rate)
// Author:
//------------------------------------------------------------------------------
/**
* Parametrize camera ( format 0 - 2 )
*
* \param format
* \param mode
* \param rate
* \return void
*/
//------------------------------------------------------------------------------
void CCamera::ParametrizeCamera(DCSVideoFormat format, DCSVideoMode mode, DCSVideoFrameRate rate)
{
if ( ReconfigurationRequest() )
{
InternalParametrizeCamera(format, mode, rate, BcamUtility::ColorCode(format, mode), CPoint(0, 0), BcamUtility::ImageSize(format, mode), -1 );
ConfigurationChanged();
}
}
//------------------------------------------------------------------------------
// void CCamera::ParametrizeCamera(DCSVideoMode mode, DCSColorCode code, CPoint position, CSize size, unsigned long bpp)
// Author:
//------------------------------------------------------------------------------
/**
* Parametrize camera ( format 7 )
*
* \param mode
* \param code
* \param position
* \param size
* \param bpp
* \return void
*
*/
//------------------------------------------------------------------------------
void CCamera::ParametrizeCamera(DCSVideoMode mode, DCSColorCode code, CPoint position, CSize size, unsigned long bpp)
{
if ( ReconfigurationRequest() )
{
InternalParametrizeCamera(DCS_Format7, mode, DCS_IgnoreFrameRate, code, position, size, bpp );
ConfigurationChanged();
}
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
// Private / protected member functions
//
//------------------------------------------------------------------------------
// void CCamera::InternalParmetrizeCamera(DCSVideoFormat format, DCSVideoMode mode, DCSVideoFrameRate rate, DCSColorCode code, CPoint position, CSize size, unsigned long bpp)
// Author:
//------------------------------------------------------------------------------
/**
* Internal function to parametrize camera.
*
* \param format
* \param mode
* \param rate
* \param code
* \param position
* \param size
* \param bpp
* \return void
*/
//------------------------------------------------------------------------------
void CCamera::InternalParametrizeCamera(DCSVideoFormat format, DCSVideoMode mode, DCSVideoFrameRate rate, DCSColorCode code, CPoint position, CSize size, unsigned long bpp)
{
#ifdef DEBUG
CString s = rate != -1 ? BcamUtility::VideoFrameRateName(rate) : "Ignore";
ATLTRACE(" format = %d, mode = %d, rate = %s, code = %s\n", format, mode, s, BcamUtility::ColorCodeName(code));
#endif
SetVideoMode(format, mode, rate);
if ( format == DCS_Format7 )
{
m_SensorSize = FormatSeven[mode].MaxSize(); // Max. size of AOI
// First ensure that the AOI stored in the camera is properly aligned.
// Because we use DIBs as buffer, the width must be a multiple of 4 ( DWORD alignment of the DIB's scanlines)
AlignAOI(size, mode);
#ifdef DEBUG
const CSize SizeInc = FormatSeven[mode].Size.Inc();
const CSize PosInc = FormatSeven[mode].Position.Inc();
assert ( position.x % PosInc.cx == 0 );
assert ( position.y % PosInc.cy == 0 );
assert ( size.cx % SizeInc.cx == 0 );
assert ( size.cy % SizeInc.cy == 0 );
assert ( size.cx + position.x <= m_SensorSize.cx );
assert ( size.cy + position.y <= m_SensorSize.cy );
assert ( size.cx % 4 == 0 );
#endif
// SetAOI
ATLTRACE("SetAOI: Origin: (%d, %d), Size: (%d, %d)\n", position.x, position.y, size.cx, size.cy );
FormatSeven[mode].Position = position;
FormatSeven[mode].Size = size;
FormatSeven[mode].ColorCoding = code;
if ( bpp == -1 )
{
bpp = FormatSeven[mode].BytePerPacket.Rec();
}
unsigned long maxbpp = FormatSeven[mode].BytePerPacket.Max();
// our cameras don't allow more than 4095 packets per frame. -> calculate according minimum
unsigned long inc = lcm(4, FormatSeven[mode].BytePerPacket.Inc());
unsigned long minbpp = inc * ( ( (FormatSeven[mode].BytePerFrame() + 4094) / 4095 + inc - 1 ) / inc);
minbpp = __max( minbpp, inc );
if ( bpp > maxbpp )
bpp = inc * ( maxbpp / inc );
else if ( bpp < minbpp )
bpp = inc * ( ( minbpp + inc - 1 ) / inc );
// transfer value to the camera
assert ( bpp >= minbpp );
assert ( bpp <= maxbpp );
assert ( bpp % inc == 0 );
FormatSeven[mode].BytePerPacket = bpp;
}
else
{
m_SensorSize = size;
}
// invalidate bitmap, if its size doesn't match the new settings
m_fBitmapValid = ! IsContinuousGrabActive() && m_pBitmap != NULL && m_SensorSize == m_pBitmap->GetSensorSize();
// update internal state and notify clients of changes
Refresh(true);
}
//------------------------------------------------------------------------------
// void CCamera::CreateThreads()
// Author:
//------------------------------------------------------------------------------
/**
* - Creates the display and acquisition threads
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -