📄 cellview.cpp
字号:
// 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 + -