Click here to Skip to main content
15,891,645 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.9K   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
//  ProgDlg.cpp : implementation file
// CG: This file was added by the Progress Dialog component

#include "stdafx.h"
#include "resource.h"
#include "ProgDlg.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CProgressDlg dialog

CProgressDlg::CProgressDlg(UINT nCaptionID)
{
	m_nCaptionID = CG_IDS_PROGRESS_CAPTION;
	if (nCaptionID != 0)
		m_nCaptionID = nCaptionID;

    m_nLower=0;
    m_nUpper=100;
    m_nStep=10;
    //{{AFX_DATA_INIT(CProgressDlg)
    // NOTE: the ClassWizard will add member initialization here
    //}}AFX_DATA_INIT
    m_bParentDisabled = FALSE;
}

CProgressDlg::~CProgressDlg()
{
    if(m_hWnd!=NULL)
      DestroyWindow();
}

BOOL CProgressDlg::DestroyWindow()
{
    ReEnableParent();
    return CDialog::DestroyWindow();
}

void CProgressDlg::ReEnableParent()
{
    if(m_bParentDisabled && (m_pParentWnd!=NULL))
      m_pParentWnd->EnableWindow(TRUE);
    m_bParentDisabled=FALSE;
}

BOOL CProgressDlg::Create(CWnd *pParent)
{
    // Get the true parent of the dialog
    m_pParentWnd = CWnd::GetSafeOwner(pParent);

    // m_bParentDisabled is used to re-enable the parent window
    // when the dialog is destroyed. So we don't want to set
    // it to TRUE unless the parent was already enabled.

    if((m_pParentWnd!=NULL) && m_pParentWnd->IsWindowEnabled())
    {
      m_pParentWnd->EnableWindow(FALSE);
      m_bParentDisabled = TRUE;
    }

    if(!CDialog::Create(CProgressDlg::IDD,pParent))
    {
      ReEnableParent();
      return FALSE;
    }

    return TRUE;
}

void CProgressDlg::DoDataExchange(CDataExchange* pDX)
{
    CDialog::DoDataExchange(pDX);
    //{{AFX_DATA_MAP(CProgressDlg)
    DDX_Control(pDX, CG_IDC_PROGDLG_PROGRESS, m_Progress);
    //}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CProgressDlg, CDialog)
    //{{AFX_MSG_MAP(CProgressDlg)
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CProgressDlg::SetStatus(LPCTSTR lpszMessage)
{
    ASSERT(m_hWnd); // Don't call this _before_ the dialog has
                    // been created. Can be called from OnInitDialog
    CWnd *pWndStatus = GetDlgItem(CG_IDC_PROGDLG_STATUS);

    // Verify that the static text control exists
    ASSERT(pWndStatus!=NULL);
    pWndStatus->SetWindowText(lpszMessage);
}

void CProgressDlg::OnCancel()
{
}

void CProgressDlg::SetRange(int nLower,int nUpper)
{
    m_nLower = nLower;
    m_nUpper = nUpper;
    m_Progress.SetRange(nLower,nUpper);
}
  
int CProgressDlg::SetPos(int nPos)
{
    PumpMessages();
    int iResult = m_Progress.SetPos(nPos);
    UpdatePercent(nPos);
    return iResult;
}

int CProgressDlg::SetStep(int nStep)
{
    m_nStep = nStep; // Store for later use in calculating percentage
    return m_Progress.SetStep(nStep);
}

int CProgressDlg::OffsetPos(int nPos)
{
    PumpMessages();
    int iResult = m_Progress.OffsetPos(nPos);
    UpdatePercent(iResult+nPos);
    return iResult;
}

int CProgressDlg::StepIt()
{
    PumpMessages();
    int iResult = m_Progress.StepIt();
    UpdatePercent(iResult+m_nStep);
    return iResult;
}

void CProgressDlg::PumpMessages()
{
    // Must call Create() before using the dialog
    ASSERT(m_hWnd!=NULL);

    MSG msg;
    // Handle dialog messages
    while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
      if(!IsDialogMessage(&msg))
      {
        TranslateMessage(&msg);
        DispatchMessage(&msg);  
      }
    }
}


void CProgressDlg::UpdatePercent(int nNewPos)
{
    CWnd *pWndPercent = GetDlgItem(CG_IDC_PROGDLG_PERCENT);
    int nPercent;
    
    int nDivisor = m_nUpper - m_nLower;
    ASSERT(nDivisor>0);  // m_nLower should be smaller than m_nUpper

    int nDividend = (nNewPos - m_nLower);
    ASSERT(nDividend>=0);   // Current position should be greater than m_nLower

    nPercent = nDividend * 100 / nDivisor;

    // Since the Progress Control wraps, we will wrap the percentage
    // along with it. However, don't reset 100% back to 0%
    if(nPercent!=100)
      nPercent %= 100;

    // Display the percentage
    CString strBuf;
    strBuf.Format(_T("%d%c"),nPercent,_T('%'));

	CString strCur; // get current percentage
    pWndPercent->GetWindowText(strCur);

	if (strCur != strBuf)
		pWndPercent->SetWindowText(strBuf);
}
    
/////////////////////////////////////////////////////////////////////////////
// CProgressDlg message handlers

BOOL CProgressDlg::OnInitDialog() 
{
    CDialog::OnInitDialog();
    m_Progress.SetRange(m_nLower,m_nUpper);
    m_Progress.SetStep(m_nStep);
    m_Progress.SetPos(m_nLower);

	CString strCaption;
	VERIFY(strCaption.LoadString(m_nCaptionID));
    SetWindowText(strCaption);

    return 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