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

📄 imganalyse.cpp

📁 用C++实现的数字图像处理各个算法源代码 我精心整理的 很难的啊 希望可以给大家带来帮助
💻 CPP
📖 第 1 页 / 共 2 页
字号:
// ImgAnalyse.cpp: implementation of the CImgAnalyse class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "dip.h"
#include "ImgAnalyse.h"
#include "math.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNCREATE(CImgAnalyse, CObject)

//Diagnostics and dump member functions, overridden
#ifdef _DEBUG
void CImgAnalyse::Dump(CDumpContext &dc) const
{
	//call base class function first
	CObject::Dump(dc);
}
#endif

#ifdef _DEBUG
void CImgAnalyse::AssertValid() const
{
	//call inherited AssertValid first
	CObject::AssertValid();
	//Check CDibObject members...
	ASSERT(m_pDibObject != NULL);	//Must exist
}
#endif

/***********************************************************************
*                                                                      *
*                             图像特征分析类                           *
*                                                                      *
***********************************************************************/

////////////////////////////////////////////////////////////////////////
//构造函数CImgAnalyse()    
//----------------------------------------------------------------------
//基本功能:构造一个CImgAnalyse类的对象,如不传入CDibObject对象。第   
//			一次调用某一个处理函数时必须给出一个CDibObject对象指针。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返    回:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CImgAnalyse::CImgAnalyse()
{

}

////////////////////////////////////////////////////////////////////////
//构造函数CImgAnalyse()    
//----------------------------------------------------------------------
//基本功能:构造一个CImgAnalyse类的对象并传入CDibObject对象。所有的
//			操作都针对该对象,直到另一个对象作为参数被传给图像处理函数。
//----------------------------------------------------------------------
//参数说明:无
//----------------------------------------------------------------------
//返    回:无
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
CImgAnalyse::CImgAnalyse( CDibObject *pDibObject )
{
	m_pDibObject = pDibObject;
}

CImgAnalyse::~CImgAnalyse()
{

}

////////////////////////////////////////////////////////////////////////
//void SetDibObjectClass(CDibObject *pDibObject)   
//----------------------------------------------------------------------
//基本功能:本函数为CImgAnalyse类对象指定一个CDibObject对象指针
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject, 默认为NULL。
//----------------------------------------------------------------------
//返    回:无。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
void CImgAnalyse::SetDibObjectClass( CDibObject *pDibObject )
{
	m_pDibObject = pDibObject;
}

////////////////////////////////////////////////////////////////////////
//函数:BOOL EdgeTrace(CDibObject *pDibObject)
//功能:对灰度图像进行轮廓跟踪并生成链码,结果存储在TraceArray中
//说明:只对二值化后的灰度图像跟踪一个连通成分;
//      跟踪之前,应滤除噪声,建议使用灰值 闭运算去噪并平滑边界。
//返回:跟踪成功则返回TRUE
////////////////////////////////////////////////////////////////////////
BOOL CImgAnalyse::EdgeTrace(CDibObject *pDibObject)
{
	if(m_pDibObject==NULL) return FALSE;
	if(m_pDibObject->GetNumBits()!=8){AfxMessageBox("不是8位灰度图像");return FALSE;}
	
	unsigned char *pOld,*pBits,*pTemp,*pNew,*pNewBits,*pNewTemp;
	int nWidthBytes, nNumColors;
	DWORD offset,BufSize;
	pOld = (BYTE *) m_pDibObject->GetDIBPointer(&nWidthBytes);
	if(pOld == NULL) return FALSE;
	
	nNumColors = m_pDibObject->GetNumColors();
	offset=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD);
	pBits =(unsigned char *)&pOld[offset];
	int nHeight=m_pDibObject->GetHeight();
	int nWidth=m_pDibObject->GetWidth();
	BufSize=nWidthBytes*nHeight ;
	HGLOBAL hNewDib;
	hNewDib = ::GlobalAlloc(GHND,offset+BufSize );
	if( hNewDib == NULL ){
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib() );
		return FALSE;}
	pNew = (unsigned char *) ::GlobalLock( hNewDib );
	if( pNew == NULL )
	{
		::GlobalFree( hNewDib );
		m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
		::GlobalUnlock( m_pDibObject->GetDib());
		return FALSE;
	}
	pNewBits = (unsigned char *)&pNew[offset];
	memcpy(pNew,pOld,offset);
	//设定初始值为255
	memset(pNewBits,(BYTE)255,BufSize);
	
	//是否找到起始点及回到起始点
	bool bFindStartPoint;
	//是否扫描到一个边界点
	bool bFindPoint;
	//起始边界点与当前边界点
	CPoint StartPoint,CurPoint;
	//八个方向和起始扫描方向,依次是左上方、上方、右上方、右方、右下方、下方、左下方和左方。
	int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};
	int BeginDirect;
	
	//清空样板数组中的数据
	TraceArray.RemoveAll();
	//定义一个EdgePoint型结构成员变量存放边界点的信息
	EdgePoint m_EdgePoint;
	
	//先找到最左下方的边界点
	bFindStartPoint=false;
	int i,j;
	for(j=0;j<nHeight && !bFindStartPoint;j++)
	{
		for(i=0;i<nWidth && !bFindStartPoint;i++)
		{
			//指向原图倒数第j行,第i个像素的指针
			pTemp=pBits+nWidthBytes*j+i;
			//取得当前指针处的像素值
			if(*pTemp==0)
			{
				bFindStartPoint=true;
				StartPoint.x=i;
				StartPoint.y=j;
				//指向目标图像的倒数第j行,第i个像素的指针
				pNewTemp=pNewBits+nWidthBytes*j+i;
				*pNewTemp=(BYTE)0;
			}
		}
	}
	//由于起始点是在左下方,故起始扫描沿左上方向
	BeginDirect=0;
	//跟踪边界
	bFindStartPoint=false;
	//从起始点开始扫描
	CurPoint.x=StartPoint.x;
	CurPoint.y=StartPoint.y;
	while(!bFindStartPoint)
	{
		bFindPoint=false;
		while(!bFindPoint)
		{
			//要注意以下判断的顺序
			//判断当前搜索方向上的点是否超出图像左边界
			if((CurPoint.x==0) && (CurPoint.x+Direction[BeginDirect][0]<0)) BeginDirect=1;
			//判断当前搜索方向上的点是否超出图像上边界
			if((CurPoint.y==nHeight-1) && (CurPoint.y+Direction[BeginDirect][1]>nHeight-1)) BeginDirect=3;
			//判断当前搜索方向上的点是否超出图像右边界
			if((CurPoint.x==nWidth-1) && (CurPoint.x+Direction[BeginDirect][0]>nWidth-1)) BeginDirect=5;
			//判断当前搜索方向上的点是否超出图像下边界
			if((CurPoint.y==0) && (CurPoint.y+Direction[BeginDirect][1]<0)) BeginDirect=7;
			
			
			//沿扫描方向查看一个像素
			pTemp=pBits+nWidthBytes*(CurPoint.y+Direction[BeginDirect][1])+(CurPoint.x+Direction[BeginDirect][0]);
			if(*pTemp==0)
			{
				bFindPoint=true;

				/////////////////////////////////////////////////////
				//结构数组中记录的第一个点是最左下边界点,即起始点
				//方向为到下一点的矢量方向,2003年2月20日修改
				m_EdgePoint.CurPoint.x = CurPoint.x;
				m_EdgePoint.CurPoint.y = CurPoint.y;
				m_EdgePoint.nCurVerct = (BYTE)BeginDirect;
				TraceArray.Add(m_EdgePoint);
				////////////////////////////////////////////////////

				CurPoint.x=CurPoint.x+Direction[BeginDirect][0];
				CurPoint.y=CurPoint.y+Direction[BeginDirect][1];
				if(CurPoint.y==StartPoint.y && CurPoint.x==StartPoint.x) bFindStartPoint=true;
				pNewTemp = pNewBits + nWidthBytes * CurPoint.y + CurPoint.x;
				*pNewTemp= (unsigned char)0;
				
				/*//结构数组中记录的第一个点是最左下边界点的下一个邻点,方向为
				//该点的当前矢量;最后一个点为最左下点,2002年5月18日
				m_EdgePoint.CurPoint.x = CurPoint.x;
				m_EdgePoint.CurPoint.y = CurPoint.y;
				m_EdgePoint.nCurVerct = (BYTE)BeginDirect;
				TraceArray.Add(m_EdgePoint);*/

				//扫描的方向逆时针旋转两格
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
			}
			else
			{
				//扫描方向顺时针旋转一格
				BeginDirect++;
				if(BeginDirect == 8)
					BeginDirect = 0;
			}
		}
	}
	::GlobalUnlock(m_pDibObject->GetDib());
	::GlobalFree(m_pDibObject->GetDib());
	::GlobalUnlock(hNewDib );
	
	//将新图像设置为当前图像
	m_pDibObject->SetDib( hNewDib );
	return true;
}

////////////////////////////////////////////////////////////////////////
//函数:Calibrate()
//功能:对图像进行尺寸标定
//参数:X_Scale、Y_Scale、XY_Scale分别为水平、垂直和对角方向的标定系数;
//      realSize为实际尺寸,单位为mm,标定后的系数单位为mm/pixel。
//返回:无
////////////////////////////////////////////////////////////////////////
void CImgAnalyse::Calibrate(float *X_Scale, float *Y_Scale, float *XY_Scale, float realSize)
{
	if(m_pDibObject == NULL) return;
	if(m_pDibObject->GetNumBits()!=8)
	{
		AfxMessageBox("不是8位灰度图像");
		return;
	}
	
	unsigned char *pOld,*pBits,*pTemp;
	int nWidthBytes;
	DWORD offset;
	pOld = (BYTE *) m_pDibObject->GetDIBPointer(&nWidthBytes);
	if(pOld == NULL) return;
	
	offset=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD);
	pBits =(unsigned char *)&pOld[offset];

	int nHeight = m_pDibObject->GetHeight();
	int nWidth = m_pDibObject->GetWidth();

	int i,j,y1,y2,x1,x2;
	//从上向下,逐行搜索像素值为0(黑)的第一个像素点,即为参考物的上切点,记其y坐标为y1。
	for(j=0;j<nHeight;j++)
	{
		pTemp = pBits+(nHeight-j-1)*nWidthBytes;
		for(i=0;i<nWidth;i++)
			if(pTemp[i] == 0)
			{
				y1 = j;
				//跳出两层循环
				j = nHeight;
				break;
			}
	}
	//从下向上,逐行搜索像素值为0(黑)的第一个像素点,即为参考物的下切点,记其y坐标为y2。
	for(j=0;j<nHeight;j++)
	{
		pTemp = pBits+j*nWidthBytes;
		for(i=0;i<nWidth;i++)
			if(pTemp[i] == 0)
			{
				y2 = nHeight-j-1;
				//跳出两层循环
				j = nHeight;
				break;
			}
	}
	//从左向右逐列找出参考物的最左边一个为0(黑)的像素,记为x1
	for(i=0;i<nWidth;i++)
	{
		for(j=0;j<nHeight;j++)
		{
			pTemp = pBits+j*nWidthBytes+i;
			if(*pTemp == 0)
			{
				x1 = i;
				//跳出两层循环
				i = nWidth;
				break;
			}
		}
	}
	//从右向左逐列找出参考物的最右边一个0(黑)的像素,记为x2
	for(i=nWidth-1;i>=0;i--)
	{
		for(j=0;j<nHeight;j++)
		{
			pTemp = pBits+j*nWidthBytes+i;
			if(*pTemp == 0)
			{
				x2 = i;
				//跳出两层循环
				i = -1;
				break;
			}
		}
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -