📄 locateview.cpp
字号:
{
rcArray.Add(rcTemp);
}
}
delete[]lFlag;
Invalidate();
//////////////////////////////////////////////////////////////////////////
memset(m_pzRect,0,sizeof(m_pzRect));
if (rcArray.GetSize() > 0)
{
double min = 1000;
for (i = 0; i < rcArray.GetSize(); i++)
{
double ratio = (double)rcArray[i].Width()/(double)rcArray[i].Height();
if (fabs(ratio - 3.5) < min)
{
min = ratio;
}
}
for (i = 0; i < rcArray.GetSize(); i++)
{
double ratio = (double)rcArray[i].Width()/(double)rcArray[i].Height();
if (ratio == min)
{
break;
}
}
m_pzRect = rcArray[i];
}
}
// 截取集装箱号图像
void CLocateView::OnSubrect()
{
Paste();
/* CRect rect;
rect.left = m_pzRect.left - 20;
rect.right = m_pzRect.right + 20;
rect.bottom = m_pzRect.bottom - 50;
rect.top = m_pzRect.top + 50;
*/
TempSubrect(m_pzRect);
Paste();
}
//剪裁指定区域图像
void CLocateView::TempSubrect(CRect rect)
{
HDIB hDIB,hNewDIB;
hDIB = m_hDIB;
long lWidth; //图像宽度和高度
long lHeight;
// 指向DIB的指针
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);//获得当前位图
// 找到DIB图像象素起始位置
lWidth = ::DIBWidth(lpDIB); //DIB 宽度
lHeight = ::DIBHeight(lpDIB); //DIB 高度
//假定的剪裁区域(车牌附近)
hNewDIB= CropDIB(hDIB,rect);
if (OpenClipboard())
{
EmptyClipboard();
SetClipboardData (CF_DIB, CopyHandle((HANDLE) hNewDIB ));
CloseClipboard();
}
}
// 替换DIB,在功能粘贴中用到该函数
void CLocateView::ReplaceHDIB(HDIB hDIB)
{
// 判断DIB是否为空
if (m_hDIB != NULL)
{
// 非空,则清除
::GlobalFree((HGLOBAL) m_hDIB);
}
// 替换成新的DIB对象
m_hDIB = hDIB;
}
// 初始化DIB对象
void CLocateView::InitDIBData()
{
// 判断调色板是否为空
if (m_palDIB != NULL)
{
// 删除调色板对象
delete m_palDIB;
// 重置调色板为空
m_palDIB = NULL;
}
// 如果DIB对象为空,直接返回
if (m_hDIB == NULL)
{
return;
}
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);
// 判断图像是否过大
if (::DIBWidth(lpDIB) > INT_MAX ||::DIBHeight(lpDIB) > INT_MAX)
{
::GlobalUnlock((HGLOBAL) m_hDIB);
// 释放DIB对象
::GlobalFree((HGLOBAL) m_hDIB);
// 设置DIB为空
m_hDIB = NULL;
CString strMsg;
strMsg = "BMP图像太大!";
// 提示用户
MessageBoxA(strMsg);
// 返回
return;
}
::GlobalUnlock((HGLOBAL) m_hDIB);
// 创建新调色板
m_palDIB = new CPalette;
// 判断是否创建成功
if (m_palDIB == NULL)
{
// 失败,可能是内存不足
::GlobalFree((HGLOBAL) m_hDIB);
// 设置DIB对象为空
m_hDIB = NULL;
// 返回
return;
}
// 调用CreateDIBPalette来创建调色板
if (::CreateDIBPalette(m_hDIB, m_palDIB) == NULL)
{
// 返回空,可能该DIB对象没有调色板
// 删除
delete m_palDIB;
// 设置为空
m_palDIB = NULL;
// 返回
return;
}
}
LRESULT CLocateView::OnDoRealize(WPARAM wParam, LPARAM)
{
ASSERT(wParam != NULL);
// 判断DIB是否为空
if (m_hDIB == NULL)
{
// 直接返回
return 0L;
}
// 获取Palette
CPalette* pPal = GetViewPalette();
if (pPal != NULL)
{
// 获取MainFrame
CMainFrame* pAppFrame = (CMainFrame*) AfxGetApp()->m_pMainWnd;
ASSERT_KINDOF(CMainFrame, pAppFrame);
CClientDC appDC(pAppFrame);
// All views but one should be a background palette.
// wParam contains a handle to the active view, so the SelectPalette
// bForceBackground flag is FALSE only if wParam == m_hWnd (this view)
CPalette* oldPalette = appDC.SelectPalette(pPal, ((HWND)wParam) != m_hWnd);
if (oldPalette != NULL)
{
UINT nColorsChanged = appDC.RealizePalette();
if (nColorsChanged > 0)
{
Invalidate();
}
appDC.SelectPalette(oldPalette, TRUE);
}
else
{
TRACE0("OnPaletteChanged中调用SelectPalette()失败!\n");
}
}
return 0L;
}
// 复制当前图像
void CLocateView::Copy()
{
if (OpenClipboard()) // 打开剪贴板
{
BeginWaitCursor();
// 清空剪贴板
EmptyClipboard();
// 复制当前图像到剪贴板
SetClipboardData (CF_DIB, CopyHandle(m_hDIB) );
// 关闭剪贴板
CloseClipboard();
EndWaitCursor();
}
}
// 粘贴图像
void CLocateView::Paste()
{
// 创建新DIB
HDIB hNewDIB = NULL;
// 打开剪贴板
if (OpenClipboard())
{
// 更改光标形状
BeginWaitCursor();
// 读取剪贴板中的图像
hNewDIB = (HDIB) CopyHandle(::GetClipboardData(CF_DIB));
// 关闭剪贴板
CloseClipboard();
// 判断是否读取成功
if (hNewDIB != NULL)
{
// 替换DIB,同时释放旧DIB对象
ReplaceHDIB(hNewDIB);
// 更新DIB大小和调色板
InitDIBData();
// 实现新的调色板
OnDoRealize((WPARAM)m_hWnd,0);
Invalidate();
}
// 恢复光标
EndWaitCursor();
}
}
// 查看灰度直方图
void CLocateView::OnViewHist()
{
CDlgHistShow dlg;
if (m_hDIB == NULL)
return;
dlg.m_hDIB = m_hDIB;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);//获得当前位图
if (::DIBNumColors(lpDIB) == 256)
{
dlg.DoModal();
}
else
{
return;
}
::GlobalUnlock((HGLOBAL) m_hDIB);
}
// 设置参数
void CLocateView::OnOptionParam()
{
CSetParamtDlg dlg;
dlg.m_lMaxDist = m_lMaxDist;
dlg.m_lMinDotNum = m_lMinDotNum;
dlg.m_nMaxOffset = m_nMaxOffset;
dlg.m_nMaxGap = m_nMaxGap;
dlg.m_nMinHeight = m_nMinHeight;
dlg.m_nMinWidth = m_nMinWidth;
if (dlg.DoModal() == IDOK)
{
m_lMaxDist = dlg.m_lMaxDist;
m_lMinDotNum = dlg.m_lMinDotNum;
m_nMaxOffset = dlg.m_nMaxOffset;
m_nMaxGap = dlg.m_nMaxGap;
m_nMinHeight = dlg.m_nMinHeight;
m_nMinWidth = dlg.m_nMinWidth;
}
}
void CLocateView::OnTempSubrect()
{
HDIB hDIB,hNewDIB;
hDIB=m_hDIB;
long lWidth; //图像宽度和高度
long lHeight;
// 指向DIB的指针
LPSTR lpDIB;
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);//获得当前位图
// 找到DIB图像象素起始位置
lWidth = ::DIBWidth(lpDIB); //DIB 宽度
lHeight = ::DIBHeight(lpDIB); //DIB 高度
//假定的剪裁区域(车牌附近)
//
CRect rect(m_ipzLeft,m_ipzTop,m_ipzRight,m_ipzBottom);
// CRect rect(m_ipzLeft,190,m_ipzRight,240);
//CRect rect(0,190,lWidth,260);
// CRect rect(0,m_ipzTop,lWidth,m_ipzBottom);
hNewDIB= myCropDIB(hDIB,rect);
if (OpenClipboard())
{
EmptyClipboard();
SetClipboardData (CF_DIB, CopyHandle((HANDLE) hNewDIB ));
CloseClipboard();
}
}
void CLocateView::OnFirst()
{
if (m_hDIB == NULL)
return;
unsigned char * lpSrc; //指向原图像象素点的指针
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);//获得当前位图
LPSTR lpDIBBits = ::FindDIBBits(lpDIB);
LONG lWidth = ::DIBWidth(lpDIB); //DIB 宽度
LONG lHeight = ::DIBHeight(lpDIB); //DIB 高度
// 计算图像每行的字节数
LONG lLineBytes = WIDTHBYTES(lWidth * 8);
long lCount[256];
for(long i=0;i<256;i++)
{
lCount[i]=0; //清零
}
if(::DIBNumColors(lpDIB) != 256) //256色位图不作任何处理
{
return;
}
for(i = 0; i < lHeight; i++)
{
for(long j = 0; j < lWidth; j++)
{
// lpSrc=(unsigned char *)lpDIB+lLineBytes*i+j;
lpSrc=(unsigned char *)lpDIBBits+lLineBytes*i+j;
lCount[*(lpSrc)]++;
}
}
//求窗口变换的上限和下限
long temp[16];
int k=0;
for(k=0;k<16;k++)
{
temp[k]=0;
for(i=k*16;i<(k+1)*16;i++)
temp[k]+=lCount[i];
}
long max=0;
int t=0;
for(k=15;k>=0;k--)
{
if(temp[k]>max)
{
max=temp[k];
t=k;
}
}
int bLow=0,bUp=0;
bLow=(t-1)*16;
// bUp=(t+5)*16;
// bLow=100;
bUp=255;
// 阈值(重要)
INT bThre=(INT)((2*bUp+bLow)/3);
// INT bThre = 150;
BeginWaitCursor();
// 调用ThresholdTrans()函数进行阈值变换
ThresholdTrans(lpDIBBits, ::DIBWidth(lpDIB), ::DIBHeight(lpDIB), bThre);
Invalidate();
::GlobalUnlock((HGLOBAL) m_hDIB);
EndWaitCursor();
CStatusBar* pStatus=(CStatusBar*)
AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
pStatus->SetPaneText(0,"二值化处理");
}
void CLocateView::OnMiddle()
{
LPSTR lpDIB; //指向DIB的指针
if (m_hDIB == NULL)
return;
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);//获得当前位图
if(::DIBNumColors(lpDIB) != 256) //256色位图不作任何处理
{
return;
}
BeginWaitCursor();
//用自定义的模板边缘检测
myTemplate(lpDIB);
Invalidate();
::GlobalUnlock((HGLOBAL)m_hDIB);
EndWaitCursor();
CStatusBar* pStatus=(CStatusBar*)
AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
pStatus->SetPaneText(0,"边缘检测处理");
}
void CLocateView::OnLast()
{
LPSTR lpDIB; //指向DIB的指针
long lWidth; //图像宽度和高度
long lHeight;
if (m_hDIB == NULL)
return;
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);//获得当前位图
lWidth = ::DIBWidth(lpDIB); //DIB 宽度
lHeight = ::DIBHeight(lpDIB); //DIB 高度
//水平投影,求取集装箱号图像的上下边缘位置
myHprojectDIB(lpDIB, lWidth, lHeight,&m_ipzTop, &m_ipzBottom) ;
m_ipzLeft=0;
m_ipzRight=lWidth;
//对含集装箱号图像进行剪裁,得到集装箱号高度,原图像宽度的图像
CLocateDoc* pDoc = GetDocument();
HDIB hNewDIB;
CRect rect1(m_ipzLeft,m_ipzTop,m_ipzRight,m_ipzBottom);
hNewDIB= myCropDIB(m_hDIB,rect1);
if (hNewDIB != NULL)
{
// 替换DIB,同时释放旧DIB对象
ReplaceHDIB(hNewDIB);
// 更新DIB大小和调色板
InitDIBData();
// 实现新的调色板
OnDoRealize((WPARAM)m_hWnd,0);
//刷新
Invalidate();
}
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL) m_hDIB);//获得当前位图
lWidth = ::DIBWidth(lpDIB); //DIB 宽度
lHeight =::DIBHeight(lpDIB); //DIB 高度
myVprojectDIB(lpDIB, lWidth, lHeight,&m_ipzLeft, &m_ipzRight) ;
CRect rect2(m_ipzLeft,0,m_ipzRight,lHeight);
hNewDIB= myCropDIB(m_hDIB,rect2);
if (hNewDIB != NULL)
{
// 替换DIB,同时释放旧DIB对象
ReplaceHDIB(hNewDIB);
// 更新DIB大小和调色板
InitDIBData();
// 实现新的调色板
OnDoRealize((WPARAM)m_hWnd,0);
//刷新
Invalidate();
}
::GlobalUnlock((HGLOBAL) m_hDIB);
CStatusBar* pStatus=(CStatusBar*)
AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
pStatus->SetPaneText(0,"投影截取处理");
}
void CLocateView::OnResult()
{
if (m_hDIB == NULL)
return;
Paste();
OnTempSubrect();
Paste();
CStatusBar* pStatus=(CStatusBar*)
AfxGetApp()->m_pMainWnd->GetDescendantWindow(AFX_IDW_STATUS_BAR);
pStatus->SetPaneText(0,"恢复截图处理");
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -