Click here to Skip to main content
15,891,136 members
Articles / Programming Languages / C++

Realtime Webcam Sudoku Solver

Rate me:
Please Sign up or sign in to vote.
4.97/5 (311 votes)
8 Aug 2011LGPL319 min read 455.5K   25.7K   416  
Sudoku solver via a webcam: A nice computer vision application
  • WebCamSudokuSolver_demo.zip
    • SudSolver.exe
  • WebCamSudokuSolver_src.zip
    • AviCapTest.cpp
    • AviCapTest.h
    • AviCapTest.rc
    • AviCapTest.vcproj
    • AviCapTestDoc.cpp
    • AviCapTestDoc.h
    • AviCapTestView.cpp
    • AviCapTestView.h
    • CAvicap.cpp
    • CAvicap.h
    • EnhCtl.cpp
    • EnhCtl.h
    • Info.cpp
    • Info.h
    • MainFrm.cpp
    • MainFrm.h
    • OCRDigit.cpp
    • OCRDigit.h
    • ProgDlg.cpp
    • ProgDlg.h
    • res
      • 1
        • Train0a.bmp
        • Train0b.bmp
        • Train0c.bmp
        • Train1_0_6.bmp
        • Train1_0_6a.bmp
        • Train1_1_0.bmp
        • Train1_1_0a.bmp
        • Train1_1_0b.bmp
        • Train1_1_0d.bmp
        • Train1_1_1.bmp
        • Train1_1_1b.bmp
        • Train1_1_1c.bmp
        • Train1_2_3.bmp
        • Train1_3_2.bmp
        • Train1_4_4.bmp
        • Train1_5_5.bmp
        • Train1_6_5.bmp
        • Train1a.bmp
        • Train1b.bmp
        • Train1c.bmp
      • 2
        • Train2_1_3.bmp
        • Train2_1_3a.bmp
        • Train2_2_2.bmp
        • Train2_2_5.bmp
        • Train2_2_5a.bmp
        • Train2_5_6.bmp
        • Train2_5_6a.bmp
        • Train2_5_6b.bmp
        • Train2_5_6c.bmp
        • Train2_5_7.bmp
        • Train2_5_7a.bmp
        • Train2_5_7b.bmp
        • Train2_5_7c.bmp
        • Train2_6_3.bmp
        • Train2_6_3a.bmp
        • Train2_6_6.bmp
        • Train2_7_2.bmp
        • Train2_7_2a.bmp
        • Train2_7_2b.bmp
        • Train2_8_2.bmp
        • Train2_8_2a.bmp
        • Train2a.bmp
        • Train2b.bmp
        • Train2c.bmp
      • 3
        • Train3_0_8.bmp
        • Train3_0_8c.bmp
        • Train3_1_2.bmp
        • Train3_1_2c.bmp
        • Train3_3_3.bmp
        • Train3_3_5.bmp
        • Train3_3_5b.bmp
        • Train3_3_5c.bmp
        • Train3_4_0.bmp
        • Train3_4_0c.bmp
        • Train3_6_2.bmp
        • Train3_6_8.bmp
        • Train3_6_8a.bmp
        • Train3_7_1.bmp
        • Train3_7_1a.bmp
        • Train3_8_2.bmp
        • Train3_8_7.bmp
        • Train3a.bmp
        • Train3b.bmp
        • Train3c.bmp
      • 4
        • Train4_0_2.bmp
        • Train4_0_2a.bmp
        • Train4_0_7.bmp
        • Train4_1_5.bmp
        • Train4_1_6.bmp
        • Train4_2_8.bmp
        • Train4_2_8a.bmp
        • Train4_4_4.bmp
        • Train4_4_5.bmp
        • Train4_6_0.bmp
        • Train4_7_6.bmp
        • Train4a.bmp
        • Train4b.bmp
        • Train4c.bmp
      • 5
        • Train5_0_1.bmp
        • Train5_1_4.bmp
        • Train5_1_4a.bmp
        • Train5_1_8.bmp
        • Train5_2_8.bmp
        • Train5_4_1.bmp
        • Train5_4_1a.bmp
        • Train5_5_8.bmp
        • Train5_5_8a.bmp
        • Train5_7_6.bmp
        • Train5_8_5.bmp
        • Train5_8_5a.bmp
        • Train5a.bmp
        • Train5b.bmp
        • Train5c.bmp
      • 6
        • Train6_0_4.bmp
        • Train6_0_5.bmp
        • Train6_1_3.bmp
        • Train6_1_3a.bmp
        • Train6_1_5.bmp
        • Train6_2_0.bmp
        • Train6_2_3.bmp
        • Train6_2_3a.bmp
        • Train6_2_3b.bmp
        • Train6_2_3c.bmp
        • Train6_2_6.bmp
        • Train6_3_6.bmp
        • Train6_3_6d.bmp
        • Train6_4_2.bmp
        • Train6_4_2a.bmp
        • Train6_4_2b.bmp
        • Train6_4_2c.bmp
        • Train6_5_2.bmp
        • Train6_5_3.bmp
        • Train6_5_4.bmp
        • Train6_5_4a.bmp
        • Train6_5_4b.bmp
        • Train6_5_4c.bmp
        • Train6_6_7.bmp
        • Train6_6_7b.bmp
        • Train6_6_7c.bmp
        • Train6_7_1.bmp
        • Train6_7_8.bmp
        • Train6_7_8a.bmp
        • Train6_7_8b.bmp
        • Train6_8_1.bmp
        • Train6_8_5.bmp
        • Train6a.bmp
        • Train6b.bmp
        • Train6d.bmp
      • 7
        • Train7_0_3.bmp
        • Train7_0_3a.bmp
        • Train7_0_7.bmp
        • Train7_1_2.bmp
        • Train7_2_0.bmp
        • Train7_2_0a.bmp
        • Train7_3_1.bmp
        • Train7_3_5.bmp
        • Train7_3_6.bmp
        • Train7_3_6a.bmp
        • Train7_4_6.bmp
        • Train7_4_8.bmp
        • Train7_5_2.bmp
        • Train7_5_2a.bmp
        • Train7_7_0.bmp
        • Train7_7_5.bmp
        • Train7_7_5a.bmp
        • Train7_8_0.bmp
        • Train7_8_7.bmp
        • Train7_8_7a.bmp
        • Train7a.bmp
        • Train7b.bmp
        • Train7c.bmp
        • Train7d.bmp
        • Train7e.bmp
      • 8
        • Train8_0_1.bmp
        • Train8_0_1a.bmp
        • Train8_0_2.bmp
        • Train8_0_2c.bmp
        • Train8_1_8.bmp
        • Train8_2_0.bmp
        • Train8_2_4.bmp
        • Train8_3_0.bmp
        • Train8_3_0a.bmp
        • Train8_3_3.bmp
        • Train8_3_4.bmp
        • Train8_3_4c.bmp
        • Train8_4_7.bmp
        • Train8_4_7a.bmp
        • Train8_6_7.bmp
        • Train8_7_2.bmp
        • Train8_7_4.bmp
        • Train8_7_4a.bmp
        • Train8_7_6.bmp
        • Train8_7_6c.bmp
        • Train8_72.bmp
        • Train8_8_5.bmp
        • Train8a.bmp
        • Train8b.bmp
        • Train8c.bmp
      • 9
        • Train9_0_1c.bmp
        • Train9_0_2.bmp
        • Train9_1_7.bmp
        • Train9_1_7a.bmp
        • Train9_2_7.bmp
        • Train9_2_7b.bmp
        • Train9_2_7c.bmp
        • Train9_3_0.bmp
        • Train9_3_1.bmp
        • Train9_3_1a.bmp
        • Train9_3_1b.bmp
        • Train9_5_7.bmp
        • Train9_6_0.bmp
        • Train9_6_0a.bmp
        • Train9_6_8.bmp
        • Train9_6_8a.bmp
        • Train9_6_8b.bmp
        • Train9_6_8c.bmp
        • Train9_7_2.bmp
        • Train9_7_2a.bmp
        • Train9_7_2b.bmp
        • Train9_7_2c.bmp
        • Train9_7_3.bmp
        • Train9_8_6.bmp
        • Train9_8_6a.bmp
        • Train9_8_6b.bmp
        • Train9a.bmp
        • Train9b.bmp
        • Train9c.bmp
      • AviCapTest.ico
      • AviCapTest.rc2
      • AviCapTestDoc.ico
    • resource.h
    • StdAfx.cpp
    • StdAfx.h
    • SudBitmap.cpp
    • SudBitmap.h
    • SudResultVoter.cpp
    • SudResultVoter.h
    • SudSolver.cpp
    • SudSolver.h
    • WebcamSudSolver.sln
// CAVICAP.H
// (c) Vadim Gorbatenko, 1996-99
// CAviCap window
// Started: 11.09.96
//______________________________________________________________________________

//Options:  on connection action:
//BB #define	ON_CONNECT_TEST_BIBITSCOUNT		// Testing for available bits resolution
//BB #define	ON_CONNECT_CHECK_DRIVERLIST		// Create full list of installed drivers
//BB #define	ON_CONNECT_CHECK_VALIDFORMATS	// Create full list of available formats
//#define	CAPTURE_PRIORITY_CONTROL	
#define DEFAULT_FORCE_SINGLE_FRAME		// Skip cached frames for GrabOne
//#define	DEFAULT_USED_DOSMEMORY		// std setting for driver
//#define	DEFAULT_STEP_CAPTUREAT2X	// get average frame
#define	AVICAP_WINDOW_ID	0xffff

#if !defined(_INC_VFW)
    #define	NODRAWDIB
    #define	NOAVIFMT
    #define	NOMMREG
    #define	NOAVIFILE
    #define	NOMCIWND
    #define	NOMSACM
    #include "vfw.h"
#endif

typedef VOID (CALLBACK *PROGRESSCALLBACK)(LPSTR , DWORD);
typedef VOID (CALLBACK *DRAWCALLBACK)(BOOL);
typedef LRESULT (CALLBACK *FRAMECALLBACK)(HWND , LPVIDEOHDR);

#define	ANY_DRIVER				-1	// default driver(for connection only)
#define	MAXCAPDRIVERS			10	// maximum drivers list size
#define DEFAULT_PREVIEW_RATE	50	// default preview rate = 50 msec
#define	MAX_VALID_BUFFERS_COUNT 10	// maximum internal buffer for Vxd(testing)
#define MIN_FRAME_PERIOD		20	// msec -> 50 frames per second (can't do faster!)

//Image Bits resolution
#define	BITS01	0x0001		// B&W Mono
#define	BITS04	0x0002		// 16  Colors
#define	BITS08	0x0004		// 256 Colors
#define	BITS16	0x0008		// 16 bits RGB
#define	BITS24	0x0010		// 24 bits RGB
#define	BITS32	0x0020		// 32 bits RGB

//struct for gathering capture driver information
typedef struct
{
	CHAR	psName[128];				  //name of driver
	DWORD	dwInternalBufCnt;			 //driver cache size
	DWORD	dwCurBiBitCount;			//current resolution
	DWORD	dwBiBitsCountSupported; //see abow for flags
    BOOL	fNTSC;			//this is NTSC videostandard
	DWORD	dwCompressed;		//is compressed
	SIZE	szFrameSize;		//Current frame size
	BOOL	fFormatDlgSup;	//"Format"  dialog supported
	BOOL	fSourceDlgSup;	//"Source"  dialog supported
	BOOL	fDisplayDlgSup;	//"Display" dialog supported
} CAPDRVINFO;

class CAviCap: public CWnd
{
public:
	enum { visible = WS_CHILD|WS_VISIBLE,hidden=WS_CHILD};

	CAviCap();
	~CAviCap();
	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAviCap)
	public:
	virtual BOOL	Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, BOOL fAutoSize=TRUE);
	//}}AFX_VIRTUAL

	//
	// Connection & disconnection
	//
	BOOL	ConnectWithDriver(LPCSTR Name=NULL);//connect by name
	BOOL	ConnectWithDriver(int indx);		//connect by index
	BOOL	Disconnect();

	//
	// Standard AVICap window COMMANDs.
	// Implemeted via cap[xxx] macros	
	// See SDK for more information
	//
	BOOL	StartPreview(BOOL offOn);
	BOOL	GetPreviewFlag();
	BOOL	StartOverlay(BOOL offOn);
	BOOL	StartSeq(BOOL offOn);
	BOOL	SavePalette(LPCSTR file);
	BOOL	LoadPalette(LPCSTR file);
	BOOL	PastePalette();
	BOOL	CreatePalette(int frames,int colors);
	BOOL	CopyFrame();			 // copy image to clipboard
	BOOL	SetPreviewRate(int Rate);// Rate == xx msec
	BOOL	SetCapSetup(CAPTUREPARMS *parms);
	BOOL	GetCapStatus(CAPSTATUS *status);
	BOOL	GetCapSetup(CAPTUREPARMS *parms);
			//Standard AVICap window Dialogs
	BOOL	CompressDlg();
	BOOL	DisplayDlg();
	BOOL	FormatDlg();
	BOOL	VSourceDlg();
			//Setup standard AVICap window callbacks
	BOOL	SetStreamCallBack(LPVOID cb);
	BOOL	SetYiedCallBack(LPVOID cb);
	BOOL	SetErrorCallBack(LPVOID cb);
	// 
	// Enhanced capturing control
	//
	BOOL	SetFrameCallBack(FRAMECALLBACK cb);
	void	ResetCache();			//Reset internal driver buffers queue(if exist)
	BOOL	SetFormat(LPBITMAPINFO bmpinf);
	BOOL	SetBitResolution(UINT reqBitsCount);
	BOOL	SetFrameSize(int x, int y);
	BOOL	SetFrameSize(CSize sz);
	BOOL	GrabOneFrame();		  // manual capturing
	BOOL	SetShowFlag(BOOL fsf);// enable/disable painting
	BOOL	Cancel();			  // to cancel long-time operations
	//
	// Extended formats information
	//
	BOOL			GetDriverInfo(CAPDRVINFO *cdi);//get complete driver information
	CSize			GetFrameSize();
	DWORD			GetRequiredBufferSize();
	LPBITMAPINFO	GetCurrentFormat();
	BOOL			IsSupportedBitsResolution(UINT bitsCount);
	DWORD			GetCurrentBitsResolution();
					//get list of supported frame size
	BOOL			EnumValidFrameSize(CSize &sz, int indx);
	//
	// Extended  setup information
	//
	BOOL		GetDriverCaps(CAPDRIVERCAPS *caps);
	//
	// Additional driver(s) information
	//	
			//get comlpete capture drivers list
	int		GetDriversList(CStringArray *Names, CStringArray *Vers);
	LPCSTR	GetDriverName(); //get current driver name
	LPCSTR	GetDriverVer();	 //get current driver version string
	int		GetDriverIndex();//get current driver index
	//
	// Setup specific callbacks for drawing and progress notification
	//
			//setup callback for drawing in capture window
	VOID	SetDrawCallBack(DRAWCALLBACK cb);
			//setup callback for progress notification
	VOID	SetProgressCallback(PROGRESSCALLBACK cb);
	//
	// misc
	//
			//adjust window size and position  according current frame size
	void	AdjustPlacement(BOOL fStretch=FALSE);
	BOOL	IsReady();		//is connected with driver?
	int		GetLastError(); //last error code
	//
	// Optional attribute for quick connection(without testing)
	// Note if you performs quick connection you can't determine
	// internal driver buffers queue size or you have to modify
	// _connect2Driver method
	BOOL		m_DoQuickConnection; 

protected:

	CAPDRIVERCAPS	_capDriverCaps;
	CAPSTATUS		_capStatus;
	CAPTUREPARMS	_captureParms;
	LPBITMAPINFO	_bmpInfo;
	CStringArray	_drvNames;
	CStringArray 	_drvVers;
	int			_curDriver;
	BOOL 		_fDialogIsUp;
	BOOL		_fPreviewIsOn;
	BOOL		_fOverlayIsOn;
	BOOL		_fSeqIsOn;
	int			_previewRate;
	DWORD		_biBitsCountSupported;
	CDWordArray	_formats;
	CDWordArray	_cmprs_formats;
	BOOL		_1FrameCallBackInstalled;
	CSize		_smallFrame;
	int			_internalBufCnt;
	BOOL		_fShow;
	int			iLastError;
	BOOL		_autosize;

	volatile BOOL	_capAbort;

  	PROGRESSCALLBACK	_progressCB;
	DRAWCALLBACK		_drwcb;

	int		_GetInternalBuffersCount();
	BOOL	_IsImageCompressed();
	void	_notify(LPSTR lp=NULL);
	void	_notify(LPSTR lp, DWORD pc);
	void	_selfInit();
	void	_getDrvList();
	BOOL	_getCaps();
	BOOL	_getStatus();
	BOOL	_getSetup();
	BOOL	_setSetup();
	BOOL	_getFormat();
	BOOL	_connect2Driver(int indx);
	BOOL	_testBiBitsCount();
	BOOL	_testValidFormats();
	BOOL	_testInternalBuffers();
	BOOL	_testBitsFormat(UINT bits);
	BOOL	_testFrameFormat(int x, int y);

	LPBITMAPINFO	_mk_LPBITMAPINFO(UINT bitsReqCode,int x, int y);
	int				_getBMIsize(UINT bitsReq, UINT bmiColors);
	int				_getBMIsize(LPBITMAPINFO);
	DWORD			_calcBufferSize(LPBITMAPINFOHEADER bih);
	
	void		_pushResolution();
	void		_popResolution();
	void		_autoSize();
	int			_totalDrv();
protected:
	//{{AFX_MSG(CAviCap)
	afx_msg void OnPaint();
	afx_msg void OnDestroy();
	afx_msg void OnTimer(UINT nIDEvent);
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

//Error codes
#define	CAP_CREATE_DUP				-1	/*can't connect twice!*/
#define	CAP_WINCREATION_FAILED		-2	/*failed to create capture window*/
#define	CAP_NO_CAPDEVICE_INSTALLED	-3	/*no capture device found*/
#define	CAP_DRIVERNAME_NOT_FOUND	-4	/*no capture driver found*/
#define	CAP_ILLEGAL_DRIVERID		-5	/*out of drivers list*/
#define	CAP_CONNECTION_FAILED		-6	/*no comments*/
#define	CAP_INIT_FAILED				-7	/*initialization step failed*/
#define	CAP_TEST_FAILED				-8	/*can't test device*/
#define	CAP_CALLNOWINDOW			-9	/*window not created*/
#define	CAP_CALLNOCONNECTION		-10	/*no connection with capture driver*/


//	CAviCap inlines
inline	int	CAviCap::_totalDrv()	
	{return _drvNames.GetSize();}
inline	BOOL	CAviCap::GetPreviewFlag()
	{return _fPreviewIsOn;}
inline	VOID	CAviCap::SetDrawCallBack(DRAWCALLBACK cb) 
	{_drwcb = cb;}
inline 	VOID	CAviCap::SetProgressCallback(PROGRESSCALLBACK cb) 
	{_progressCB= cb;}
inline	void	CAviCap::AdjustPlacement(BOOL fStretch)
	{_autosize=!fStretch; _autoSize(); }
inline	BOOL	CAviCap::IsReady()	
	{return (_curDriver!=-1)&&GetSafeHwnd();}
inline	int		CAviCap::GetLastError()
	{int ret=iLastError;iLastError=0; return ret;}	
inline	BOOL	CAviCap::_getStatus()
	{return capGetStatus (GetSafeHwnd(), &_capStatus, sizeof (CAPSTATUS));}
inline	BOOL	CAviCap::_getSetup()
	{return capCaptureGetSetup (GetSafeHwnd(), &_captureParms, sizeof CAPTUREPARMS);}
inline	BOOL	CAviCap::_setSetup()
	{return capCaptureSetSetup (GetSafeHwnd(), &_captureParms, sizeof CAPTUREPARMS);}
inline	void	CAviCap::_notify(LPSTR lp)
	{if(_progressCB) (*_progressCB)(lp,100);}
inline	void	CAviCap::_notify(LPSTR lp, DWORD pc)
	{if(_progressCB) (*_progressCB)(lp,pc);}
inline	BOOL	CAviCap::SetFrameSize(CSize sz)
	{return SetFrameSize(sz.cx,sz.cy);}
inline	LPCSTR	CAviCap::GetDriverName()	
	{return (_curDriver==-1||!_drvNames.GetSize()) ? NULL : (LPCSTR)_drvNames[_curDriver];}
inline	LPCSTR	CAviCap::GetDriverVer()	
	{return (_curDriver==-1||!_drvNames.GetSize()) ? NULL : (LPCSTR)_drvVers[_curDriver];}
inline	int		CAviCap::GetDriverIndex() 
	{return _curDriver;}
inline	BOOL	CAviCap::SavePalette(LPCSTR file) 
	{return (_curDriver==-1) ? FALSE : (BOOL)capPaletteSave(GetSafeHwnd(), file);}
inline	BOOL	CAviCap::LoadPalette(LPCSTR file) 
	{return (_curDriver==-1) ? FALSE : (BOOL)capPaletteOpen(GetSafeHwnd(), file);}
inline	BOOL	CAviCap::PastePalette()
	{return (_curDriver==-1) ? FALSE : (BOOL)capPalettePaste(GetSafeHwnd());}
inline	BOOL	CAviCap::CreatePalette(int frames,int colors)
	{return (_curDriver==-1) ? FALSE : (BOOL)capPaletteAuto(GetSafeHwnd(), frames, colors);};
inline	BOOL	CAviCap::CopyFrame()
	{return (_curDriver==-1) ? FALSE : (BOOL)capEditCopy(GetSafeHwnd());}
inline	BOOL	CAviCap::SetShowFlag(BOOL fsf)
	{BOOL os=_fShow; _fShow=fsf; return os;}
inline	CSize	CAviCap::GetFrameSize()
	{return (_curDriver==-1) ? CSize(0,0) : CSize(((LPBITMAPINFOHEADER)_bmpInfo)->biWidth,((LPBITMAPINFOHEADER)_bmpInfo)->biHeight);}
inline	DWORD	CAviCap::GetRequiredBufferSize()
	{return (_curDriver==-1) ? FALSE : _calcBufferSize((LPBITMAPINFOHEADER)_bmpInfo);}
inline	LPBITMAPINFO	CAviCap::GetCurrentFormat()
	{return _bmpInfo;}
inline	DWORD	CAviCap::GetCurrentBitsResolution()
	{_getFormat(); return  _bmpInfo ? ((LPBITMAPINFOHEADER)_bmpInfo)->biBitCount:0;}
inline	BOOL	CAviCap::CompressDlg()
	{return (_curDriver==-1) ? FALSE : (BOOL)capDlgVideoCompression(GetSafeHwnd());}
inline	BOOL	CAviCap::DisplayDlg()
	{BOOL r = (_curDriver==-1) ? FALSE : (BOOL)capDlgVideoDisplay(GetSafeHwnd());_autoSize();return r;}	
inline	BOOL	CAviCap::FormatDlg()
	{BOOL r = (_curDriver==-1) ? FALSE : (BOOL)capDlgVideoFormat(GetSafeHwnd());_autoSize();return r;}
inline	BOOL	CAviCap::VSourceDlg()
	{BOOL r = (_curDriver==-1) ? FALSE : (BOOL)capDlgVideoSource(GetSafeHwnd());_autoSize();return r;}
inline	BOOL	CAviCap::Cancel()
	{return _capAbort=TRUE;}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The GNU Lesser General Public License (LGPLv3)


Written By
Skilja
Croatia Croatia
Programmer since 1994.

Comments and Discussions