📄 locateview.cpp
字号:
{
e[lRows].y = K;
r[lRows]++;
lDist = 0;
}
else if (lDist > m_lMaxDist && r[lRows] < m_lMinDotNum)
{
s[lRows].y = K;
e[lRows].y = K;
r[lRows] = 0;
lDist = 0;
}
else if (lDist > m_lMaxDist && r[lRows] >= m_lMinDotNum)
{
lRows++;
break;
}
}// end for K
}// end for L
CPoint pts[1000],pte[1000];
for (int i = 0; i < lRows; i++)
{
lFlag[s[i].x] = TRUE; // 该行有效
pts[s[i].x] = s[i];
pte[s[i].x] = e[i];
// for (int col = s[i].y; col < e[i].y; col++)
// VALUE(s[i].x,col) = 255;
}
::GlobalUnlock((HGLOBAL)GetHDIB());
//////////////////////////////////////////////////////////////////////////
CArray<group,group> grpArray; // 存放候选区域
int nDist = -1;
int nCurS;
int nCurE;
for (i = 0; i < lHeight; i++)
{
if (lFlag[i] == FALSE)
{
if (nDist != -1) // 为-1的时候不考虑,只管跳过
{
nCurE = i;
while (lFlag[i] == FALSE && i < lHeight)
{
i++;
nDist++;
}
if (nDist > m_nMaxGap) // 之间的行间距太大
{
if ((nCurE - nCurS) > m_nMinHeight)
{
group grpTemp;
grpTemp.s = nCurS;
grpTemp.e = nCurE;
grpArray.Add(grpTemp);
}
nDist = -1; // 重新置为-1
}
else
{
nCurE = i;
}
}
}
else // TRUE
{
if (nDist == -1) // 这一行将要成为一个区域的起始行
{
nCurS = nCurE = i;
nDist = 0;
}
else
{
// 求当前的跳变点左端离起始行的跳变点左端距离
if (abs(pts[i].y - pts[nCurS].y) > m_nMaxOffset)
{
nCurE = i; // 一段结束
if ((nCurE - nCurS) > m_nMinHeight)
{
group grpTemp;
grpTemp.s = nCurS;
grpTemp.e = nCurE;
grpArray.Add(grpTemp);
}
nDist = -1;
}
else
{
nCurE = i;
nDist = 0;
}
}
}
}
//////////////////////////////////////////////////////////////////////////
CArray<CRect,CRect> rcArray;
for (i = 0; i < grpArray.GetSize(); i++)
{
for (int j = grpArray[i].s; j <= grpArray[i].e; j++)
{
if (lFlag[j] == TRUE)
{
for (int col = pts[j].y; col < pte[j].y; col++)
VALUE(pts[j].x,col) = 255;
}
}
CRect rcTemp;
double left = 0,right = 0;
int lines = 0;
for (j = grpArray[i].s; j <= grpArray[i].e; j++)
{
if (lFlag[j] == TRUE)
{
left += pts[j].y;
right += pte[j].y;
lines++;
}
}
rcTemp.left = long(left / lines);
rcTemp.right = long(right / lines);
rcTemp.top = grpArray[i].s;
rcTemp.bottom = grpArray[i].e;
if (rcTemp.Width() > rcTemp.Height() && rcTemp.Width() > m_nMinWidth
&& rcTemp.Height() > m_nMinHeight)
{
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;
dlg.m_hDIB = m_hDIB;
LPSTR lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)m_hDIB);//获得当前位图
if (::DIBNumColors(lpDIB) == 256)
{
dlg.DoModal();
}
else
{
AfxMessageBox("必须是256色灰度图!");
}
::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;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -