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

📄 locateview.cpp

📁 车牌定位识别系统地涉及具体由车牌定位
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			{
				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 + -