www.pudn.com > Hough.rar > HoughDlg.cpp


// HoughDlg.cpp : implementation file
//

#include "stdafx.h"
#include "Hough.h"
#include "HoughDlg.h"
#include "HoughTransform.h"
#include "Bmp.h"
#include "CfgDlg.h"
#include "GlobalVariable.h"
#include "afx.h"


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



/////////////////////////////////////////////////////////////////////////////
// CHoughDlg dialog

CHoughDlg::CHoughDlg(CWnd* pParent /*=NULL*/)
: CDialog(CHoughDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CHoughDlg)
m_sCentersCoord = _T("");
//}}AFX_DATA_INIT
// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CHoughDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CHoughDlg)
DDX_Control(pDX, ID_SOURCE_BMP, m_picSourceImg);
DDX_Text(pDX, IDC_Edit_CircleCenters, m_sCentersCoord);
//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CHoughDlg, CDialog)
//{{AFX_MSG_MAP(CHoughDlg)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_BN_CLICKED(IDOPEN, OnOpen)
ON_BN_CLICKED(IDCONFIG, OnConfig)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CHoughDlg message handlers

BOOL CHoughDlg::OnInitDialog()
{
CDialog::OnInitDialog();

// Set the icon for this dialog. The framework does this automatically
// when the application's main window is not a dialog
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon

//m_sCentersCoord = "";

// TODO: Add extra initialization here
m_FullFilename = "c:\\source.bmp";

return TRUE; // return TRUE unless you set the focus to a control
}

// If you add a minimize button to your dialog, you will need the code below
// to draw the icon. For MFC applications using the document/view model,
// this is automatically done for you by the framework.

void CHoughDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // device context for painting

SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

// Center icon in client rectangle
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&amt;rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;

// Draw the icon
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialog::OnPaint();
}
}

// The system calls this to obtain the cursor to display while the user drags
// the minimized window.
HCURSOR CHoughDlg::OnQueryDragIcon()
{
return (HCURSOR) m_hIcon;
}

void CHoughDlg::OnOK()
{

// 清空圆心图和圆图的显示
((CStatic*)GetDlgItem(ID_CENTER_BMP))->SetBitmap(NULL);
((CStatic*)GetDlgItem(ID_TARGET_BMP))->SetBitmap(NULL);
// 删除圆心图文件和圆图文件
CFileStatus fs;
if (CFile::GetStatus(_T("c:\\centers.bmp"), fs)) // centers.bmp文件存在
{
CFile::Remove("c:\\centers.bmp");
}
if (CFile::GetStatus(_T("c:\\target.bmp"), fs)) // target.bmp文件存在
{
CFile::Remove("c:\\target.bmp");
}
// 清空圆心坐标编辑框
m_sCentersCoord = "";

// TODO: Add extra validation here
BYTE* pPaletteData;
BYTE* pImgData;
//BYTE* pLeftData;
long paletteDataCount,imgDataCount;
//long leftDataCount;
BmpHead bmpHead;
InfoHead infoHead;
CString errorMsg="", info="";

// 读BMP图像到内存

BOOL result = ::ReadBinaryBMP(m_FullFilename, bmpHead, infoHead,
pPaletteData, paletteDataCount,
pImgData, imgDataCount, /*pLeftData, leftDataCount,*/
errorMsg, info);
CString showMsg = result?info:errorMsg;
AfxMessageBox(showMsg);

// 生成两份内存块的拷贝,后面要用
BYTE* pPaletteData2;
BYTE* pImgData2;
BYTE* pPaletteData3;
BYTE* pImgData3;
pPaletteData2 = new BYTE[paletteDataCount];
pPaletteData3 = new BYTE[paletteDataCount];
pImgData2 = new BYTE[imgDataCount];
pImgData3 = new BYTE[imgDataCount];
memcpy(pPaletteData2, pPaletteData, paletteDataCount);
memcpy(pPaletteData3, pPaletteData, paletteDataCount);
memcpy(pImgData2, pImgData, imgDataCount);
memcpy(pImgData3, pImgData, imgDataCount);



CString tmpInfo;
info = "";
errorMsg = "";
int threshold = 85;
int* pDetectedCenterPos;

// int detectedCentersCount;
// // Hough变换检测圆心, 用设阈值法
// ::HoughTransform((unsigned char *)pImgData, infoHead.width, infoHead.height, threshold,
// pDetectedCenterPos, detectedCentersCount);
// info.Format("共检测出>d个圆心", detectedCentersCount);

int circleNum = g_nCircleNum;
int nMaxRadius = g_nMaxRadius;
int edgeThick = g_nEdgeThick;
int nDistBetweenCenters = g_nDistBetweenCenters;
pDetectedCenterPos = new int[circleNum];
// Hough变换检测圆心, 用设置圆个数的方法
::HoughTransform((unsigned char *)pImgData, infoHead.width, infoHead.height, circleNum,
nMaxRadius, edgeThick, nDistBetweenCenters, pDetectedCenterPos);

// 将圆心的坐标写在圆心坐标编辑框
int xPos, yPos;
CString sTemp;
for (int i = 0; i < circleNum; i++)
{
yPos = pDetectedCenterPos[i] / infoHead.width;
xPos = pDetectedCenterPos[i] > infoHead.width;
sTemp.Format("(>d,>d) ", xPos, yPos);
m_sCentersCoord += sTemp;
}
UpdateData(FALSE);

// 将检测出的圆心点画在内存块中
info = "";
errorMsg = "";
BOOL isCircleCenter;
for(int m=0; m<imgDataCount; m++)
{
isCircleCenter = FALSE;
for(int n=0; n<circleNum; n++)
{
if (m == pDetectedCenterPos[n])
{
pImgData2[m] = 255;
isCircleCenter = TRUE; // 是圆心点
break;
}
}
if(!isCircleCenter)
{
pImgData2[m] = 0;
}
}


// 将内存的数据块写为centers.bmp文件
BOOL result1 = ::WriteBinaryBMP("c:\\centers.bmp", bmpHead, infoHead,
pPaletteData2, paletteDataCount,
pImgData2, imgDataCount,
/*pLeftData, leftDataCount, */
errorMsg, info); // WriteBinaryBMP内部会释放pImgData2、指针所指内存块
CString showMsg2 = result?info:errorMsg;
// AfxMessageBox(showMsg2);

// 将检测出的圆上的点画在内存数据块中
::DetectCircle((unsigned char* )pImgData3, imgDataCount, infoHead.height,
infoHead.width, nMaxRadius, edgeThick, pDetectedCenterPos, circleNum);
// 将内存的数据块写为target.bmp文件
BOOL result2 = ::WriteBinaryBMP("c:\\target.bmp", bmpHead, infoHead,
pPaletteData3, paletteDataCount,
pImgData3, imgDataCount,
errorMsg, info);
CString showMsg3 = result?info:errorMsg;
// AfxMessageBox(showMsg3);

// 释放原图像内存块
delete pPaletteData;
delete pImgData;
delete pDetectedCenterPos;

// 显示圆心图像
HBITMAP hsource=(HBITMAP)LoadImage(AfxGetInstanceHandle(),"c:\\centers.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
int k = GetLastError();
HBITMAP hbmp = ((CStatic*)GetDlgItem(ID_CENTER_BMP))->SetBitmap(hsource);
// 显示检测出的圆图像
HBITMAP hsource2=(HBITMAP)LoadImage(AfxGetInstanceHandle(),"c:\\target.bmp",IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
int k2 = GetLastError();
HBITMAP hbmp2 = ((CStatic*)GetDlgItem(ID_TARGET_BMP))->SetBitmap(hsource2);


//CDialog::OnOK();
}

void CHoughDlg::OnCancel()
{
// TODO: Add extra cleanup here

CDialog::OnCancel();
}

void CHoughDlg::OnOpen()
{
// TODO: Add your control notification handler code here
AfxMessageBox("本软件只能针对bmp格式的二值(像素值为0或255)图像, \n 且背景为黑色,前景为白色!");
CFileDialog dlg(TRUE);
if(dlg.DoModal() == IDOK)
{
m_FullFilename = dlg.GetPathName();
}



// 显示原图
HBITMAP hsource=(HBITMAP)LoadImage(AfxGetInstanceHandle(),m_FullFilename,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
int i = GetLastError();
HBITMAP hbmp = ((CStatic*)GetDlgItem(ID_SOURCE_BMP))->SetBitmap(hsource);
// 清空圆心图和圆图的显示
((CStatic*)GetDlgItem(ID_CENTER_BMP))->SetBitmap(NULL);
((CStatic*)GetDlgItem(ID_TARGET_BMP))->SetBitmap(NULL);
// 删除圆心图文件和圆图文件
CFileStatus fs;
if (CFile::GetStatus(_T("c:\\centers.bmp"), fs)) // centers.bmp文件存在
{
CFile::Remove("c:\\centers.bmp");
}
if (CFile::GetStatus(_T("c:\\target.bmp"), fs)) // target.bmp文件存在
{
CFile::Remove("c:\\target.bmp");
}
m_sCentersCoord = "";
UpdateData(FALSE);
}

void CHoughDlg::OnConfig()
{
// TODO: Add your control notification handler code here
CCfgDlg cfgDlg;
cfgDlg.DoModal();

}