www.pudn.com > imageFeatures_Ver3_0_source.zip > ImageFeaturesDoc.cpp
// ImageFeaturesDoc.cpp : implementation of the CImageFeaturesDoc class
// This code is partially Wizard generated.
//
#include "stdafx.h"
#include "ImageFeatures.h"
#include "ImageFeaturesDoc.h"
#include "VisDisplay.h"
#include "Options.h"
#include "TestImage.h"
#include "quad_dis.h"
#include "CannyDlg.h"
#include "profile.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CImageFeaturesDoc
IMPLEMENT_DYNCREATE(CImageFeaturesDoc, CDocument)
BEGIN_MESSAGE_MAP(CImageFeaturesDoc, CDocument)
//{{AFX_MSG_MAP(CImageFeaturesDoc)
ON_COMMAND(ID_PROCESS_FIND, OnProcessFind)
ON_COMMAND(ID_PROCESS_GRID, OnProcessGrid)
ON_COMMAND(ID_VIEW_GRAPHICALOUTPUT, OnViewGraphicaloutput)
ON_COMMAND(ID_VIEW_GRIDFILE, OnViewGridfile)
ON_COMMAND(ID_VIEW_TEXTOUTPUT, OnViewTextoutput)
ON_COMMAND(ID_PROCESS_OPTIONS, OnProcessOptions)
ON_COMMAND(ID_PROCESS_TESTCASES_EDGES, OnProcessTestEdges)
ON_COMMAND(ID_PROCESS_TESTCASES_BARS, OnProcessTestBars)
ON_UPDATE_COMMAND_UI(ID_VIEW_GRAPHICALOUTPUT, OnUpdateViewGraphicaloutput)
ON_UPDATE_COMMAND_UI(ID_VIEW_TEXTOUTPUT, OnUpdateViewTextoutput)
ON_COMMAND(ID_VIEW_EDGESONLY, OnViewEdgesonly)
ON_UPDATE_COMMAND_UI(ID_VIEW_EDGESONLY, OnUpdateViewEdgesonly)
ON_UPDATE_COMMAND_UI(ID_VIEW_GRIDFILE, OnUpdateViewGridfile)
ON_COMMAND(ID_PROCESS_TESTCASES_TAPEREDBARS, OnProcessTestTaperedBars)
ON_COMMAND(ID_PROCESS_TESTCASES_STOPPEDBARS, OnProcessTestStoppedBars)
ON_COMMAND(ID_PROCESS_TESTCASES_SOLID3WAY, OnProcessTestSolid3way)
ON_COMMAND(ID_PROCESS_TESTCASES_SEPARATEDCORNERS, OnProcessTestSeparatedCorners)
ON_COMMAND(ID_PROCESS_TESTCASES_FORKSYY, OnProcessTestForks)
ON_COMMAND(ID_PROCESS_TESTCASES_EDGERESOLUTION, OnProcessTestEdgeResolution)
ON_COMMAND(ID_PROCESS_TESTCASES_DOUBLECORNERS, OnProcessTest2Corners)
ON_COMMAND(ID_PROCESS_TESTCASES_DISKS, OnProcessTestDisks)
ON_COMMAND(ID_PROCESS_TESTCASES_CURVES, OnProcessTestCurves)
ON_COMMAND(ID_PROCESS_TESTCASES_CROSSESX, OnProcessTestCross)
ON_COMMAND(ID_PROCESS_TESTCASES_CORNERS, OnProcessTestCorners)
ON_COMMAND(ID_PROCESS_TESTCASES_BLOBS, OnProcessTestBlobs)
ON_COMMAND(ID_PROCESS_TESTCASES_BARRESOLURION, OnProcessTestBarResolurion)
ON_COMMAND(ID_PROCESS_TESTCASES_ANGLEBARS, OnProcessTestAngleBars)
ON_COMMAND(ID_CANNY, OnProcessCanny)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CImageFeaturesDoc construction/destruction
CImageFeaturesDoc::CImageFeaturesDoc()
{
// TODO: add one-time construction code here
// m_ImageHandler.ConnectToSource(((CImageFeaturesApp*)AfxGetApp())->m_imagesource, true, false);
// m_ImageHandler.SetThreadPriority(THREAD_PRIORITY_BELOW_NORMAL);
// m_ImageHandler.SetImagePtr(&m_image);
}
CImageFeaturesDoc::~CImageFeaturesDoc()
{
}
BOOL CImageFeaturesDoc::OnNewDocument()
{
// We don't want to have documents that are not associated with files.
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// CImageFeaturesDoc serialization
void CImageFeaturesDoc::Serialize(CArchive& ar)
{
if (ar.IsStoring())
{
// Saving is handled in CImageFeaturesDoc::OnSaveDocument, so this
// function shouldn't get called.
assert(0);
}
else
{
// Loading is handled in CImageFeaturesDoc::OnOpenDocument, so this
// function shouldn't get called.
assert(0);
}
}
/////////////////////////////////////////////////////////////////////////////
// CImageFeaturesDoc diagnostics
#ifdef _DEBUG
void CImageFeaturesDoc::AssertValid() const
{
CDocument::AssertValid();
}
void CImageFeaturesDoc::Dump(CDumpContext& dc) const
{
CDocument::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CImageFeaturesDoc commands
BOOL CImageFeaturesDoc::OnOpenDocument(LPCTSTR lpszPathName)
{
try
{
m_image.ReadFile(lpszPathName);
}
catch (...) // "..." is bad - we could leak an exception object.
{
// Try using a grayscale image and then copying the pixels to
// our color image.
CVisByteImage image;
try
{
image.ReadFile(lpszPathName);
m_image.Allocate(image.Rect());
image.CopyPixelsTo(m_image);
}
catch (...) // "..." is bad - we could leak an exception object.
{
// Give up trying to read an image from this file.
// Warn the user.
AfxMessageBox("The file specified could not be opened.");
return FALSE;
}
}
// Fill in the CProcessFeature for this image.
CRect bounds = m_image.Rect();
m_process.SetBounds( bounds );
m_process.SetImage( &m_image );
return TRUE;
}
BOOL CImageFeaturesDoc::OnSaveDocument(LPCTSTR lpszPathName)
{
try
{
m_image.WriteFile(lpszPathName);
}
catch(CVisFileIOError& e)
{
AfxMessageBox(e.FullMessage());
return FALSE;
}
catch (...) // "..." is bad - we could leak an exception object.
{
// Warn the user.
AfxMessageBox("The file cound not be saved.");
return FALSE;
}
return TRUE;
}
void CImageFeaturesDoc::DeleteContents()
{
// Invalidate the image.
CDefaultImage imageT;
m_image = imageT;
CDocument::DeleteContents();
}
/*------------------------------------------------------------------------*/
// Call the routines to find and display features
void CImageFeaturesDoc::OnProcessFind()
{
#ifdef PROFILE_ME
CProfileManager::Reset();
PROFILE("OnProcessFind");
#endif // PROFILE_ME
// Do all the work
if (!m_process.Process( eMakeGrid ))
{
AfxMessageBox("Bad or missing 'Grid.txt'");
return;
}
if (!m_process.WriteFeatureList(1))
{
AfxMessageBox("Can't write text results");
}
if (m_viewText)
{
if(!DisplayText())
{
AfxMessageBox("Can't display text results");
}
}
if (m_viewGraphics)
{
DisplayFeatureImage();
}
#ifdef PROFILE_ME
CProfileManager::Write();
#endif // PROFILE_ME
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessCanny()
{
m_pCanny = new Canny( &m_image);
CannyDlg cannydlg;
cannydlg.m_Gaussian=1.5;
cannydlg.m_HighTh=5;
cannydlg.m_LowerTh=3;
cannydlg.DoModal();
if(cannydlg.m_Gaussian < 0.25)
{
cannydlg.m_Gaussian = 0.25;
}
if(cannydlg.m_Gaussian > 5.0)
{
cannydlg.m_Gaussian = 5.0;
}
{
#ifdef PROFILE_ME
CProfileManager::Reset();
PROFILE("OnProcessFind");
#endif // PROFILE_ME
m_pCanny->SetGaussianDeviation(cannydlg.m_Gaussian);
m_pCanny->SetHighTreshold(cannydlg.m_HighTh);
m_pCanny->SetLowerTreshold(cannydlg.m_LowerTh);
CVisRGBAByteImage featureImage( m_image.Rect() );
m_pCanny->CannyEdgeDetect(&featureImage);
CVisPane featureImagePane = VisDisplayImage( /* m_image.Rect(), */
featureImage, evispanedispDefault, "Canny" );
delete(m_pCanny);
#ifdef PROFILE_ME
CProfileManager::Write();
#endif // PROFILE_ME
}
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessGrid()
{
// TODO: Add your command handler code here
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnViewGridfile()
{
m_process.m_viewGrid = !m_process.m_viewGrid;
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnUpdateViewGridfile(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_process.m_viewGrid);
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnViewGraphicaloutput()
{
m_viewGraphics = !m_viewGraphics;
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnUpdateViewGraphicaloutput(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_viewGraphics);
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnViewTextoutput()
{
m_viewText = !m_viewText;
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnUpdateViewTextoutput(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_viewText);
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnViewEdgesonly()
{
m_process.m_viewEdgesOnly = !m_process.m_viewEdgesOnly;
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnUpdateViewEdgesonly(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(m_process.m_viewEdgesOnly);
}
/*------------------------------------------------------------------------*/
bool CImageFeaturesDoc::DisplayText()
{
WindowNew();
// To do: display the test
return true;
}
/*------------------------------------------------------------------------*/
// Not yet used. Sample code for opening a window for text or graphics.
void CImageFeaturesDoc::WindowNew()
// void CMDIFrameWnd::OnWindowNew()
{
// Get a pointer to the active MDI child window.
/* CMDIChildWnd* pActiveChild = MDIGetActive();
// CFrameWnd* pFrame = pView->GetParentFrame();
CDocument* pDocument;
if (pActiveChild == NULL ||
(pDocument = pActiveChild->GetActiveDocument()) == NULL)
{
TRACE0("Warning: No active document for WindowNew command.\n");
AfxMessageBox(AFX_IDP_COMMAND_FAILURE);
return; // command failed
}
// otherwise we have a new frame !
CDocTemplate* pTemplate = pDocument->GetDocTemplate();
ASSERT_VALID(pTemplate);
CFrameWnd* pFrame = pTemplate->CreateNewFrame(pDocument, pActiveChild);
if (pFrame == NULL)
{
TRACE0("Warning: failed to create new frame.\n");
return; // command failed
}
pTemplate->InitialUpdateFrame(pFrame, pDocument);
*/
}
/*------------------------------------------------------------------------*/
// Graphical version of features overlaid on the image.
void CImageFeaturesDoc::DisplayFeatureImage()
{
PROFILE("DisplayFeatureImage");
// Create an RGBA version of the image compatible with
// Windows drawing.
CVisRGBAByteImage featureImage( m_image.Rect() );
m_image.CopyPixelsTo( featureImage );
// draw graphics on the image.
m_process.MakeFeatureImage( featureImage );
CVisPane featureImagePane = VisDisplayImage( /* m_image.Rect(), */
featureImage, evispanedispDefault, "Features found" );
// For some reason, the lines drawn in featureImage show up in m_image
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessOptions()
{
COptions optionsDialog;
optionsDialog.TransferData( &m_process, true);
optionsDialog.DoModal();
optionsDialog.TransferData( &m_process, false);
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessTestEdges()
{
int width = 4 * m_process.m_filterDiam;
int height = 4 * m_process.m_filterDiam;
CTestImage base( width, height );
int mode = ios::out;
char title[80];
CTime theTime = CTime::GetCurrentTime();
CString date = theTime.Format( "%B %d, %Y" ); // date == "March 19, 1991"
sprintf(title, "Edges of contrast %d on %s.",
m_process.m_testImageContrast, LPCTSTR(date));
for (int angle = 90; angle >= 40; angle -= 10)
{
base.MakeEdge( m_process.m_testImageContrast );
base.Rotate(angle);
m_image.Allocate(base.Rect());
m_process.SetBounds(base.Rect());
base.CopyPixelsTo(m_image);
float x = ((float) width - 3) / 2;
float y = ((float) height - 3) / 2;
m_process.Process( eTest1D );
m_process.SetAnswer( eEDGE, x, y, (float) angle,
(float) m_process.m_testImageContrast / MEDIUM_GRAY );
m_process.WriteFeatureList(2, mode, title);
if (m_process.m_displayTestImages)
{
DisplayFeatureImage();
}
base.AddNoise( m_process.m_testImageNoise);
m_image.Allocate(base.Rect());
base.CopyPixelsTo(m_image);
m_process.Process( eTest1D );
mode = ios::app;
m_process.WriteFeatureList(2, mode, title, m_process.m_testImageNoise);
if (m_process.m_displayTestImages)
{
DisplayFeatureImage();
}
}
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessTestEdgeResolution()
{
int oldDiam = m_process.m_filterDiam;
bool oldDisplay = m_process.m_displayTestImages;
m_process.m_displayTestImages = false;
for (int diam = 21; diam > 3; diam--)
{
m_process.m_filterDiam = diam;
OnProcessTestEdges();
}
m_process.m_filterDiam = oldDiam;
m_process.m_displayTestImages = oldDisplay;
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessTestBars()
{
int width = 4 * m_process.m_filterDiam;
int height = 4 * m_process.m_filterDiam;
CTestImage base( width, height );
int mode = ios::out;
char title[80];
CTime theTime = CTime::GetCurrentTime();
CString date = theTime.Format( "%B %d, %Y" ); // date == "March 19, 1991"
sprintf(title, "Bars of contrast %d on %s.",
m_process.m_testImageContrast, LPCTSTR(date));
for (int angle = 90; angle >= 85; angle -= 10)
{
for (int barWidth = m_process.m_filterDiam/2; barWidth > 1; barWidth /= 2)
{
base.MakeBar( m_process.m_testImageContrast, barWidth );
base.Rotate(angle);
m_image.Allocate(base.Rect());
m_process.SetBounds(base.Rect());
base.CopyPixelsTo(m_image);
float x = (float) width / 2;
if ((barWidth & 1) == 0)
x -= 0.5; // even bar width
float y = ((float) height - 3) / 2;
m_process.Process( eTest1D );
m_process.SetAnswer( eWHITE_LINE, x, y, (float) angle,
(float) m_process.m_testImageContrast / MEDIUM_GRAY,
(float) barWidth );
m_process.WriteFeatureList(2, mode, title);
if (m_process.m_displayTestImages)
{
DisplayFeatureImage();
}
base.AddNoise( m_process.m_testImageNoise);
m_image.Allocate(base.Rect());
base.CopyPixelsTo(m_image);
m_process.Process( eTest1D );
mode = ios::app;
m_process.WriteFeatureList(2, mode, title, m_process.m_testImageNoise);
if (m_process.m_displayTestImages)
{
DisplayFeatureImage();
}
} // loop on barWidth
}
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessTestBarResolurion()
{
int oldDiam = m_process.m_filterDiam;
bool oldDisplay = m_process.m_displayTestImages;
m_process.m_displayTestImages = false;
for (int diam = 21; diam > 3; diam--)
{
m_process.m_filterDiam = diam;
OnProcessTestEdges();
}
m_process.m_filterDiam = oldDiam;
m_process.m_displayTestImages = oldDisplay;
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessTestCorners()
{
int width = 4 * m_process.m_filterDiam;
int height = 4 * m_process.m_filterDiam;
CTestImage base( width, height );
int mode = ios::out;
char title[80];
CTime theTime = CTime::GetCurrentTime();
CString date = theTime.Format( "%B %d, %Y" ); // date == "March 19, 1991"
sprintf(title, "Corners of contrast %d on %s.",
m_process.m_testImageContrast, LPCTSTR(date));
for (int angle = 180; angle >= 0; angle -= 20)
{
base.MakeCorner( m_process.m_testImageContrast );
base.Rotate(angle);
m_image.Allocate(base.Rect());
m_process.SetBounds(base.Rect());
base.CopyPixelsTo(m_image);
float x = (float) (width - 1) / 2;
float y = (float) (height - 1) / 2;
m_process.Process( eTest2D );
m_process.SetAnswer( eDARK_CORNER, x, y, (float) angle,
(float) m_process.m_testImageContrast / MEDIUM_GRAY );
m_process.WriteFeatureList(2, mode, title);
if (m_process.m_displayTestImages)
{
DisplayFeatureImage();
}
/*
base.AddNoise( m_process.m_testImageNoise);
m_image.Allocate(base.Rect());
base.CopyPixelsTo(m_image);
m_process.Process( eTest1D );
mode = ios::app;
m_process.WriteFeatureList(2, mode, title, m_process.m_testImageNoise);
if (m_process.m_displayTestImages)
{
DisplayFeatureImage();
} */
}
}
/*------------------------------------------------------------------------*/
void CImageFeaturesDoc::OnProcessTestTaperedBars()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestStoppedBars()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestSolid3way()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestSeparatedCorners()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestForks()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTest2Corners()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestDisks()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestCurves()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestCross()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestBlobs()
{
// TODO: Add your command handler code here
}
void CImageFeaturesDoc::OnProcessTestAngleBars()
{
// TODO: Add your command handler code here
}