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

📄 bloodvesseldlg.cpp

📁 对CFileException进行修改后 这个血管提取的程序已经可以在VC8下面编译了 但是还有点内存泄露 没有进行修正 等有时间了在进行修改
💻 CPP
字号:
// BloodVesselDlg.cpp : implementation file
//

#include "stdafx.h"
#include "BloodVessel.h"
#include "BloodVesselDlg.h"
#include "cdib.h"
#include "ximage.h"

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

/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
		// No message handlers
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBloodVesselDlg dialog

CBloodVesselDlg::CBloodVesselDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CBloodVesselDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CBloodVesselDlg)
		// NOTE: the ClassWizard will add member initialization here
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}

void CBloodVesselDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CBloodVesselDlg)
		// NOTE: the ClassWizard will add DDX and DDV calls here
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CBloodVesselDlg, CDialog)
	//{{AFX_MSG_MAP(CBloodVesselDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_BN_CLICKED(IDC_OPEN, OnOpen)
	ON_BN_CLICKED(IDC_BTN_EXTRACT, OnBtnExtract)
	ON_BN_CLICKED(IDC_BTN_BW, OnBtnBw)
	ON_BN_CLICKED(IDC_BTN_FILL, OnBtnFill)
	ON_BN_CLICKED(IDC_BTN_SAVE, OnBtnSave)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CBloodVesselDlg message handlers

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

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// 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
	
	// TODO: Add extra initialization here
	//m_pImag =NULL;
	m_ximag = NULL;
	m_ximagReserve = NULL;

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

void CBloodVesselDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// 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 CBloodVesselDlg::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(&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 CBloodVesselDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CBloodVesselDlg::OnOpen() 
{
	// TODO: Add your control notification handler code here
	CString szFilter;
	szFilter = "BMP Files(*.bmp)|*.bmp|All Files(*.*)|*.*||";

	CFileDialog filedlg(TRUE, NULL, NULL, OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
		szFilter, NULL);
	if (filedlg.DoModal() == IDCANCEL)
		return;

	m_filename = filedlg.GetFileName();

	m_imagRect.left = 20;
	m_imagRect.top = 20;
	m_imagRect.right = m_imagRect.left + 600;
	m_imagRect.bottom = m_imagRect.top + 480;


	if (m_ximag != NULL)
	{
		delete m_ximag;
	}
	if (m_ximagReserve != NULL)
	{
		delete m_ximagReserve;
	}
	m_ximag = new CxImage(m_filename, CXIMAGE_FORMAT_BMP);
	m_ximagReserve = new CxImage(CXIMAGE_FORMAT_BMP);
	*m_ximagReserve = *m_ximag;//copy

	CClientDC dc(this);
	m_ximag->Draw2(dc.GetSafeHdc(), m_imagRect);
	//m_pImag->Draw(&dc, m_imagRect);
	
}

void CBloodVesselDlg::OnBtnExtract() 
{
	// TODO: Add your control notification handler code here
	m_ximag->GrayScale();//灰度化

	int size = m_ximag->GetEffWidth() * m_ximag->GetHeight();

	IM2BW(m_ximag->GetBits(), size, 1);//二值化
	ExtractVessel(m_ximagReserve, m_ximag->GetBits(), 5);//抽取血管

	//m_ximagReserve->GrayScale();//灰度化
	//IM2BW(m_ximagReserve->GetBits(), size, 0.1);//二值化
	//ImDilate(m_ximagReserve->GetBits(), m_ximagReserve->GetWidth(), m_ximagReserve->GetHeight());//膨胀
	//ImErode(m_ximagReserve->GetBits(), m_ximagReserve->GetWidth(), m_ximagReserve->GetHeight());//腐蚀

	CClientDC dc(this);
	m_ximagReserve->Draw2(dc.GetSafeHdc(), m_imagRect);
}

void CBloodVesselDlg::IM2BW(BYTE *pGray, int size, float level)
{
	for (int i = 0; i < size; i++)
	{//*(pGray + i)=255;

		if (*(pGray + i) >= 255 * level)
		{
			*(pGray + i) = 255;
		}
		else *(pGray + i) = 0;
	}
}

void CBloodVesselDlg::ExtractVessel(CxImage *pRGBImage, BYTE *pBW, int bloodWidth)
{
	BYTE *pData = pRGBImage->GetBits();
	int width = pRGBImage->GetWidth();
	int height = pRGBImage->GetHeight();
	int effWidth = pRGBImage->GetEffWidth();
	int half = bloodWidth / 2;
	int ceaseHeight = pRGBImage->GetHeight() - half;
	int ceaseWidth = pRGBImage->GetWidth() - half;

	BOOL flagWhite = FALSE;
	for (int i = half; i < ceaseHeight; i++)
	{
		for (int j = half; j < ceaseWidth; j++)
		{
			flagWhite = NearWhite(pBW, width, height, i, j, bloodWidth);

			BYTE r = *(pData + i * effWidth + j * 3 + 2);
			BYTE g = *(pData + i * effWidth + j * 3 + 1);
			BYTE b = *(pData + i * effWidth + j * 3 + 0);
				
			if (r < 256 && r > 56 && g < 100 && b < 100 && flagWhite)//靠近白线且为红色
			{
				continue;//保留
			}

			else//否则,变为背景
			{
				*(pData + i * effWidth + j * 3 + 0) = 0;
				*(pData + i * effWidth + j * 3 + 1) = 0;
				*(pData + i * effWidth + j * 3 + 2) = 0;
			}
		}
	}
}

BOOL CBloodVesselDlg::NearWhite(BYTE *pBW, int width, int height, int i, int j, int bloodwidth)
{
	BOOL flag = FALSE;
	BOOL over = FALSE;

	int effWidth = (width * 8 + 31) / 32 * 4;
	int half = bloodwidth / 2;
	for (int m = 0; m < bloodwidth; m++)
	{
		for (int n = 0; n < bloodwidth; n++)
		{
			BYTE bw = *(pBW + (i - half + m) * effWidth + (j - half + n));
			if (bw == 255)
			{
				flag = TRUE;
				over = TRUE;
				break;
			}
		}

		if (over)
		{
			break;
		}
	}

	return flag;	
}

void CBloodVesselDlg::ImDilate(BYTE *pData, int width, int height)
{
	int effWidth = (width * 8 + 31) / 32 * 4;
	int maskWidth = 7;
	int half = maskWidth / 2;

	BYTE *pDst = new BYTE[effWidth * height];
	memset(pDst, (BYTE)0, effWidth * height);

	for (int i = half; i <  height - half; i++)
	{
		for (int j = half; j < width - half; j++)
		{
			BOOL over = FALSE;
			for (int m = 0; m < maskWidth; m++)
			{
				for (int n = 0; n < maskWidth; n++)
				{
					BYTE bw = *(pData + (i - half + m) * effWidth + (j - half + n));
					if (bw > 128)//有物体
					{
						*(pDst + i * effWidth + j) = 255;
						over = TRUE;
						break;
					}
				}

				if (over)
				{
					break;
				}
			}

		}
	}

	memcpy(pData, pDst, effWidth * height);
}

void CBloodVesselDlg::ImErode(BYTE *pData, int width, int height)
{
	int effWidth = (width * 8 + 31) / 32 * 4;
	int maskWidth = 7;
	int half = maskWidth / 2;

	BYTE *pDst = new BYTE[effWidth * height];
	memset(pDst, (BYTE)0, effWidth * height);

	for (int i = half; i <  height - half; i++)
	{
		for (int j = half; j < width - half; j++)
		{
			BOOL over = FALSE;
			for (int m = 0; m < maskWidth; m++)
			{
				for (int n = 0; n < maskWidth; n++)
				{
					BYTE bw = *(pData + (i - half + m) * effWidth + (j - half + n));
					if (bw < 128)//有背景
					{
						over = TRUE;
						break;
					}
				}
				if (over)
				{
					break;
				}
			}

			if (!over)//没有背景
			{
				*(pDst + i * effWidth + j) = 255;//保留
			}

		}
	}

	memcpy(pData, pDst, effWidth * height);
}

void CBloodVesselDlg::OnBtnBw() 
{
	// TODO: Add your control notification handler code here
	m_ximagReserve->GrayScale();//灰度化

	int size = m_ximagReserve->GetEffWidth() * m_ximagReserve->GetHeight();
	IM2BW(m_ximagReserve->GetBits(), size, 0.1);//二值化

	CClientDC dc(this);
	m_ximagReserve->Draw2(dc.GetSafeHdc(), m_imagRect);
}

void CBloodVesselDlg::OnBtnFill() 
{
	// TODO: Add your control notification handler code here
	ImDilate(m_ximagReserve->GetBits(), m_ximagReserve->GetWidth(), m_ximagReserve->GetHeight());//膨胀
	ImErode(m_ximagReserve->GetBits(), m_ximagReserve->GetWidth(), m_ximagReserve->GetHeight());//腐蚀

	CClientDC dc(this);
	m_ximagReserve->Draw2(dc.GetSafeHdc(), m_imagRect);
}

void CBloodVesselDlg::OnBtnSave() 
{
	// TODO: Add your control notification handler code here
	if (m_ximagReserve == NULL)
	{
		return;
	}

	CString szFilter;
	szFilter = "BMP Files(*.bmp)|*.bmp|All Files(*.*)|*.*||";

	CFileDialog filedlg(FALSE, "bmp", "vessel", OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
						szFilter, NULL);

	if (filedlg.DoModal() == IDCANCEL)
		return;

	m_filename = filedlg.GetFileName();
	m_ximagReserve->Save(m_filename, CXIMAGE_FORMAT_BMP);//保存
}

⌨️ 快捷键说明

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