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

📄 camera.cpp

📁 用MFC开发的SDI程序
💻 CPP
字号:
/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                        Intel License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000, Intel Corporation, all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of Intel Corporation may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/// Camera.cpp: implementation of the CCamera class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Camera.h"
#include <assert.h>

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCamera::CCamera()
{
    m_capWnd = 0;
    m_isRunning = false;
}

CCamera::~CCamera()
{
    Uninitialize();
}

/* conversion YUV->RGB */
#define TWIST_BITS 12
#define TAP(x) ((int)((x)*(1<<TWIST_BITS) + 0.5 ))

static const int YUV2RGB[] = 
{
    TAP(1.1644), TAP(1.596), TAP(    0), -TAP(222.9184),
    TAP(1.1644),-TAP(0.815),-TAP( 0.39),  TAP(135.6096),
    TAP(1.1644), TAP(0),     TAP(2.016), -TAP(276.6784)
};

#define PROCESS_UV( uv_ofs, r0, g0, b0 )                                       \
    b0 = U[uv_ofs]*YUV2RGB[1+4*0] +           /* 0 + */        YUV2RGB[3+4*0]; \
    g0 = U[uv_ofs]*YUV2RGB[1+4*1] + V[uv_ofs]*YUV2RGB[2+4*1] + YUV2RGB[3+4*1]; \
    r0 =      /*  0 + */            V[uv_ofs]*YUV2RGB[2+4*2] + YUV2RGB[3+4*2];

#define PROCESS_Y( y_ofs, r, g, b, r0, g0, b0 ) \
    r = Y[y_ofs]*YUV2RGB[0+4*0];                \
    b = (r + b0) >> TWIST_BITS;                 \
    g = (r + g0) >> TWIST_BITS;                 \
    r = (r + r0) >> TWIST_BITS;

#define SATURATE(x) (BYTE)(!((x)&~255)?(x):~((x)>>31))

#define SAVE_RGB(ofs,r,g,b)     \
    BGR[(ofs)]   = SATURATE(b); \
    BGR[(ofs)+1] = SATURATE(g); \
    BGR[(ofs)+2] = SATURATE(r);


static void ConvertYUV420_TO_BGR( int width, int height,
                                  BYTE* Y, BYTE* U, BYTE* V,
                                  BYTE* BGR, int bgrStep )
{
    int  i, j;
    assert( ((width|height)&7) == 0 );

    int delta = bgrStep - width*3;
    width /= 2;

    for( i = 0; i < height; i += 2, Y += 4*width,
                                    U += width, V += width,
                                    BGR += delta + bgrStep )
    {
        for( j = 0; j < width; j++, BGR += 6 )
        {
            int r0, g0, b0, r, g, b;

            PROCESS_UV( j, r0, g0, b0 );
            
            PROCESS_Y( j*2, r, g, b, r0, g0, b0 );
            SAVE_RGB( 0, r, g, b );

            PROCESS_Y( j*2 + 1, r, g, b, r0, g0, b0 );
            SAVE_RGB( 3, r, g, b );

            PROCESS_Y( j*2 + width*2, r, g, b, r0, g0, b0 );
            SAVE_RGB( bgrStep, r, g, b );

            PROCESS_Y( j*2 + width*2 + 1, r, g, b, r0, g0, b0 );
            SAVE_RGB( bgrStep + 3, r, g, b );
        }
    }
}


static void CopyBGR_TO_BGR( int width, int height, BYTE* srcBGR, int srcStep,
                            BYTE* dstBGR, int dstStep )
{
    int i;

    for( i = 0; i < height; i++, srcBGR += srcStep, dstBGR += dstStep )
    {
        memcpy( dstBGR, srcBGR, width*3 );            
    }
}


void CCamera::UpdateParent( bool whole )
{
    HWND parent = GetParent( m_capWnd );
    RECT r = { 0, 0, 0, 0 };
    IplImage* img = m_frame.GetImage();

    if( img )
    {
        r.right = img->width;
        r.bottom = img->height;
    }
    
    InvalidateRect( parent, whole ? 0 : &r, whole );
    UpdateWindow( parent );
}

// Wrapper for frame callback
void CCamera::OnFrame( BYTE* data, int width, int height, int format, int bpp )
{
    const int mirror = 1;

    if( m_isRunning )
    {
        BYTE *BGR;
        int bgrStep;
        IplImage* img;
        bool refresh = width != m_frame.Width() || height != m_frame.Height();
    
        /* check if need reallocate image */
        m_frame.Create( width, height, 24 );

        img = m_frame.GetImage();

        BGR = (BYTE*)(img->imageData);
        bgrStep = img->widthStep;

        if( format == MAKEFOURCC('Y','V','1','2') || format == MAKEFOURCC('I','4','2','0'))
        {
            BYTE *Y = data,
                 *U = Y + width*height,
                 *V = U + width*height/4;

            ConvertYUV420_TO_BGR( width, height, Y, U, V, BGR, bgrStep );
        }
        else if( format == 0 && bpp == 24 )
        {
            int step = (width*3 + 3) & -4;

            if( mirror )
            {
                BGR += bgrStep*(height - 1);
                bgrStep = -bgrStep;
            }

            CopyBGR_TO_BGR( width, height, data, step, BGR, bgrStep );
        }

        UpdateParent( refresh );
    }
}

// Frame callback
LRESULT PASCAL FrameCallbackProc( HWND hWnd, VIDEOHDR* hdr ) 
{ 
    BITMAPINFO vfmt;
    int sz;

    if (!hWnd) return FALSE;

    sz = capGetVideoFormat( hWnd, &vfmt, sizeof(vfmt));
    
    if( hdr && hdr->lpData && sz != 0 )
    {
        int width = vfmt.bmiHeader.biWidth;
        int height = vfmt.bmiHeader.biHeight;
        int format = vfmt.bmiHeader.biCompression;
        int bpp = vfmt.bmiHeader.biBitCount;
        BYTE* data = (BYTE*)(hdr->lpData);

        CCamera* camera_obj = (CCamera*)capGetUserData(hWnd);
        if( camera_obj )
        {
            camera_obj->OnFrame( data, width, height, format, bpp );
        }
    }

    return (LRESULT) TRUE; 
} 


// Initialize camera input
bool  CCamera::Initialize( int width, int height, int format, HWND parent, int wIndex )
{
    char szDeviceName[80];
    char szDeviceVersion[80];
		 
	HWND hWndC = 0;
    
	if( (unsigned)wIndex < 10 )
        goto init_camera;

    for( wIndex = 0; wIndex < 10; wIndex++ ) 
    {
init_camera:  
	    /* the function below give us the description of the driver and we 
	       test the function if it's OK, we have the right (wIndex) number */ 

	   if( capGetDriverDescription( wIndex, szDeviceName, 
            sizeof (szDeviceName), szDeviceVersion, 
            sizeof (szDeviceVersion)))
			
        {   /* here we create a capture window */
            hWndC = capCreateCaptureWindow ( "My Own Capture Window", 
                  WS_CHILD | WS_VISIBLE , 0, 0, 160, 120, parent, 0);

            /* the function below connect the driver to the window handle
			   if it's OK we can go on */
			if( capDriverConnect (hWndC, wIndex))
            {
                BITMAPINFO bmi;
 
                //capPreviewRate(hWndC, 66);  // rate, in milliseconds
                memset( &bmi.bmiHeader, 0, sizeof(bmi.bmiHeader));
                bmi.bmiHeader.biSize = sizeof(bmi.bmiHeader);
                bmi.bmiHeader.biBitCount = format == 0 ? 24 : 12;
                bmi.bmiHeader.biWidth = width;
                bmi.bmiHeader.biHeight = height;
                bmi.bmiHeader.biPlanes = 1;
                bmi.bmiHeader.biCompression = format;
                bmi.bmiHeader.biSizeImage = ((bmi.bmiHeader.biWidth*
                                              bmi.bmiHeader.biBitCount/8 + 3)&-4)*
                                              bmi.bmiHeader.biHeight;
                if( format == -1 || capSetVideoFormat( hWndC, &bmi, sizeof(bmi)-4)) break;
                capDriverDisconnect( hWndC );
            }
            DestroyWindow( hWndC );
            hWndC = 0;
        }
    }
    
    if( hWndC )
    {
        m_capWnd = hWndC;
        
        memset( &m_caps, 0, sizeof(m_caps));
        capDriverGetCaps( hWndC, &m_caps, sizeof(m_caps));
        capSetUserData( hWndC, (long)this );
        capSetCallbackOnFrame( m_capWnd, FrameCallbackProc ); 
        ::MoveWindow( m_capWnd, 0, 0, 1, 1, TRUE );
        CAPTUREPARMS p;
        capCaptureGetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
        p.dwRequestMicroSecPerFrame = 1;
        capCaptureSetSetup(hWndC,&p,sizeof(CAPTUREPARMS));
        
		// enables or disables scaling of the preview video images
        capPreviewScale(hWndC,FALSE); 

		// sets the frame display rate in preview mode
        capPreviewRate(hWndC,1);
    }
    return m_capWnd != 0;
}


// Uninitialize camera input
void  CCamera::Uninitialize()
{
    Stop();
    capSetCallbackOnFrame( m_capWnd, NULL ); 
    capDriverDisconnect( m_capWnd );
    DestroyWindow( m_capWnd );
}

// Start capture
void  CCamera::Start()
{
    if( m_capWnd )
    {
        m_isRunning = true;
    }
}

// Stop capture
void  CCamera::Stop()
{
    if( m_capWnd )
    {
        m_isRunning = false;
    }
}


void  CCamera::VideoFormatDlg()
{
    if( m_capWnd && m_caps.fHasDlgVideoFormat )
    {
        capDlgVideoFormat( m_capWnd );
    }
}


void  CCamera::VideoSourceDlg()
{
    if( m_capWnd && m_caps.fHasDlgVideoSource )
    {
        capDlgVideoSource( m_capWnd );
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -