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

📄 morphology.cpp

📁 将数字图像处理的一般算法都集中在一个MFC的框架中
💻 CPP
📖 第 1 页 / 共 3 页
字号:
*
*说明:二值闭运算,m_pImgData为输入,m_pImgDataOut为输出
***********************************************************************/
void Morphology::BinaryClose()
{
	//如果没有结构元素输入,则返回
	if(m_maskBuf==NULL)
		return;

	//灰度图像每行像素所占字节数
	int lineByte=(m_imgWidth+3)/4*4;

	//中间结果缓冲区申请,用来存放腐蚀后的中间结果
	unsigned char *buf=new unsigned char[lineByte*m_imgHeight];

	//先膨胀
	BasicDilationForBinary(m_pImgData, buf,m_imgWidth,m_imgHeight,
		m_maskBuf, m_maskW, m_maskH);

	//后腐蚀
	BasicErosionForBinary(buf, m_pImgDataOut,m_imgWidth,m_imgHeight,
		m_maskBuf, m_maskW, m_maskH);

	//释放缓冲区
	delete []buf;
}

/***********************************************************************
* 函数名称:
* BinaryInnerEdge()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:求二值形态学内边界,m_pImgData为输入,m_pImgDataOut为输出
***********************************************************************/
void Morphology::BinaryInnerEdge()
{
	//如果没有模板输入,则返回
	if(m_maskBuf==NULL)
		return;

	//灰度图像每行像素所占字节数
	int lineByte=(m_imgWidth+3)/4*4;

	//腐蚀
	BasicErosionForBinary(m_pImgData, m_pImgDataOut,m_imgWidth,m_imgHeight,
		m_maskBuf, m_maskW, m_maskH);

	//原始数据减腐蚀结果
	int i, j;
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<lineByte;j++){
			*(m_pImgDataOut+i*lineByte+j) =
				*(m_pImgData+i*lineByte+j)- *(m_pImgDataOut+i*lineByte+j);
		}
	}
	
}

/***********************************************************************
* 函数名称:
* BinaryOuterEdge()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:求二值形态学外边界,m_pImgData为输入,m_pImgDataOut为输出
***********************************************************************/
void Morphology::BinaryOuterEdge()
{
	//如果没有结构元素输入,则返回
	if(m_maskBuf==NULL)
		return;

	//灰度图像每行像素所占字节数
	int lineByte=(m_imgWidth+3)/4*4;

	//腐蚀
	BasicDilationForBinary(m_pImgData, m_pImgDataOut,m_imgWidth,m_imgHeight,
		m_maskBuf, m_maskW, m_maskH);

	//膨胀结果减去原始数据
	int i, j;
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<lineByte;j++){
			*(m_pImgDataOut+i*lineByte+j) -= *(m_pImgData+i*lineByte+j);
		}
	}
}

/***********************************************************************
* 函数名称:
* BinaryContour()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:求二值形态学边界,m_pImgData为输入,m_pImgDataOut为输出
***********************************************************************/
void Morphology::BinaryContour()
{
	//如果没有结构元素输入,则返回
	if(m_maskBuf==NULL)
		return;

	//灰度图像每行像素所占字节数
	int lineByte=(m_imgWidth+3)/4*4;

	//中间结果缓冲区申请,用来存放腐蚀后的中间结果
	unsigned char *buf=new unsigned char[lineByte*m_imgHeight];

	//腐蚀
	BasicErosionForBinary(m_pImgData, buf,m_imgWidth,m_imgHeight,
		m_maskBuf, m_maskW, m_maskH);

	//膨胀
	BasicDilationForBinary(m_pImgData, m_pImgDataOut,m_imgWidth,m_imgHeight,
		m_maskBuf, m_maskW, m_maskH);
	
	//膨胀结果减腐蚀结果
	int i, j;
	for(i=0;i<m_imgHeight;i++){
		for(j=0;j<lineByte;j++){
			*(m_pImgDataOut+i*lineByte+j) -= *(buf+i*lineByte+j);
		}
	}

	//释放缓冲区
	delete []buf;
}


/***********************************************************************
* 函数名称:
* HitAndMiss()
*
*函数参数:
*  unsigned char *imgBufIn   -待变换的输入图像
*  unsigned char *imgBufOut   -输出图像
*  int imgWidth   -图像宽
*  int imgHeight   -图像高
*  struct ElementPair hitMissMask  -击中击不中结构元素对
*
*返回值:
*   无
*
*说明:击中击不中变换,0代表背景,255代表目标
***********************************************************************/
void Morphology::HitAndMiss(unsigned char *imgBufIn, unsigned char *imgBufOut,
					int imgWidth,int imgHeight, ElementPair hitMissMask)						 
{
	//循环变量
	int i, j;

	//标志变量,1表示结构元素对有效,0表示无效
	int validateFlag=1;

	//检查结构元素对是否交集为空,交集若不为空则为无效结构元素对,算法将退出
	for(i=0; i<3;i++){
		for(j=0;j<3;j++){
			if(hitMissMask.hitElement[i*3+j]&&hitMissMask.missElement[i*3+j]){
				validateFlag=0;
				break;
			}
		}
	}

	//非法结构元素对,返回
	if(validateFlag==0)
		return;

	//图像每行像素所占字节数
	int lineByte=(imgWidth+3)/4*4;

	//输出图像置0
	memset(imgBufOut, 0, lineByte*imgHeight);

	//循环变量
	int k,l;
	
	//击中标志变量和击不中标志变量
	int hitFlag, missFlag;

	for(i=1; i<imgHeight-1; i++){
		for(j=1;j<imgWidth-1; j++){
			hitFlag=1;
			missFlag=1;
			for(k=-1;k<=1;k++){
				for(l=-1;l<=1;l++){
					//如果击中结构元素当前位置为1
					if(hitMissMask.hitElement[(k+1)*3+l+1]==1){
						//判断图像对应点是否为0,如果是,则没有击中图像当前点
						if(!*(imgBufIn+(i+k)*lineByte+j+l))
							hitFlag=0;
					}

					//如果击不中结构元素当前位置为1
					if(hitMissMask.missElement[(k+1)*3+l+1]==1){
						//判断图像对应点是否为0,如果是,则没有击中图像当前点
						if(*(imgBufIn+(i+k)*lineByte+j+l))
							missFlag=0;
					}
				}
			}

			//输出点置255
			if(hitFlag&&missFlag)
				*(imgBufOut+i*lineByte+j)=255;
		}
	}
}

/***********************************************************************
* 函数名称:
* DefineElementPair()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:为击中击不中变换的结构元素对m_hitMissMask赋值,共8对
***********************************************************************/
void Morphology::DefineElementPair()
{
	//定义8个方向的击中击不中变换结构元素对
	int i, k, l;
	for(i=0;i<8;i++){
		for(k=0;k<3;k++){
			for(l=0;l<3;l++){
				m_hitMissMask[i].hitElement[k*3+l]=0;
				m_hitMissMask[i].missElement[k*3+l]=0;
			}
		}
	}

	m_hitMissMask[0].hitElement[0]=1;
	m_hitMissMask[0].hitElement[1]=1;
	m_hitMissMask[0].hitElement[2]=1;
	m_hitMissMask[0].hitElement[4]=1;
	m_hitMissMask[0].missElement[6]=1;
	m_hitMissMask[0].missElement[7]=1;
	m_hitMissMask[0].missElement[8]=1;

	m_hitMissMask[1].hitElement[6]=1;
	m_hitMissMask[1].hitElement[7]=1;
	m_hitMissMask[1].hitElement[8]=1;
	m_hitMissMask[1].hitElement[4]=1;
	m_hitMissMask[1].missElement[0]=1;
	m_hitMissMask[1].missElement[1]=1;
	m_hitMissMask[1].missElement[2]=1;

	m_hitMissMask[2].hitElement[2]=1;
	m_hitMissMask[2].hitElement[5]=1;
	m_hitMissMask[2].hitElement[8]=1;
	m_hitMissMask[2].hitElement[4]=1;
	m_hitMissMask[2].missElement[0]=1;
	m_hitMissMask[2].missElement[3]=1;
	m_hitMissMask[2].missElement[6]=1;

	m_hitMissMask[3].hitElement[0]=1;
	m_hitMissMask[3].hitElement[3]=1;
	m_hitMissMask[3].hitElement[6]=1;
	m_hitMissMask[3].hitElement[4]=1;
	m_hitMissMask[3].missElement[2]=1;
	m_hitMissMask[3].missElement[5]=1;
	m_hitMissMask[3].missElement[8]=1;


	m_hitMissMask[4].hitElement[0]=1;
	m_hitMissMask[4].hitElement[1]=1;
	m_hitMissMask[4].hitElement[3]=1;
	m_hitMissMask[4].hitElement[4]=1;
	m_hitMissMask[4].missElement[5]=1;
	m_hitMissMask[4].missElement[7]=1;
	m_hitMissMask[4].missElement[8]=1;

	m_hitMissMask[5].hitElement[5]=1;
	m_hitMissMask[5].hitElement[7]=1;
	m_hitMissMask[5].hitElement[8]=1;
	m_hitMissMask[5].hitElement[4]=1;
	m_hitMissMask[5].missElement[0]=1;
	m_hitMissMask[5].missElement[1]=1;
	m_hitMissMask[5].missElement[3]=1;


	m_hitMissMask[6].hitElement[1]=1;
	m_hitMissMask[6].hitElement[2]=1;
	m_hitMissMask[6].hitElement[5]=1;
	m_hitMissMask[6].hitElement[4]=1;
	m_hitMissMask[6].missElement[3]=1;
	m_hitMissMask[6].missElement[6]=1;
	m_hitMissMask[6].missElement[7]=1;

	m_hitMissMask[7].hitElement[3]=1;
	m_hitMissMask[7].hitElement[6]=1;
	m_hitMissMask[7].hitElement[7]=1;
	m_hitMissMask[7].hitElement[4]=1;
	m_hitMissMask[7].missElement[1]=1;
	m_hitMissMask[7].missElement[2]=1;
	m_hitMissMask[7].missElement[5]=1;
}


/***********************************************************************
* 函数名称:
* MorphoThinning()
*
*函数参数:
*  无
*
*返回值:
*   无
*
*说明:用击中击不中变换对输入图像进行细化
***********************************************************************/
void Morphology::MorphoThinning()
{
	//定义8个方向的结构元素对
	DefineElementPair();


	//灰度图像每行像素所占字节数
	int lineByte=(m_imgWidth+3)/4*4;

	//申请缓冲区,存放中间结果
	unsigned char *buf=new unsigned char[lineByte*m_imgHeight];
	memcpy(buf, m_pImgData, lineByte*m_imgHeight);

	//循环变量
	int i, k, l;

	//thinFlag用来记录当前一个循环周期内是否有细化掉的点,如果为0表明没
	//有可以细化的点存在,细化终止	
	int thinFlag=1;
	while(thinFlag){
		thinFlag=0;
		//用8个方向的结构元素对都对图像作一次击中击不中变换,并将输出结果
		//从原图中去除
		for(i=0;i<8;i++){
			HitAndMiss(buf, m_pImgDataOut, m_imgWidth, m_imgHeight,m_hitMissMask[i]);
			//将击中击不中变换的输出结果从原数据中去除
			for(k=0;k<m_imgHeight;k++){
				for(l=0;l<lineByte;l++){
					if(*(m_pImgDataOut+k*lineByte+l)==255){
						*(buf+k*lineByte+l)=0;
						thinFlag=1;
					}
				}
			}
		}
	}

	//把最后细化的结果拷贝到m_pImgDataOut
	memcpy(m_pImgDataOut, buf,  lineByte*m_imgHeight);

	//释放缓冲区
	delete []buf;

}

/***********************************************************************
* 函数名称:
* BasicErosionForGray()
*
*函数参数:
*  unsigned char *imgBufIn   -待腐蚀的图像
*  unsigned char *imgBufOut  -腐蚀后的结果
*  int imgWidth   -图像宽
*  int imgHeight   -图像高
*  int *maskBuf   -结构元素缓冲区指针
*  int maskW   -结构元素宽
*  int maskH   -结构元素高
*
*返回值:
*   无
*
*说明:灰值腐蚀基本运算,后面的灰值开/闭/形态学梯度等操作都要调用这个函数
***********************************************************************/
void Morphology::BasicErosionForGray(unsigned char *imgBufIn,
					unsigned char *imgBufOut,int imgWidth,int imgHeight,
					int *maskBuf, int maskW, int maskH)
{
	//循环   变量
	int i,j,k,l;

	//灰度图像每行像素所占字节数
	int lineByte=(imgWidth+3)/4*4;

	//申请缓冲区存放中间结果
	unsigned char *buf=new unsigned char[(imgHeight+maskH)*(lineByte+maskW)];

	//将输入图像,上下加m_maskH/2个像素的灰度为255的亮边,左右加m_maskW/2个像
	//素的灰度为255的亮边,加边后的图像存入buf
	for(i=0;i<imgHeight+maskH;i++)
	{
		for(j=0;j<lineByte+maskW;j++)
		{
			if(i<maskH/2||i>=imgHeight+maskH/2||j<maskW/2||j>=lineByte+maskW/2)
				*(buf+i*(lineByte+maskW)+j)=255;
			else
				*(buf+i*(lineByte+maskW)+j)=*(imgBufIn+(i-maskH/2)*lineByte+j-maskW/2);

⌨️ 快捷键说明

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