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

📄 locateview.cpp

📁 集装箱号码演示程序1.0完美版本
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		{
			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 + -