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

📄 cellview.cpp

📁 这是一个细胞识别系统及其开放的源代码
💻 CPP
📖 第 1 页 / 共 5 页
字号:
// CellView.cpp : implementation of the CCellView class
//
#include "stdafx.h"
#include "Cell.h"

#include "CellDoc.h"
#include "CellView.h"

#include "HSI.h"
#include "HSIDlg.h"
#include "HistogramDlg.h"
#include "Set.h"
#include  <math.h>

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

#define MAX_HOLE 625

#define BITMAP_ID 0x4D42 // universal id for a bitmap

#define DISTANCE(x0,y0,x1,y1) sqrt((x0-x1)*(x0-x1)+(y0-y1)*(y0-y1))

/////////////////////////////
// GLOBALS
HBITMAP		g_hBitmap=NULL;
CString		g_csFileName;		// current open file name
int			g_nMapWidth=0;
int			g_nMapHeight=0;
//bool		g_bImgBufferChanged;
RGB			spec_rgb = { 0xff, 0x00, 0x00 };		// 标识色
//RGB		*	g_pOrgImgBuffer;					// 全局的原始图像数据
RGB		*	g_pImgBuffer;							// 全局的图像数据
//RGB		*	g_pImgBufferBack;					// 全局的图像数据 用于redo
BYTE	*	g_pSobelResult;							// Soble运算的结果
HSI		*	g_pHSIBuffer;							// 全局的HSI数据
FLAGS	*	g_pFlags;								// 全局的标志量
FLAGS	*	g_pFlagsBack;							// 全局的标志量

bool		g_bDir4Ero=false;
bool		g_bDir4Dil=false;

long		g_nCellCount=0;
long		g_nCellTotArea=0;


/////////////////////////////////////////////////////////////////////////////
// 用于某些特定函数中的全局
CPoint		scroll_lefttop;							// scroll bar 左上角
double		huegap,intgap,satgap;					// 在FindInVectorHSI中使用.提高效率
long		tot_area,tot_x,tot_y,max_radius;		// 用于递归
vector<CENTER_POINT>	points_temp;				// 用于临时存储CENTER_POINT

int *qh; //queue handle
int *qs, *qst, *qr; //queue save, start, read
long qSz; //queue size (physical)
int xt, yt; //temporary x and y locations
/////////////////////////////////////////////////////////////////////////////
// CCellView

IMPLEMENT_DYNCREATE(CCellView, CScrollView)

BEGIN_MESSAGE_MAP(CCellView, CScrollView)
	//{{AFX_MSG_MAP(CCellView)
	ON_COMMAND(ID_FILE_OPEN, OnFileOpen)
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONUP()
	ON_COMMAND(ID_PROC_HSI, OnProcHsi)
	ON_WM_SETCURSOR()
	ON_COMMAND(ID_EDIT_UNDO, OnEditUndo)
	ON_COMMAND(ID_PROC_SOBEL, OnProcSobel)
	ON_COMMAND(ID_DISP_SOBEL, OnDispSobel)
	ON_COMMAND(ID_PROC_HISTOGRAM, OnProcHistogram)
	ON_COMMAND(ID_PROC_SPEC_COLOR, OnProcSpecColor)
	ON_COMMAND(ID_DISP_EDGE, OnDispEdge)
	ON_COMMAND(ID_DISP_REGION, OnDispRegion)
	ON_COMMAND(ID_PROC_RELOAD, OnProcReload)
	ON_COMMAND(ID_PROC_FINDCENTER, OnProcFindCenter)
	ON_COMMAND(ID_PROC_SOBEL_CORRECT, OnProcSobelCorrect)
	ON_COMMAND(ID_PROC_FORCE_KILL, OnProcForceKill)
	ON_COMMAND(ID_PROC_FORCE_SELE, OnProcForceSele)
	ON_COMMAND(ID_PROC_DILATION, OnProcDilation)
	ON_COMMAND(ID_PROC_EROSION, OnProcErosion)
	ON_COMMAND(ID_PROC_SMOOTH, OnProcSmooth)
	ON_COMMAND(ID_PROC_STAT, OnProcStat)
	ON_COMMAND(ID_PROC_FILLHOLE, FillHoles)
	//}}AFX_MSG_MAP
	// Standard printing commands
	ON_COMMAND(ID_FILE_PRINT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_DIRECT, CScrollView::OnFilePrint)
	ON_COMMAND(ID_FILE_PRINT_PREVIEW, CScrollView::OnFilePrintPreview)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCellView construction/destruction

CCellView::CCellView()
{
	// TODO: add construction code here
	m_DragRectSize.cx = 1;
	m_DragRectSize.cy = 1;

	g_csFileName = "";
	g_pImgBuffer = NULL;
//	g_pOrgImgBuffer = NULL;
//	g_pImgBufferBack = NULL;
	g_pHSIBuffer = NULL;
	g_pFlags = NULL;
	g_pFlagsBack = NULL;
	g_pSobelResult= NULL;

	// 所有布尔量初始化
//	g_bImgBufferChanged=false;

	m_bDrag=false;
	m_bProcHsi=false;
	m_bDispSobel=false;
	m_bIsDispEdge=false;
	m_bFullEdge=false;
	m_bForceKill=false;
	m_bForceAdd=false;

	CSize sz(g_nMapWidth,g_nMapHeight);
	SetScrollSizes(MM_TEXT, sz);
}

CCellView::~CCellView()
{
	if(g_hBitmap)
		DeleteObject(g_hBitmap);
	if(g_pImgBuffer)
		delete[] g_pImgBuffer;
//	if (g_pOrgImgBuffer)
//		delete[] g_pOrgImgBuffer;
//	if (g_pImgBufferBack)
//		delete[] g_pImgBufferBack;
	if(g_pHSIBuffer)
		delete[] g_pHSIBuffer;
	if (g_pSobelResult)
		delete[] g_pSobelResult;
	if(g_pFlags)
		delete[] g_pFlags;
	if (g_pFlagsBack)
		delete[] g_pFlagsBack;
}

BOOL CCellView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CView::PreCreateWindow(cs);
}

/////////////////////////////////////////////////////////////////////////////
// CCellView drawing

void CCellView::OnDraw(CDC* pDC)
{
	int x,y;
	CCellDoc* pDoc = GetDocument();
	ASSERT_VALID(pDoc);
	// TODO: add draw code for native data here
	if(g_hBitmap)
	{
		scroll_lefttop=GetScrollPosition();
		RECT rect;
		GetClientRect(&rect);
		int drawwd,drawht;
		if (g_nMapWidth>rect.right-rect.left)
			drawwd=rect.right-rect.left+1;
		else drawwd=g_nMapWidth;
		if (g_nMapHeight>rect.bottom-rect.top)
			drawht=rect.bottom-rect.top+1;
		else drawht=g_nMapHeight;

		BITMAPINFO bitmapinfo;
		CDC *pdc = GetDC();
		HDC dc = pdc->m_hDC;
		HDC memdc = ::CreateCompatibleDC(dc);
		::SelectObject(memdc, g_hBitmap);
		if (m_bDispSobel) // 显示Sobel
		{
			BYTE *cur_pos=g_pSobelResult;
			for(y = 0; y < g_nMapHeight; y++)
			{
				for(x = 0; x < g_nMapWidth; x++)
				{
					if (x-scroll_lefttop.x>=0 && x-scroll_lefttop.x<=drawwd && y-scroll_lefttop.y>=0 && y-scroll_lefttop.y<=drawht)
						SetPixel(memdc,x,y,RGB(*cur_pos,*cur_pos,*cur_pos));
					cur_pos++;
				}
			}
//			g_bImgBufferChanged=false;
		}
		else
		{
			bitmapinfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
			bitmapinfo.bmiHeader.biWidth = g_nMapWidth;
			bitmapinfo.bmiHeader.biHeight = g_nMapHeight;
			bitmapinfo.bmiHeader.biPlanes = 1;
			bitmapinfo.bmiHeader.biBitCount = 24;
			bitmapinfo.bmiHeader.biCompression = BI_RGB;
			GetDIBits(memdc, g_hBitmap, 0, g_nMapHeight, NULL,
				&bitmapinfo, DIB_RGB_COLORS);
			FlipBitmapData(g_pImgBuffer); // flip it
			SetDIBits(memdc, g_hBitmap, 0, g_nMapHeight, g_pImgBuffer,
				&bitmapinfo, DIB_RGB_COLORS);
			FlipBitmapData(g_pImgBuffer); // flip back
/*			if (m_bIsDispEdge)
			{
				FlipBitmapData(g_pImgBuffer); // flip it
				SetDIBits(memdc, g_hBitmap, 0, g_nMapHeight, g_pImgBuffer,
					&bitmapinfo, DIB_RGB_COLORS);
				FlipBitmapData(g_pImgBuffer); // flip back
			}
			else
			{
				FlipBitmapData(g_pImgBuffer); // flip it
				SetDIBits(memdc, g_hBitmap, 0, g_nMapHeight, g_pImgBuffer,
					&bitmapinfo, DIB_RGB_COLORS);
				FlipBitmapData(g_pImgBuffer); // flip back
			}
*/		}
		::BitBlt(dc, 0, 0, drawwd, drawht, memdc, scroll_lefttop.x, scroll_lefttop.y, SRCCOPY);

		FLAGS* cur_flag;
		if(m_bIsDispEdge)
		{
			for(y = 0; y < g_nMapHeight; y++)
			{
				cur_flag=&g_pFlags[y*g_nMapWidth];
				for(x = 0; x < g_nMapWidth; x++)
				{
					if(cur_flag->edged)
						if (x-scroll_lefttop.x>=0 && x-scroll_lefttop.x<=drawwd && y-scroll_lefttop.y>=0 && y-scroll_lefttop.y<=drawht)
							pdc->SetPixel(x-scroll_lefttop.x, y-scroll_lefttop.y, RGB(spec_rgb.r, spec_rgb.g, spec_rgb.b));
					cur_flag++;
				}
			}
		}
		else // region
		{
			for(y = 0; y < g_nMapHeight; y++)
			{
				cur_flag=&g_pFlags[y*g_nMapWidth];
				for(x = 0; x < g_nMapWidth; x++)
				{
					if(cur_flag->marked)
						if (x-scroll_lefttop.x>=0 && x-scroll_lefttop.x<=drawwd && y-scroll_lefttop.y>=0 && y-scroll_lefttop.y<=drawht)
							pdc->SetPixel(x-scroll_lefttop.x, y-scroll_lefttop.y, RGB(spec_rgb.r, spec_rgb.g, spec_rgb.b));
					cur_flag++;
				}
			}
		}
		CENTER_POINT centerp;
		CPen	pen;
		pen.CreatePen(PS_SOLID, 1, RGB(spec_rgb.r, spec_rgb.g, spec_rgb.b));
		pdc->SelectObject(pen);
		for (int i=0;i<m_vCenterPoints.size();i++)
		{
			centerp=m_vCenterPoints.at(i);
			Arc(pdc->m_hDC,
				centerp.x-scroll_lefttop.x-centerp.radius,
				centerp.y-scroll_lefttop.y-centerp.radius,
				centerp.x-scroll_lefttop.x+centerp.radius,
				centerp.y-scroll_lefttop.y+centerp.radius,
				centerp.x-scroll_lefttop.x+centerp.radius,
				centerp.y-scroll_lefttop.y,
				centerp.x-scroll_lefttop.x+centerp.radius,
				centerp.y-scroll_lefttop.y
				);
		}
		DeleteObject(pen);

		ReleaseDC(pdc);
		::DeleteDC(memdc);
	}
}

/////////////////////////////////////////////////////////////////////////////
// CCellView printing

BOOL CCellView::OnPreparePrinting(CPrintInfo* pInfo)
{
	// default preparation
	return DoPreparePrinting(pInfo);
}

void CCellView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add extra initialization before printing
}

void CCellView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
	// TODO: add cleanup after printing
}

/////////////////////////////////////////////////////////////////////////////
// CCellView diagnostics

#ifdef _DEBUG
void CCellView::AssertValid() const
{
	CView::AssertValid();
}

void CCellView::Dump(CDumpContext& dc) const
{
	CView::Dump(dc);
}

CCellDoc* CCellView::GetDocument() // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CCellDoc)));
	return (CCellDoc*)m_pDocument;
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CCellView message handlers

void CCellView::OnFileOpen() 
{
	// 打开文件对话框
	char		szFilter[] = "位图文件 (*.bmp)|*.bmp|所有文件(*.*)|*.*||";
	CString		szFilename;
	BITMAP		bmp;
	CFileDialog *FileDlg = new CFileDialog(TRUE, NULL, NULL, OFN_OVERWRITEPROMPT, szFilter, NULL);

	if(FileDlg->DoModal() == IDOK)
	{
		szFilename = FileDlg->GetPathName();
		if(!szFilename.IsEmpty())
		{
			HANDLE	handle;
			handle = LoadImage(theApp.m_hInstance, szFilename, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
			if(handle)
			{
				if(g_hBitmap)
					DeleteObject(g_hBitmap);
				InvalidateRect(0, TRUE);
				g_hBitmap = (struct HBITMAP__ *) handle;
				g_csFileName = FileDlg->GetFileName();
				theApp.m_pMainWnd->SetWindowText((LPCTSTR) (g_csFileName + " - Cell"));
			}
			else
			{
				MessageBox("无法打开文件");
				return;
			}
			m_vAllSelected.clear();
			// 所有布尔量初始化
			m_bDrag=false;
			m_bProcHsi=false;
			m_bForceKill=false;
			m_bForceAdd=false;
			m_bDispSobel=false;
			AfxGetApp()->m_pMainWnd->GetMenu()->CheckMenuItem(ID_DISP_SOBEL, MF_UNCHECKED);
			m_bIsDispEdge=false;
			AfxGetApp()->m_pMainWnd->GetMenu()->CheckMenuItem(ID_DISP_REGION, MF_CHECKED);
			AfxGetApp()->m_pMainWnd->GetMenu()->CheckMenuItem(ID_DISP_EDGE, MF_UNCHECKED);
			m_vCenterPoints.clear(); // 清除!

			CDC *pdc = GetDC();
			HDC dc = pdc->m_hDC;
			HDC memdc = ::CreateCompatibleDC(dc);
			CBitmap::FromHandle(g_hBitmap)->GetBitmap(&bmp);
			::SelectObject(memdc, g_hBitmap);

			g_nMapWidth=bmp.bmWidth;
			g_nMapHeight=bmp.bmHeight;

			// 设置滚动条
			CSize sz(g_nMapWidth,g_nMapHeight);
			SetScrollSizes(MM_TEXT, sz);

			// fill g_pImgBuffer
			if (LoadImageBuffer(memdc,(LPSTR)(LPCTSTR)g_csFileName)==0)
				return;

			// 初始化Flags
			if(g_pFlags)
				delete[] g_pFlags;
			g_pFlags = new FLAGS[g_nMapHeight * g_nMapWidth];
			memset(g_pFlags, 0,	g_nMapHeight * g_nMapWidth * sizeof(FLAGS));
			if (g_pFlagsBack)
				delete[] g_pFlagsBack;
			g_pFlagsBack = new FLAGS[g_nMapHeight * g_nMapWidth];
			memset(g_pFlagsBack, 0,	g_nMapHeight * g_nMapWidth * sizeof(FLAGS));

			GenHSIData();

			OnProcSobel(); // 预先生成Sobel信息

			::BitBlt(dc, 0, 0, g_nMapWidth, g_nMapHeight, memdc, 0, 0, SRCCOPY);
			ReleaseDC(pdc);
			::DeleteDC(memdc);
		}
	}

	delete FileDlg;
}

void CCellView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	m_LBDnPoint = point;
	m_LastPoint = point;
	m_bDrag = true;

	// draw selection box
	RECT	currect;
	currect.top = m_LBDnPoint.y;
	currect.left = m_LBDnPoint.x;
	currect.right = point.x;
	currect.bottom = point.y;

	CDC *pdc = GetDC();
	pdc->DrawDragRect(&currect, m_DragRectSize, NULL, m_DragRectSize, NULL, NULL);
	ReleaseDC(pdc);

	CView::OnLButtonDown(nFlags, point);
}

void CCellView::OnMouseMove(UINT nFlags, CPoint point) 
{
	if(m_bDrag)
	{
		RECT	lastrect, currect;
		lastrect.top =		m_LBDnPoint.y > m_LastPoint.y ? m_LastPoint.y : m_LBDnPoint.y;
		lastrect.left =		m_LBDnPoint.x > m_LastPoint.x ? m_LastPoint.x : m_LBDnPoint.x;
		lastrect.right =	m_LBDnPoint.x > m_LastPoint.x ? m_LBDnPoint.x : m_LastPoint.x;
		lastrect.bottom =	m_LBDnPoint.y > m_LastPoint.y ? m_LBDnPoint.y : m_LastPoint.y;
		currect.top =		m_LBDnPoint.y > point.y ? point.y : m_LBDnPoint.y;
		currect.left =		m_LBDnPoint.x > point.x ? point.x : m_LBDnPoint.x;
		currect.right =		m_LBDnPoint.x > point.x ? m_LBDnPoint.x : point.x;
		currect.bottom =	m_LBDnPoint.y > point.y ? m_LBDnPoint.y : point.y;

		SIZE	sz;
		sz.cx = 1;
		sz.cy = 1;

		CDC *pdc = GetDC();
		pdc->DrawDragRect(&currect, m_DragRectSize, &lastrect, m_DragRectSize, NULL, NULL);
		ReleaseDC(pdc);

		m_LastPoint = point;
	}
	
	CView::OnMouseMove(nFlags, point);
}

void CCellView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	if (!m_bDrag) // 安全措施
	{
		CView::OnLButtonUp(nFlags, point);
		return;
	}

	int exchange;
	m_bDrag = false;

	// 画选择框
	m_SelectedRect.left = m_LBDnPoint.x;
	m_SelectedRect.top = m_LBDnPoint.y;
	m_SelectedRect.right = point.x;
	m_SelectedRect.bottom = point.y;

	if(m_SelectedRect.left > m_SelectedRect.right)
	{
		exchange = m_SelectedRect.left;
		m_SelectedRect.left = m_SelectedRect.right;
		m_SelectedRect.right = exchange;
	}

	if(m_SelectedRect.top > m_SelectedRect.bottom)
	{
		exchange = m_SelectedRect.top;
		m_SelectedRect.top = m_SelectedRect.bottom;
		m_SelectedRect.bottom = exchange;
	}

	SIZE	zero;
	zero.cx = 0;
	zero.cy = 0;

	CDC *pdc = GetDC();
	pdc->DrawDragRect(&m_SelectedRect, zero, &m_SelectedRect, m_DragRectSize, NULL, NULL);
	ReleaseDC(pdc);

	m_LastPoint.x = 0;	// 设置为0
	
	if(g_hBitmap)
	{
		if(m_bProcHsi)
		{
			if(m_SelectedRect.left >= m_SelectedRect.right || m_SelectedRect.top >= m_SelectedRect.bottom)
				MessageBox("选择的范围不正确.请重新选择!");
			else
			{
				m_bProcHsi = false;
				CHSIDlg hsiDlg(&m_SelectedRect);
				if(hsiDlg.DoModal() == IDOK)
					ProcHSI(hsiDlg.m_bEx);
			}
		}
		else if (m_bForceKill)
		{
			if(m_SelectedRect.left >= m_SelectedRect.right || m_SelectedRect.top >= m_SelectedRect.bottom)
				MessageBox("选择的范围不正确.请重新选择!");
			else
			{
				m_bForceKill = false;
				m_SelectedRect.left+=scroll_lefttop.x;
				m_SelectedRect.right+=scroll_lefttop.x;
				m_SelectedRect.top+=scroll_lefttop.y;
				m_SelectedRect.bottom+=scroll_lefttop.y;
				for(int j = m_SelectedRect.top; j < m_SelectedRect.bottom; j++)
				{
					for(int i = m_SelectedRect.left; i < m_SelectedRect.right; i++)
					{
						if (i<0 || i>=g_nMapWidth || j<0 || j>=g_nMapHeight)
							continue;

⌨️ 快捷键说明

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