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

📄 imganalyse.cpp

📁 用C++实现的数字图像处理各个算法源代码 我精心整理的 很难的啊 希望可以给大家带来帮助
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	//计算标定系数
	*X_Scale = realSize/(x2-x1);
	*Y_Scale = realSize/(y2-y1);
	*XY_Scale = (float)sqrt((*X_Scale)*(*X_Scale) + (*Y_Scale)*(*Y_Scale));
}

////////////////////////////////////////////////////////////////////////
//函数:GetEdgePointNum()
//功能:获取边界点数
//返回:返回边界点数
////////////////////////////////////////////////////////////////////////
int CImgAnalyse::GetEdgePointNum()
{
	return	(TraceArray.GetSize());
}

////////////////////////////////////////////////////////////////////////
//函数:AreaByChain()
//功能:由边界链码计算区域面积
//返回:BOOL	计算正确则返回TRUE
////////////////////////////////////////////////////////////////////////
BOOL CImgAnalyse::AreaByChain(float *fArea)
{
	//循环变量
	int i;
	//边界点结构体变量
	EdgePoint m_EdgePoint;
	//边界点数,即TraceArray的大小
	int nNumNode;

	//分别用于存储条件公式中X的增量和2α
	//注意:由于边界跟踪的作用,各方向在数组中的顺序依次为
	//左上方、上方、右上方、右方、右下方、下方、左下方、左方
	//另外:TraceArray中存储的坐标与常用坐标相同,其原点在左下角,Y朝上
	int DetaX[8] = {-1,0,1,1,1,0,-1,-1};
	int Alfa[8] = {1,0,-1,0,1,0,-1,0};

	float sum = 0.0f;
	nNumNode = TraceArray.GetSize();
	if(nNumNode<1)
	{
		AfxMessageBox("是否没有进行轮廓跟踪?\n请进行正确的轮廓跟踪!");
		return FALSE;
	}

	for(i=0;i<nNumNode;i++)
	{
		//获取第i个结点的数据
		m_EdgePoint = TraceArray.GetAt(i);
		sum += m_EdgePoint.CurPoint.y*DetaX[m_EdgePoint.nCurVerct]+0.5f*Alfa[m_EdgePoint.nCurVerct];
	}
	//返回由边界链码计算的面积
	*fArea = sum;

	return (TRUE);
}

////////////////////////////////////////////////////////////
//函数:BOOL AreaByGreen(m_fXScale,m_fYScale,float *fArea)
//功能:利用格林公式求封闭轮廓内的面积,要利用边界点坐标
//参数:m_fXScale,m_fYScale分别为X和Y方向的标定系数
///////////////////////////////////////////////////////////
BOOL CImgAnalyse::AreaByGreen(float m_fXScale, float m_fYScale, float *fArea)
{
	//循环变量
	int i;
	//边界点结构体变量
	EdgePoint m_EdgePoint;
	//边界点数,即TraceArray的大小
	int nNumNode;
	//当前点和下一点的坐标, 第一点的坐标
	int nCurX,nCurY,nNextX,nNextY,nFirstX,nFirstY;

	float sum = 0.0f;

	nNumNode = TraceArray.GetSize();

	if(nNumNode<1)
	{
		AfxMessageBox("是否没有进行轮廓跟踪?\n请进行正确的轮廓跟踪!");
		return FALSE;
	}

	//获取第0个结点的数据
	m_EdgePoint = TraceArray.GetAt(0);
	nCurX = m_EdgePoint.CurPoint.x;
	nCurY = m_EdgePoint.CurPoint.y;
	
	nFirstX = nCurX;
	nFirstY = nCurY;
	for(i=1;i<nNumNode;i++)
	{
		//获取第i个结点的数据
		m_EdgePoint = TraceArray.GetAt(i);
		nNextX = m_EdgePoint.CurPoint.x;
		nNextY = m_EdgePoint.CurPoint.y;
		//对当前点与下一点的X和Y坐标的乘积和累加
		sum += (nCurY*nNextX - nCurX*nNextY);
		nCurX = nNextX;
		nCurY = nNextY;
	}
	//加上最后一点与第0点的X和Y的乘积和
	sum += (nNextY*nFirstX - nNextX*nFirstY);
	//返回由边界坐标计算的面积
	 *fArea = (float)(0.5*m_fXScale*m_fYScale*sum);
	 return (TRUE);
}

////////////////////////////////////////////////////////////
//函数:BOOL PeriByChainCode()
//功能:由边界链码计算封闭区域的周长
//参数:分别为水平、垂直和斜方向的标定系数
////////////////////////////////////////////////////////////
BOOL CImgAnalyse::PeriByChainCode(float m_fXScale, float m_fYScale, float m_fXYScale, float *fP)
{
	//水平、垂直、斜向链码数
	int nHorNum = 0,nVerNum = 0,nDiaNum = 0;
	//循环变量
	int i;
	//边界点结构体变量
	EdgePoint m_EdgePoint;
	//当前矢量方向,即链码方向
	BYTE CurVerct;
	//边界点数,即TraceArray的大小
	int nNumNode;

	nNumNode = TraceArray.GetSize();
	if(nNumNode<1)
	{
		AfxMessageBox("是否没有进行轮廓跟踪?\n请进行正确的轮廓跟踪!");
		return FALSE;
	}

	for(i=0;i<nNumNode;i++)
	{
		//获取第i个结点的数据
		m_EdgePoint = TraceArray.GetAt(i);
		CurVerct = m_EdgePoint.nCurVerct;
		//水平方向链码数
		if(CurVerct==0 || CurVerct==4)
			nHorNum++;
		//垂直方向链码数
		else if(CurVerct==2 || CurVerct==6)
			nVerNum++;
		//斜向链码数
		else
			nDiaNum++;
	}
	//返回由边界链码计算的周长
	*fP = (nHorNum*m_fXScale+nVerNum*m_fYScale+nDiaNum*m_fXYScale);
	return (TRUE);
}

//////////////////////////////////////////////////////////////////
//函数:FourierFactor(int *nDimSize)
//功能:求傅立叶变换子
//参数:nDimSize	int型指针,用于传递数组大小
//返回:double型	变换后的频域数据
double * CImgAnalyse::FourierFactor(int *nDimSize)
{
	int j;
	EdgePoint m_EdgePoint;
	int nNumNode;
	nNumNode = TraceArray.GetSize();
	if(nNumNode<1)
	{
		AfxMessageBox("是否没有进行轮廓跟踪?\n请进行正确的轮廓跟踪!");
		return NULL;
	}

	//用于传递数组大小
	*nDimSize = nNumNode;
	//初始化为一维矩阵
	mFourier = zeros(1,nNumNode);
	//转换为复数矩阵
	mFourier = mcomplex(mFourier);

	for(j=0;j<nNumNode;j++)
	{
		m_EdgePoint = TraceArray.GetAt(j);
		//把X坐标赋予实部
		mFourier.r(j+1) = m_EdgePoint.CurPoint.x;
		//把Y坐标赋予虚部
		mFourier.i(j+1) = m_EdgePoint.CurPoint.y;
	}
	//调用Matlab下的一维傅立叶变换函数
	mFourier = fft(mFourier);
	//求复数的模
	mFourier = msqrt(dot_mul(real(mFourier),real(mFourier))+dot_mul(imag(mFourier),imag(mFourier)));

	double * mdata;
	mdata = new double[nNumNode];
	memcpy(mdata, mFourier.addr(),nNumNode*sizeof(double));
	return mdata;
}

//////////////////////////////////////////////////////////////
//函数:LabelArea(CDibObject *pDibObject)
//功能:对不同的连通成分作不同的标记,同时计算出区域面积和中心坐标
//说明:只对8位二值灰度图像(0和255两种值)有效,需经灰值化。
//参数:若pDibObject为空,则使用当前的图像对象。
//////////////////////////////////////////////////////////////
BOOL CImgAnalyse::LabelArea(CDibObject *pDibObject)
{
	if(pDibObject!=NULL) m_pDibObject=pDibObject;
	if(m_pDibObject==NULL) return(FALSE);
	int nWidth,nHeight;
	nWidth=m_pDibObject->GetWidth();
	nHeight=m_pDibObject->GetHeight();
	//当前像素的邻域方向数组
	int direct[8][2]={{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1}};
	int lx,ly;//当前点的邻点坐标
	unsigned char *pOldBuffer;
	unsigned char *pNewBuffer,*pNewBits,*pNewTemp;
	int nWidthBytes, nNumColors, x, y, i, j, k;
	HGLOBAL hNewDib;
	pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer( &nWidthBytes,m_pDibObject->GetNumBits());
	if(pOldBuffer == NULL) return(FALSE);
	nNumColors = m_pDibObject->GetNumColors();
	//位图数据偏移量
	DWORD offset=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+nNumColors*sizeof(RGBQUAD);
	//位图缓冲区大小
	DWORD dwNewSize=offset+nHeight*nWidthBytes;
	hNewDib=::GlobalAlloc(GHND,dwNewSize);
	if(hNewDib==NULL){AfxMessageBox("Alloc memory error!");return FALSE;}
	pNewBuffer=(unsigned char *)::GlobalLock(hNewDib);
	if(pNewBuffer==NULL)
	{
		::GlobalFree(hNewDib);
		AfxMessageBox("Lock memory error!");
		return FALSE;
	}
	pNewBits=(unsigned char *)&pNewBuffer[offset];
	memcpy(pNewBuffer,pOldBuffer,dwNewSize);

	LabelArray.RemoveAll();
	int label=100;//起始标记号
	LabelResult m_LabelResult;//存放标记结果的结构体
	int NumPixels;//区域面积
	int xStart,yStart;//区域起始点
	long cx,cy;//区域中心坐标
	switch(m_pDibObject->GetNumBits())
	{
	case 8:
		for(y=0;y<nHeight;y++)
		{
			pNewTemp=pNewBits;
			pNewTemp+=y*nWidthBytes;
			for(x=0;x<nWidth; x++)
			{
				if(pNewTemp[x]==255)
				{
					if(label>255){AfxMessageBox("标记太多!");return (FALSE);}
					pNewTemp[x]=label;//赋予当前元素以标记号
					int cnt=1;
					xStart=x;/////////////
					yStart=nHeight-1-y;/////////////
					cx=xStart,cy=yStart;
					NumPixels=1;
					while(cnt)
					{
						cnt=0;//循环标记
						for(j=0;j<nHeight;j++)
						{
							pNewTemp=pNewBits;
							for(k=0;k<nWidth;k++)
							{
								if(pNewTemp[k+j*nWidthBytes]==label)//如果找到一个相同的记号
								{
									for(i=0;i<8;i++)
									{
										lx=k+direct[i][0];
										ly=j+direct[i][1];
										//判断是否超出图像边界
										if(lx>=0 && lx<nWidth && ly>=0 && ly<nHeight)
											//循环标记八邻域
											if(*(pNewTemp+lx+ly*nWidthBytes)==255){
												*(pNewTemp+lx+ly*nWidthBytes)=label;
												NumPixels++;
												cx+=lx;
												cy+=nHeight-1-ly;
												cnt++;}
									}
								}
							}
						}
					}
					if(NumPixels==0){cx=0;cy=0;}
					else
					{
						cx=cx/NumPixels;cy=cy/NumPixels;
					}
					m_LabelResult.nLabelNo=label;
					m_LabelResult.StartPoint.x=xStart;
					m_LabelResult.StartPoint.y=yStart;
					m_LabelResult.CenterPoint.x=cx;
					m_LabelResult.CenterPoint.y=cy;
					m_LabelResult.LabelArea=NumPixels;
					LabelArray.Add(m_LabelResult);
					label=label+1;
				}
			}
		}
		break;
	}
	if(label-100==0){::GlobalUnlock(hNewDib);::GlobalFree(hNewDib);return (FALSE);}
	//将内存解锁和将不再使用的内存释放
	::GlobalUnlock( m_pDibObject->GetDib());
	::GlobalFree(m_pDibObject->GetDib());
	::GlobalUnlock(hNewDib);
	m_pDibObject->SetDib(hNewDib);
	return( TRUE );
}

////////////////////////////////////////////////////////
//函数名称:GetCentroid()
//功    能:返回区域标记LabelArea()中计算的质心坐标
//参    数:无
//返    回:POINT
////////////////////////////////////////////////////////
POINT CImgAnalyse::GetCentroid()
{
	//定义一个LabelResult类型的变量
	LabelResult m_LabelResult;
	
	POINT m_Center;
	if(LabelArray.GetSize() > 0)
	{
		//把模板数组LabelArray的第一个元素的数据赋予变量m_LabelResult
		m_LabelResult = LabelArray.GetAt(0);
		m_Center = m_LabelResult.CenterPoint;
	}
		return (m_Center);
}

⌨️ 快捷键说明

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