【图像处理】DibImage图像处理常用算子


// DibImage.h: interface for the CDibImage class.
//
//

#if !defined(AFX_DIBIMAGE_H__7DE2EE87_190A_4BFD_BBF3_CCC615C53419__INCLUDED_)
#define AFX_DIBIMAGE_H__7DE2EE87_190A_4BFD_BBF3_CCC615C53419__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define  Pos(i,j)  ((i)*Width + j)
//#define  PosBuf(i,j) (54+sizeof(RGBQUAD)*256 +i*Width + j)

typedef struct
{
	int Height;
	int Width;
}Point;

class CDibImage  
{
public:
	CDibImage();
	virtual ~CDibImage();

public:

/*
	BYTE *pBuffer ——为图像的灰度数据区域;
*/
	
	void Filter(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width); //设置最大最小值
	void FilterBuffer(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width);  //设置最大最小值
	
	void RemoveBlack(BYTE *pBuffer, int nLianTong, int nSetValue, const int Height , const int Width); //消除杂质灰点

	void MidFilter(BYTE *pBuffer, int nNumber, int Height, int Width); //中值滤波

	void Averary(BYTE *pBuffer, int Height, int Width);//均值滤波
	void Filter124(BYTE *pBuffer, int Height, int Width); //3*3的加权中值滤波;中间像素4倍,十字处像素2倍,四角像素1倍
	void ChaoXianAverary(BYTE *pBuffer, int nTValue, int Height, int Width);//该点大于周围8点平均值,则平均值赋给该点,否则不变
	void JuBuAverary(BYTE *pBuffer, int Height, int Width); //局部平均化

	void VertialEdge(BYTE *pBuffer, int Height, int Width);//得到垂直边界Vertial
	void HorizontalEdge(BYTE *pBuffer, int Height, int Width);//得到水平边界horizontal
	void GetEdge(BYTE *pBuffer, int Height, int Width); // 得到图像边界

//锐化
	void SharpenMenXian(BYTE *pBuffer, int nMenXianValue, int Height, int Width);//门限锐化
	void SharpenGuDing(BYTE *pBuffer, int nMenXianValue, int Height, int Width);//特定灰度锐化
	void SharpenErZhiHua(BYTE *pBuffer, int nMenXianValue, int Height, int Width);//二值化梯度锐化

//边缘检测
	void EdgeRobert(BYTE *pBuffer, int Height, int Width);//Robert算子

	void Edge_Temple(BYTE *pBuffer, int Height, int Width, int TempH, int TempW, int TempMX, int TempMY, float *fpArray, float fTempCoef);//算子的模板(卷积运算)
	void EdgeSobel(BYTE *pBuffer, int Height, int Width);//Sobel算子
	void EdgePrewitt(BYTE *pBuffer, int Height, int Width);//Prewitt算子
	void EdgeKrisch(BYTE *pBuffer, int Height, int Width);//Krisch算子
	void EdgeGaussLaplacian(BYTE *pBuffer, int Height, int Width);//GaussLaplacian算子

//图像阈值分割
	void FenGeZhiFangTu(BYTE *pBuffer, float *fTongji, int Height, int Width);  //直方图统计
	void FenGeYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width); // 阈值分割
	void FenGeBanYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width); //半阈值分割
	void FenGeDieDai(BYTE *pBuffer, int Height, int Width); //迭代阈值分割

//轮廓提取
	void OutlineGet(BYTE *pBuffer, int Height, int Width);//轮廓提取
	void OutlineTrack(BYTE *pBuffer, int Height, int Width);//轮廓跟踪

//图像的测量(面积、周长)
	void MeasureBiaoJi(BYTE *pBuffer, int Height, int Width); //对图像区域进行标记
};

#endif // !defined(AFX_DIBIMAGE_H__7DE2EE87_190A_4BFD_BBF3_CCC615C53419__INCLUDED_)


// DibImage.cpp: implementation of the CDibImage class.
//
//

#include "stdafx.h"
#include <string.h>
#include <math.h>

#include "HVSnapPnp.h"
#include "DibImage.h"

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

//
// Construction/Destruction
//




CDibImage::CDibImage()
{

}

CDibImage::~CDibImage()
{

}

//最大最小值
void CDibImage::Filter(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width)
{
	int i,j;
	for (i=0;i<Height;i++)
	{
		for (j=0; j<Width; j++)
		{
			if (pBuffer[Pos(i,j)] > MaxValue)
			{
				pBuffer[Pos(i,j)] = 255;
			}
			else if (pBuffer[Pos(i,j)] < MinValue)
			{
				pBuffer[Pos(i,j)] = 0;
			}	
		}
	}
}


//最大最小值,加白区
void CDibImage::FilterBuffer(BYTE *pBuffer, int MinValue, int MaxValue, int Height, int Width)
{
	int i,j;
 	BYTE *pTemp= new BYTE[Height * Width];
	memcpy(pTemp, pBuffer, Height*Width*sizeof(BYTE));

	for (i=200;i<Height-512;i++)
	{
		for (j=500; j<Width-500; j++)
		{
			if (pTemp[Pos(i,j)] > MaxValue)
			{
				pTemp[Pos(i,j)] = 255;
			}
// 			else if (pData[Pos(i,j)] < MinValue)
// 			{
// 				pTemp[Pos(i,j)] = 0;
// 			}	
		}
	}

	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));

// 	for (i=0;i<200;i++)
// 	{
// 		for (j=0; j<500; j++)
// 		{
// 			pBuffer[Pos(i,j)] = 255;
// 		}
// 	}

	delete []pTemp;
}

//均值滤波
void CDibImage::Averary(BYTE *pBuffer, int Height, int Width)
{
	int i,j;
	int nAverary;

	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));

	for (i=200;i<Height-512;i++)
	{
		for (j=500; j<Width-500; j++)
		{	
			nAverary = 0;
			nAverary = (int)((pBuffer[Pos(i-1,j+1)] + pBuffer[Pos(i-1,j)]+ pBuffer[Pos(i-1,j-1)]
							+ pBuffer[Pos(i,j+1)] + pBuffer[Pos(i,j-1)] + pBuffer[Pos(i+1,j-1)]
							+ pBuffer[Pos(i+1,j)] + pBuffer[Pos(i+1,j+1)])/8);
			*(pTemp+i*Width+j) = nAverary;
		}
	}

	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;

}


/*
功能:中值滤波
参数:int nNumber ——3:3*3中值滤波 ,5:5*5中值滤波
*/
void CDibImage::MidFilter(BYTE *pBuffer, int nNumber, int Height, int Width)
{
	int i,j;
	int m,n,g;
	int nEdge; //n*n忽略的边界;比如:3*3的忽略边界的1条像素
	int nSort, nSortTemp; //排序变量
	long size = Height * Width;
	int MidArray[100];

	BYTE *pTemp = new BYTE[size];
	memcpy(pTemp,0,size*sizeof(BYTE));

	nEdge = (nNumber-1)/2;

//MidFilter	
	for (i=1;i<Height-1;i++)
	{
		for (j=1; j<Width-1; j++)
		{
			g=0;
			for (m=i-nEdge;m<i+nEdge;m++)
			{
				for (n=j-nEdge;n<j+nEdge;n++)
				{
					MidArray[g] = pBuffer[Pos(m,n)];
					g++;
				}
			}

			do
			{
				nSort = 0;
				for (i=0;i<8-1;i++)
				{
					if (MidArray[i] > MidArray[i+1])
					{
						nSortTemp = MidArray[i];
						MidArray[i] = MidArray[i+1];
						MidArray[i+1] = nSortTemp;
						nSort = 1;
					}
				}
			} while (nSort == 1);
			pTemp[Pos(i,j)] = MidArray[5];
		}
	}


//将处理后的pTemp赋给pBuffer
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
		
}


/*
功能:消除杂质灰点
参数:nLianTong——4:连通,8连通
	  nSetValue——设定的周围的灰度平均值

*/
void CDibImage::RemoveBlack(BYTE *pBuffer, int nLianTong, int nSetValue, const int Height , const int Width)
{
	int i,j;
	int n4JunZhi, n8JunZhi;

	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));

	if (nLianTong == 4)
	{
		for (i=1;i<Height-1;i++)
		{
			for (j=1;j<Width-1;j++)
			{
				n4JunZhi = 0;
				n4JunZhi = (pBuffer[Pos(i,j+1)] + pBuffer[Pos(i-1,j)] + pBuffer[Pos(i+1,j)] + pBuffer[Pos(i,j-1)]) / 4;
				if (n4JunZhi > nSetValue)
					pTemp[Pos(i,j)] = 255;		
			}
		}

	}
	else if (nLianTong == 8)
	{
		for (i=1;i<Height-1;i++)
		{
			for (j=1;j<Width-1;j++)
			{
				n8JunZhi = 0;
				n8JunZhi = (pBuffer[Pos(i-1,j+1)]+pBuffer[Pos(i,j+1)]+pBuffer[Pos(i+1,j+1)]
					+pBuffer[Pos(i-1,j)]						+pBuffer[Pos(i+1,j)]
					+pBuffer[Pos(i-1,j-1)]+pBuffer[Pos(i,j-1)]+pBuffer[Pos(i+1,j-1)])/8;
				if (n8JunZhi > nSetValue)
					pTemp[Pos(i,j)] = 255;
				
			}
		}
	}
	else
		AfxMessageBox("请将参数设为:4 或者 8 !");

	delete []pTemp;
}

/*
//3*3的加权中值滤波;(中间像素4倍,十字处像素2倍,四角像素1倍) / 16;
函数说明:
			1  2  1
			2  4  2
			1  2  1
*/
void CDibImage::Filter124(BYTE *pBuffer, int Height, int Width) 
{
	int i,j;
	int nAverary;
	
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));
	
	for (i=1;i<Height-1;i++)
	{
		for (j=1; j<Width-1; j++)
		{	
			nAverary = 0;
			nAverary = (int)((pBuffer[Pos(i-1,j+1)]*1 + pBuffer[Pos(i-1,j)]*2+ pBuffer[Pos(i-1,j-1)]*1
							+ pBuffer[Pos(i,j+1)]*2 + pBuffer[Pos(i,j-1)]*2 + pBuffer[Pos(i+1,j-1)]*1
							+ pBuffer[Pos(i+1,j)]*2 + pBuffer[Pos(i+1,j+1)]*1 + pBuffer[Pos(i,j)]*4) /16);
			*(pTemp+i*Width+j) = nAverary;
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;

}

/*
函数:ChaoXianAverary()——超限邻域平均法
功能说明:选取周围8点像素值,如果该点大于平均值,则平均值赋给该点,否则不变
参数:BYTE *pBuffer —— 图像数据区
	  int nTValue   —— 设定阈值   (判断该点值与平均值)
						 abs(*(pTemp+i*Width+j) - nAverary) > nTValue
*/
void CDibImage::ChaoXianAverary(BYTE *pBuffer, int nTValue, int Height, int Width) 
{
	int i,j;
	int nAverary;
	
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));
	
	for (i=1;i<Height-1;i++)
	{
		for (j=1; j<Width-1; j++)
		{	
			nAverary = 0;
			nAverary = (int)((pBuffer[Pos(i-1,j+1)] + pBuffer[Pos(i-1,j)]+ pBuffer[Pos(i-1,j-1)]
				+ pBuffer[Pos(i,j+1)] + pBuffer[Pos(i,j-1)] + pBuffer[Pos(i+1,j-1)]
				+ pBuffer[Pos(i+1,j)] + pBuffer[Pos(i+1,j+1)]) / 8);
			if (abs(*(pTemp+i*Width+j) - nAverary) > nTValue)
			{
				*(pTemp+i*Width+j) = nAverary;
			}
			
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}

/************************************************************************/
/* 函数:局部平均化 
   说明:取5*5窗口;选取4个五边形,4个六边形,一个边长为3的正方形
		 得到它们的平均值跟方差;采用方差最小的进行平均化。
		 也称为:自适应平滑方法。
*/
/************************************************************************/
void CDibImage::JuBuAverary(BYTE *pBuffer, int Height, int Width) //局部平均化
{
	int i,j,k;  //循环变量
	float JunZhi[9] = {0,0,0,0,0,0,0,0,0}; //某区域均值
	float FangCha[9] = {0,0,0,0,0,0,0,0,0};//某区域方差
	int nData[9] = {0,0,0,0,0,0,0,0,0};    //某区域数据
	int Sum = 0;  //某区域数据之和

	int nNum = 0; //最终选择的区域

	float FangChaMin = 0.0;  //最小方差
	
	BYTE *pTemp = new BYTE[Height * Width];   //中间缓冲区
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));

	for (i=2;i<Height-2;i++)
	{
		for (j=2;j<Width-2;j++)
		{
		//九块区域
			//第一块区域——中间的边长为3的正方形
			nData[0] = pBuffer[Pos(i-1,j+1)];
			nData[1] = pBuffer[Pos(i  ,j+1)];
			nData[2] = pBuffer[Pos(i+1,j+1)];
			nData[3] = pBuffer[Pos(i-1,j  )];
			nData[4] = pBuffer[Pos(i  ,j  )];
			nData[5] = pBuffer[Pos(i+1,j  )];
			nData[6] = pBuffer[Pos(i-1,j-1)];
			nData[7] = pBuffer[Pos(i  ,j-1)];
			nData[8] = pBuffer[Pos(i+1,j-1)];
			
			for (k=0;k<9;k++)
				Sum += nData[k];
			JunZhi[0] = (float)(Sum/9);   //均值
			for (k=0;k<9;k++)
				FangCha[0] += nData[k]*nData[k] - JunZhi[0]*JunZhi[0];  //方差

			//第二块区域——上五边形
			nData[0] = pBuffer[Pos(i-1,j+2)];
			nData[1] = pBuffer[Pos(i  ,j+2)];
			nData[2] = pBuffer[Pos(i+1,j+2)];
			nData[3] = pBuffer[Pos(i-1,j+1)];
			nData[4] = pBuffer[Pos(i  ,j  )];
			nData[5] = pBuffer[Pos(i+1,j+1)];
			nData[6] = pBuffer[Pos(i-1,j+1)];

			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[1] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[1] += nData[k]*nData[k] - JunZhi[1]*JunZhi[1];

			//第三块区域——下五边形
			nData[0] = pBuffer[Pos(i-1,j-2)];
			nData[1] = pBuffer[Pos(i  ,j-2)];
			nData[2] = pBuffer[Pos(i+1,j-2)];
			nData[3] = pBuffer[Pos(i-1,j-1)];
			nData[4] = pBuffer[Pos(i  ,j  )];
			nData[5] = pBuffer[Pos(i+1,j-1)];
			nData[6] = pBuffer[Pos(i-1,j-1)];
			
			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[2] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[2] += nData[k]*nData[k] - JunZhi[2]*JunZhi[2];

			//第四块区域——左五边形
			nData[0] = pBuffer[Pos(i-2,j  )];
			nData[1] = pBuffer[Pos(i-1,j-1)];
			nData[2] = pBuffer[Pos(i-1,j  )];
			nData[3] = pBuffer[Pos(i-2,j-1)];
			nData[4] = pBuffer[Pos(i  ,j  )];
			nData[5] = pBuffer[Pos(i-1,j+1)];
			nData[6] = pBuffer[Pos(i-2,j+1)];
			
			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[3] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[3] += nData[k]*nData[k] - JunZhi[3]*JunZhi[3];

			//第五块区域——右五边形
			nData[0] = pBuffer[Pos(i+2,j  )];
			nData[1] = pBuffer[Pos(i+1,j-1)];
			nData[2] = pBuffer[Pos(i+1,j  )];
			nData[3] = pBuffer[Pos(i+2,j-1)];
			nData[4] = pBuffer[Pos(i  ,j  )];
			nData[5] = pBuffer[Pos(i+1,j+1)];
			nData[6] = pBuffer[Pos(i+2,j+1)];
			
			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[4] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[4] += nData[k]*nData[k] - JunZhi[4]*JunZhi[4];

			//第六块区域——左上六边形
			nData[0] = pBuffer[Pos(i  ,j  )];
			nData[1] = pBuffer[Pos(i-1,j  )];
			nData[2] = pBuffer[Pos(i  ,j+1)];
			nData[3] = pBuffer[Pos(i-2,j+2)];
			nData[4] = pBuffer[Pos(i-1,j+2)];
			nData[5] = pBuffer[Pos(i-1,j+1)];
			nData[6] = pBuffer[Pos(i-2,j+1)];
			
			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[5] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[5] += nData[k]*nData[k] - JunZhi[5]*JunZhi[5];

			//第七块区域——右上六边形
			nData[0] = pBuffer[Pos(i  ,j  )];
			nData[1] = pBuffer[Pos(i+1,j  )];
			nData[2] = pBuffer[Pos(i  ,j+1)];
			nData[3] = pBuffer[Pos(i+2,j+2)];
			nData[4] = pBuffer[Pos(i+1,j+2)];
			nData[5] = pBuffer[Pos(i+1,j+1)];
			nData[6] = pBuffer[Pos(i+2,j+1)];
			
			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[6] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[6] += nData[k]*nData[k] - JunZhi[6]*JunZhi[6];

			//第八块区域——左下六边形
			nData[0] = pBuffer[Pos(i  ,j  )];
			nData[1] = pBuffer[Pos(i-1,j  )];
			nData[2] = pBuffer[Pos(i  ,j-1)];
			nData[3] = pBuffer[Pos(i-2,j-2)];
			nData[4] = pBuffer[Pos(i-1,j-2)];
			nData[5] = pBuffer[Pos(i-1,j-1)];
			nData[6] = pBuffer[Pos(i-2,j-1)];
			
			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[7] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[7] += nData[k]*nData[k] - JunZhi[7]*JunZhi[7];

			//第九块区域——右下六边形
			nData[0] = pBuffer[Pos(i  ,j  )];
			nData[1] = pBuffer[Pos(i+1,j  )];
			nData[2] = pBuffer[Pos(i  ,j-1)];
			nData[3] = pBuffer[Pos(i+2,j-2)];
			nData[4] = pBuffer[Pos(i+1,j-2)];
			nData[5] = pBuffer[Pos(i+1,j-1)];
			nData[6] = pBuffer[Pos(i+2,j-1)];
			
			for (k=0;k<7;k++)
				Sum += nData[k];
			JunZhi[8] = (float)(Sum/7);
			for (k=0;k<7;k++)
				FangCha[8] += nData[k]*nData[k] - JunZhi[8]*JunZhi[8];

			//得到方差最小的那块K区域
			FangChaMin = FangCha[0];
			for (k=0;k<9;k++)
			{
				if (FangChaMin > FangCha[k])
				{
					FangChaMin = FangCha[k];
					nNum = k;
				}
			}
			pTemp[Pos(i,j)] = (int)(JunZhi[k] + 0.5);
		}
	}

	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}

//得到垂直边界Vertial
void CDibImage::VertialEdge(BYTE *pBuffer, int Height, int Width)
{
	int i,j;
	
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));
	
	for (i=1;i<Height-1;i++)
	{
		for (j=1; j<Width-1; j++)
		{	
			pTemp[Pos(i,j)] = abs(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]);
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}


//得到水平边界horizontal
void CDibImage::HorizontalEdge(BYTE *pBuffer, int Height, int Width)
{
	int i,j;
	
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));
	
	for (i=1;i<Height-1;i++)
	{
		for (j=1; j<Width-1; j++)
		{	
			pTemp[Pos(i,j)] = abs(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)]);
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}


// 得到图像边界
void CDibImage::GetEdge(BYTE *pBuffer, int Height, int Width)
{
	int i,j;

	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height * Width * sizeof(BYTE));

	for (i=1;i<Height;i++)
	{
		for (j=1;j<Width;j++)
		{
			pTemp[Pos(i,j)] = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) 
										+ (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)]));
		}
	}

	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}

/************************************************************************/
/* 函数:SharpenMenXian()——门限梯度锐化
   参数:int nMenXianValue——门限值(参考取值:30)
   说明:if( G(i,j) > T)  G(i,j) = G(f(i,j)) + 100;
		 else G(i,j) = f(i,j);
   公式:G(f(i,j)) = sqrt((f(i,j)-f(i,j-1))*(f(i,j)-f(i,j-1)) + (f(i,j)-f(i-1,j))*(f(i,j)-f(i-1,j)))
*/
/************************************************************************/

void CDibImage::SharpenMenXian(BYTE *pBuffer, int nMenXianValue, int Height, int Width)
{
	int i,j;
	int nTemp = 0;
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height * Width * sizeof(BYTE));
	
	for (i=1;i<Height;i++)
	{
		for (j=1;j<Width;j++)
		{
			nTemp = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) 
				+ (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)]));

			if (nTemp > nMenXianValue)   //如果大于门限值(30)
			{
				if (nTemp + 100 > 255)
					pTemp[Pos(i,j)] = 255;
				else 
					pTemp[Pos(i,j)] = nTemp + 100;

			}
			if (nTemp < 30)   //如果小于门限值,则将原数据赋给pTemp
				pTemp[Pos(i,j)] = pBuffer[Pos(i,j)];
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}

/************************************************************************/
/*	函数:	给边缘规定灰度(边缘为255)
			与SharpenMenXian()差不多;只是超过门限值的直接赋255;    
	参数:int nMenXianValue——门限值(参考取值:30)
	说明:if( G(i,j) > T)  G(i,j) = 255;
         else G(i,j) = f(i,j);
	公式:G(f(i,j)) = sqrt((f(i,j)-f(i,j-1))*(f(i,j)-f(i,j-1)) + (f(i,j)-f(i-1,j))*(f(i,j)-f(i-1,j)))
*/
/************************************************************************/
void CDibImage::SharpenGuDing(BYTE *pBuffer, int nMenXianValue, int Height, int Width)
{
	int i,j;
	int nTemp = 0;
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height * Width * sizeof(BYTE));
	
	for (i=1;i<Height;i++)
	{
		for (j=1;j<Width;j++)
		{
			nTemp = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) 
				+ (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)]));
			
			if (nTemp > nMenXianValue)   //如果大于门限值
				pTemp[Pos(i,j)] = 255;
			else
				pTemp[Pos(i,j)] = pBuffer[Pos(i,j)];
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}


/************************************************************************/
/*	函数:	给边缘规定灰度(边缘为255),其他区域为0;
			与SharpenMenXian()差不多;只是超过门限值的直接赋255,其他区域为0;    
	参数:int nMenXianValue——门限值(参考取值:30)
	说明:if( G(i,j) > T)  G(i,j) = 255;
          else G(i,j) = 0;
	公式:G(f(i,j)) = sqrt((f(i,j)-f(i,j-1))*(f(i,j)-f(i,j-1)) + (f(i,j)-f(i-1,j))*(f(i,j)-f(i-1,j)))
*/
/************************************************************************/
void CDibImage::SharpenErZhiHua(BYTE *pBuffer, int nMenXianValue, int Height, int Width)
{
	int i,j;
	int nTemp = 0;
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height * Width * sizeof(BYTE));
	
	for (i=1;i<Height;i++)
	{
		for (j=1;j<Width;j++)
		{
			nTemp = (int)sqrt((pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i,j-1)]) 
				+ (pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)])*(pBuffer[Pos(i,j)] - pBuffer[Pos(i-1,j)]));
			
			if (nTemp > nMenXianValue)   //如果大于门限值
				pTemp[Pos(i,j)] = 255;
			else
				pTemp[Pos(i,j)] = 0;
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}

/************************************************************************/
/*	函数:边缘检测——Robert算子
	公式:G(i,j) = sqrt((f(i,j)-f(i+1,j+1))*((f(i,j)-f(i+1,j+1))+(f(i+1,j)-f(i,j+1))*(f(i+1,j)-f(i,j+1)))
	说明:  (i,j+1)    (i+1,j+1)
	        (i,j  )    (i+1,j  )
*/
/************************************************************************/
void CDibImage::EdgeRobert(BYTE *pBuffer, int Height, int Width)
{
	int i,j;
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height * Width * sizeof(BYTE));

	int nRobert[4] = {0,0,0,0};

	for (i=0;i<Height-1;i++)
	{
		for (j=0;j<Width-1;j++)
		{
			nRobert[0] = pBuffer[Pos(i,j)];
			nRobert[1] = pBuffer[Pos(i,j+1)];
			nRobert[2] = pBuffer[Pos(i+1,j)];
			nRobert[3] = pBuffer[Pos(i+1,j+1)];
			pTemp[Pos(i,j)] = (int)sqrt((nRobert[0]-nRobert[3])*(nRobert[0]-nRobert[3])+(nRobert[2]-nRobert[1])*(nRobert[2]-nRobert[1]));
		}
	}
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}

/************************************************************************/
/*	函数:算子模板处理(原图3*3与模板3*3进行卷积运算)
	参数:	int TempH——模板高
			int TempW——模板宽
			int TempMX——模板中心X
			int TempMY——模板中心Y
			float *fpArray——模板数组指针
			float fTempCoef——模板系数
*/
/************************************************************************/
void CDibImage::Edge_Temple(BYTE *pBuffer, int Height, int Width, int TempH, int TempW, int TempMX, int TempMY, float *fpArray, float fTempCoef)
{
	int i,j,k,l;
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height * Width * sizeof(BYTE));

	float fResoult;
	for (i=TempMY;i<Height-TempH+TempMY+1;i++)
	{
		for (j=TempMX;j<Width-TempW+TempMX+1;j++)
		{
			fResoult = 0;
			for (k=0;k<TempH;k++)
			{
				for (l=0;l<TempW;l++)
				{
					fResoult += pBuffer[Pos((i-TempMY+k), (j-TempMX+1))]*fpArray[k*TempW+l];
					fResoult *= fTempCoef;
					fResoult = (float)fabs(fResoult);
					if (fResoult>255)
						pTemp[Pos(i,j)] = 255;
					else
						pTemp[Pos(i,j)] = (int)(fResoult+0.5);
				}
			}
		}
	}

	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));
	delete []pTemp;
}


/************************************************************************/
/*	函数:边缘检测——Sobel算子(索伯尔算子)
	说明:调用两个模板进行卷积运算,取较大值;(进行水平、垂直边缘检测)
		  具有噪声抑制能力,边缘宽度至少为两个像素;
		  用来提取图像边缘;
		  模板1:   -1  -2  -1    模板2: +1  0  -1
					 0   0   0            +2  0  -2
					+1  +2  +1            +1  0  -1
*/
/************************************************************************/
void CDibImage::EdgeSobel(BYTE *pBuffer, int Height, int Width)
{
	int i,j;

	int TempH = 3;
	int TempW = 3;
	int TempMX = 1;
	int	TempMY = 1;
	float fTempCoef = 1;
	float Template[9];
	
	BYTE *pTemp1 = new BYTE[Height * Width];
	memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE));
	BYTE *pTemp2 = new BYTE[Height * Width];
	memcpy(pTemp2, pBuffer, Height * Width * sizeof(BYTE));

	Template[0] = -1.0;
	Template[1] = -2.0;
	Template[2] = -1.0;
	Template[3] = 0;
	Template[4] = 0;
	Template[5] = 0;
	Template[6] = 1.0;
	Template[7] = 2.0;
	Template[8] = 1.0;

	Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);

	Template[0] = -1.0;
	Template[1] = 0;
	Template[2] = 1.0;
	Template[3] = -2.0;
	Template[4] = 0;
	Template[5] = 2.0;
	Template[6] = -1.0;
	Template[7] = 0;
	Template[8] = 1.0;
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);

	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}

	memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE));
	delete []pTemp1;
	delete []pTemp2;
}

/************************************************************************/
/*	函数:边缘检测——Prewitt算子(普瑞维特算子)
	说明:调用两个模板进行卷积运算,取较大值;(进行水平、垂直边缘检测)
		  具有噪声抑制能力,边缘宽度至少为两个像素;
		  用来提取图像边缘;
		  模板1:   -1  -1  -1    模板2: +1  0  -1
					 0   0   0            +1  0  -1
					+1  +1  +1            +1  0  -1
*/
/************************************************************************/
void CDibImage::EdgePrewitt(BYTE *pBuffer, int Height, int Width)
{
	int i,j;
	
	int TempH = 3;
	int TempW = 3;
	int TempMX = 1;
	int	TempMY = 1;
	float fTempCoef = 1;
	float Template[9];
	
	BYTE *pTemp1 = new BYTE[Height * Width];
	memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE));
	BYTE *pTemp2 = new BYTE[Height * Width];
	memcpy(pTemp2, pBuffer, Height * Width * sizeof(BYTE));
	
	Template[0] = -1.0;
	Template[1] = -1.0;
	Template[2] = -1.0;
	Template[3] = 0;
	Template[4] = 0;
	Template[5] = 0;
	Template[6] = 1.0;
	Template[7] = 1.0;
	Template[8] = 1.0;

	Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	Template[0] = 1.0;
	Template[1] = 0;
	Template[2] = -1.0;
	Template[3] = 1.0;
	Template[4] = 0;
	Template[5] = -1.0;
	Template[6] = 1.0;
	Template[7] = 0;
	Template[8] = -1.0;

	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}
	
	memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE));
	delete []pTemp1;
	delete []pTemp2;
}


/************************************************************************/
/*	函数:边缘检测——Krisch算子(克瑞斯算子)
	说明:调用模板进行卷积运算,取较大值;
		  Krisch算子有8个方向;
*/
/************************************************************************/
void CDibImage::EdgeKrisch(BYTE *pBuffer, int Height, int Width)
{
	int i,j;
	
	int TempH = 3;
	int TempW = 3;
	int TempMX = 1;
	int	TempMY = 1;
	float fTempCoef = 0.5;
	float Template[9];
	
	BYTE *pTemp1 = new BYTE[Height * Width];
	memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE));
	BYTE *pTemp2 = new BYTE[Height * Width];
	memcpy(pTemp2, pBuffer, Height * Width * sizeof(BYTE));

//模板1参数
	Template[0] = 5.0;
	Template[1] = 5.0;
	Template[2] = 5.0;
	Template[3] = -3.0;
	Template[4] = 0;
	Template[5] = -3.0;
	Template[6] = -3.0;
	Template[7] = -3.0;
	Template[8] = -3.0;
	
	Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
//模板2参数
	Template[0] = -3.0;
	Template[1] = 5.0;
	Template[2] = 5.0;
	Template[3] = -3.0;
	Template[4] = 0;
	Template[5] = 5.0;
	Template[6] = -3.0;
	Template[7] = -3.0;
	Template[8] = -3.0;
	
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}

	memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE));

//模板3参数
	Template[0] = -3.0;
	Template[1] = -3.0;
	Template[2] = 5.0;
	Template[3] = -3.0;
	Template[4] = 0;
	Template[5] = 5.0;
	Template[6] = -3.0;
	Template[7] = -3.0;
	Template[8] = 5.0;
	
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);

	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}

	memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE));

//模板4参数
	Template[0] = -3.0;
	Template[1] = -3.0;
	Template[2] = -3.0;
	Template[3] = -3.0;
	Template[4] = 0;
	Template[5] = 5.0;
	Template[6] = -3.0;
	Template[7] = 5.0;
	Template[8] = 5.0;
	
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}
	
	memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE));

//模板5参数
	Template[0] = -3.0;
	Template[1] = -3.0;
	Template[2] = -3.0;
	Template[3] = -3.0;
	Template[4] = 0;
	Template[5] = -3.0;
	Template[6] = 5.0;
	Template[7] = 5.0;
	Template[8] = 5.0;
	
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}
	
	memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE));

//模板6参数
	Template[0] = -3.0;
	Template[1] = -3.0;
	Template[2] = -3.0;
	Template[3] = 5.0;
	Template[4] = 0;
	Template[5] = -3.0;
	Template[6] = 5.0;
	Template[7] = 5.0;
	Template[8] = -3.0;
	
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}
	
	memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE));

//模板7参数
	Template[0] = 5.0;
	Template[1] = -3.0;
	Template[2] = -3.0;
	Template[3] = 5.0;
	Template[4] = 0;
	Template[5] = -3.0;
	Template[6] = 5.0;
	Template[7] = -3.0;
	Template[8] = -3.0;
	
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}
	
	memcpy(pTemp2,pBuffer,Height*Width*sizeof(BYTE));

//模板8参数
	Template[0] = 5.0;
	Template[1] = 5.0;
	Template[2] = -3.0;
	Template[3] = 5.0;
	Template[4] = 0;
	Template[5] = -3.0;
	Template[6] = -3.0;
	Template[7] = -3.0;
	Template[8] = -3.0;
	
	Edge_Temple(pTemp2,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pTemp2[Pos(i,j)] > pTemp1[Pos(i,j)])
				pTemp1[Pos(i,j)] = pTemp2[Pos(i,j)];
		}
	}
	
//
	memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE));
	delete []pTemp1;
	delete []pTemp2;
}



/************************************************************************/
/*	函数:边缘检测——GaussLaplacian算子(高斯拉普拉斯算子)
	说明:Laplacian算子是线形二阶微分算子,具有旋转不变性;
		  高斯平滑滤波器与Laplacian锐化滤波器结合;先平滑滤波,再边缘检测;
*/
/************************************************************************/
void CDibImage::EdgeGaussLaplacian(BYTE *pBuffer, int Height, int Width)
{	
	int TempH = 5;
	int TempW = 5;
	int TempMX = 4;
	int	TempMY = 4;
	float fTempCoef = 0.25;
	float Template[25];
	
	BYTE *pTemp1 = new BYTE[Height * Width];
	memcpy(pTemp1, pBuffer, Height * Width * sizeof(BYTE));
		
//设置GuassLaplacian模板参数
	Template[0]=-2.0;
	Template[1]=-4.0;
	Template[2]=-4.0;
	Template[3]=-4.0;
	Template[4]=-2.0;
	Template[5]=-4.0;
	Template[6]=0.0;
	Template[7]=8.0;
	Template[8]=0.0;
	Template[9]=-4.0;
	Template[10]=-4.0;
	Template[11]=8.0;
	Template[12]=24.0;
	Template[13]=8.0;
	Template[14]=-4.0;
	Template[15]=-4.0;
	Template[16]=0.0;
	Template[17]=8.0;
	Template[18]=0.0;
	Template[19]=-4.0;
	Template[20]=-2.0;
	Template[21]=-4.0;
	Template[22]=-4.0;
	Template[23]=-4.0;
	Template[24]=-2.0;
	
	Edge_Temple(pTemp1,Height,Width,TempH,TempW,TempMX,TempMY,Template,fTempCoef);
	
	memcpy(pBuffer, pTemp1, Height*Width*sizeof(BYTE));
	delete []pTemp1;
}

/************************************************************************/
/*	函数:图像分割——阈值分割
	说明:灰度值与阈值之差的绝对值小于30,则将阈值赋给图像点;
*/
/************************************************************************/
void CDibImage::FenGeYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width)
{
	int i,j;
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));
	
	for (i=0;i<Height;i++)
	{
		for (j=0; j<Width; j++)
		{
			if (abs(pBuffer[Pos(i,j)] - nYuZhi) < 30)
			{
				pTemp[Pos(i,j)] = nYuZhi;
			}
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));	
	delete []pTemp;
}



/************************************************************************/
/*	函数:图像分割——半阈值分割
	说明:保留阈值以外的图像部分,半阈值分割消除的是图像背景;
*/
/************************************************************************/
void CDibImage::FenGeBanYuZhi(BYTE *pBuffer, int nYuZhi, int Height, int Width)
{
	int i,j;
	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));
	
	for (i=0;i<Height;i++)
	{
		for (j=0; j<Width; j++)
		{
			if (abs(pBuffer[Pos(i,j)] - nYuZhi) < 30)
			{
				pTemp[Pos(i,j)] = pBuffer[Pos(i,j)];
			}
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));	
	delete []pTemp;
}

//直方图统计
void CDibImage::FenGeZhiFangTu(BYTE *pBuffer, float *fTongji, int Height, int Width) 
{
	int i,j;
	int huidu[256];
	memset(huidu, 0, sizeof(huidu));

	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, pBuffer, Height*Width*sizeof(BYTE));

	for (i=0;i<Height;i++)
	{
		for (j=0; j<Width; j++)
		{
			unsigned char Temp = pTemp[Pos(i,j)];
			huidu[Temp]++;
		}
	}

	for (i=0;i<256;i++)
		fTongji[i] = huidu[i]/(Height*Width*1.0f);
}


/************************************************************************/
/*	函数:图像分割——迭代阈值分割
	说明:应该选择图像的平均灰度来作为初始的阈值(T1);
	      以此阈值作为间隔,分成两组1与2,计算两组的平均灰度T = (u1+u2)/2;
		  以T为新阈值,重复上述操作;直到u1与u2不变;
*/
/************************************************************************/
void CDibImage::FenGeDieDai(BYTE *pBuffer, int Height, int Width) //迭代阈值分割
{
	float *fTongji = new float[256];
	memset(fTongji,0,sizeof(fTongji));
	int i,j;
	int T1,T2; //迭代阈值
	T1 = 127;
	T2 = 0;

	float temp1,temp2,temp3,temp4;
	temp1 = temp2 = temp3 = temp4 = 0;

	FenGeZhiFangTu(pBuffer,fTongji,Height,Width);

	while(true)
	{
		for (i=0;i<T1;i++)
		{
			temp1 += fTongji[i] * i;
			temp2 += fTongji[i];
		}
		for (j=T1;j<256;j++)
		{
			temp3 += fTongji[j] * j;
			temp4 += fTongji[j];
		}
		T2 = (int)((temp1/temp2 + temp3/temp4)/2);
		if (T1 == T2)
			break;
		else
			T1 = T2;
	}

	for (i=0;i<Height;i++)
	{
		for (j=0; j<Width; j++)
		{
			unsigned char Temp = pBuffer[Pos(i,j)];
			if (Temp < T1)
				Temp = 0;    保留部分(目标图像区)——白色 ???
			else
				Temp = 255; /背景色

			pBuffer[Pos(i,j)] = Temp;
		}
	}
}


/************************************************************************/
/*	函数:轮廓提取;
	说明:只是显示出图像上的目标物的轮廓;
*/
/************************************************************************/
void CDibImage::OutlineGet(BYTE *pBuffer, int Height, int Width)
{
	int i,j;
	int a1,a2,a3,a4,a5,a6,a7,a8;

	//先二值化
	for (i=0;i<Height;i++)
	{
		for (j=0;j<Width;j++)
		{
			if (pBuffer[Pos(i,j)] > 200)
				pBuffer[Pos(i,j)] = 255;
			else
				pBuffer[Pos(i,j)] = 0;
		}
	}

	BYTE *pTemp = new BYTE[Height * Width];
	memcpy(pTemp, 0, Height*Width*sizeof(BYTE));

	for (i=1;i<Height-1;i++)
	{
		for (j=1;j<Width-1;j++)
		{
			if (pBuffer[Pos(i,j)] == 255)
			{
				pTemp[Pos(i,j)] = 255;
				a1 = pBuffer[Pos(i+1,j-1)];
				a2 = pBuffer[Pos(i+1,j  )];
				a3 = pBuffer[Pos(i+1,j+1)];
				a4 = pBuffer[Pos(i  ,j-1)];
				a5 = pBuffer[Pos(i  ,j+1)];
				a6 = pBuffer[Pos(i-1,j-1)];
				a7 = pBuffer[Pos(i-1,j  )];
				a8 = pBuffer[Pos(i-1,j+1)];
				if (a1+a2+a3+a4+a5+a6+a7+a8 == 255*8)
					pTemp[Pos(i,j)] = 0;
			}
						
		}
	}
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE));	
	delete []pTemp;
}


/************************************************************************/
/*	函数:轮廓跟踪;
	说明:显示整张图像的轮廓
*/
/************************************************************************/
void CDibImage::OutlineTrack(BYTE *pBuffer, int Height, int Width)
{	
	int i,j;	
    int pixel;//像素值
	
	bool bFindStartPoint;//是否找到起始点及回到起始点	
	bool bFindPoint;//是否扫描到一个边界点	
	Point StartPoint,CurrentPoint;//起始边界点与当前边界点	
	int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};//八个方向和起始扫描方向
	int BeginDirect;
	
	//将图像二值化  白目标物,黑背景
	for (i=0;i<Height;i++)
	{
		for(j=0;j<Width;j++)
		{
			if(pBuffer[Pos(i,j)] > 200)
				pBuffer[Pos(i,j)] = 255;  
			else
				pBuffer[Pos(i,j)] = 0;
		}
	}
	
	BYTE *pTemp = new BYTE[Height*Width*sizeof(BYTE)];//创建缓冲区,将二值化后的图像数据赋给该缓冲区
	memcpy(pTemp,pBuffer,Height*Width*sizeof(BYTE));
		
	bFindStartPoint = false;//先找到最左上方的边界点
	for (j = 0;j < Height && !bFindStartPoint;j++)
	{
		for(i = 0;i < Width && !bFindStartPoint;i++)
		{
			pixel =  pTemp[Pos(i,j)];
			if(pixel == 255)  //如果找到白点
			{
				bFindStartPoint = true;
				StartPoint.Height = i;
				StartPoint.Width = j;
				pTemp[Pos(i,j)] = 255;
			}		
		}
	}
	
	BeginDirect = 0;//由于起始点是在左下方,故起始扫描沿左上方向
	
	bFindStartPoint = false;//跟踪边界
	
	CurrentPoint.Height = StartPoint.Height;//从初始点开始扫描
	CurrentPoint.Width = StartPoint.Width;
	while(!bFindStartPoint)
	{
		bFindPoint = false;
		while(!bFindPoint)
		{
			//沿扫描方向查看一个像素
			i = CurrentPoint.Height + Direction[BeginDirect][1];
			j = CurrentPoint.Width + Direction[BeginDirect][0];
	
			pixel =  pTemp[Pos(i,j)];
			if(pixel== 255)
			{
				bFindPoint = true;
				CurrentPoint.Height = CurrentPoint.Height + Direction[BeginDirect][1];
				CurrentPoint.Width = CurrentPoint.Width + Direction[BeginDirect][0];
				if(CurrentPoint.Height == StartPoint.Height && CurrentPoint.Width == StartPoint.Width)
					bFindStartPoint = true;

				i = CurrentPoint.Height;
				j = CurrentPoint.Width;
				pTemp[Pos(i,j)] = 255;

				
				BeginDirect--;//扫描的方向逆时针旋转两格
				if(BeginDirect == -1)
					BeginDirect = 7;
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
			}
			else
			{
				//扫描方向顺时针旋转一格
				BeginDirect++;
				if(BeginDirect == 8)
					BeginDirect = 0;
			}
		}
	}
	
	memcpy(pBuffer, pTemp, Height*Width*sizeof(BYTE)); // 复制图像
	delete []pTemp; // 释放内存	
}

/************************************************************************/
/*	函数:图像测量——图像区域标记;
	说明:标记出图像中的连通区域;
*/
/************************************************************************/
void CDibImage::MeasureBiaoJi(BYTE *pBuffer, int Height, int Width) //对图像区域进行标记
{
	int i,j;  //循环变量
	int x_sign=0; 
	int m_temp=0;
	int x_temp=0;
	int y_temp=0;
	int stop=0;

	int flag[255];
	memset(flag,0,255);
	
	BYTE *pTemp=new BYTE[Height*Width*sizeof(BYTE)];//开辟一个临时内存区
	memset(pTemp, 255, Height*Width*sizeof(BYTE));
	//从左到右标号
	for(i=1;i<Height-1;i++)	// 每行
	{
		if(stop==1)//判断连通区是否太多
			break;
		for(j=1;j<Width-1;j++)	// 每列
		{
			if(x_sign>250)
			{
				AfxMessageBox("连通区数目太多,请增大阈值!");
				stop=1;
				break;
			}
			if(pBuffer[Pos((Height-i-1),j)] == 0)//若当前点为黑点
			{
				if(pBuffer[Pos((Height-i-1+1),j+1)] == 0)//右上
				{
					pTemp[Pos((Height-i-1),j)] = pTemp[Pos((Height-i-1+1),j+1)];
					
					x_temp=pTemp[Pos((Height-i-1+1),j+1)];
					flag[x_temp]+=1;
			//左前
					if(pBuffer[Pos((Height-i-1),j-1)] == 0 && pTemp[Pos((Height-i-1),j-1)] != x_temp)
					{
						y_temp=pTemp[Pos((Height-i-1),j-1)];
						for(int m=1;m<=Height-1;m++)
							for(int n=1;n<=Width-1;n++)
							{
								if(pTemp[Pos((Height-m-1),n)] == y_temp)
								{	
									flag[y_temp]=0;
									pTemp[Pos((Height-m-1),n)]=x_temp;
									flag[x_temp]+=1;
								}
							}
					}//end//左前
            //左上
					if(pBuffer[Pos((Height-i-1+1),j-1)] == 0 && pTemp[Pos((Height-i-1+1),j-1)] != x_temp)
					{
						y_temp=pBuffer[Pos((Height-i-1+1),j-1)];
						for(int m=1;m<=Height-1;m++)
							for(int n=1;n<=Width-1;n++)
							{
								if(pTemp[Pos((Height-m-1),n)] == y_temp)
								{	
									flag[y_temp]=0;
									pTemp[Pos((Height-m-1),n)]=x_temp;
									flag[x_temp]+=1;
								}
							}
					}//end//左上
				}
				else if(pBuffer[Pos((Height-i-1+1), j)]==0)//正上
				{
					pTemp[Pos((Height-i-1), j)] = pTemp[Pos((Height-i-1+1), j)];
					x_temp = pTemp[Pos((Height-i-1+1), j)];
					flag[x_temp]+=1;
				}
				else if(pBuffer[Pos((Height-i-1+1), j-1)] == 0)//左上
				{ 
					pTemp[Pos((Height-i-1), j)]=pTemp[Pos((Height-i-1+1), j-1)];
					x_temp = pTemp[Pos((Height-i-1+1), j-1)];
					flag[x_temp]+=1;
				}
				else if(pBuffer[Pos((Height-i-1), j-1)] == 0)//左前
				{
					pTemp[Pos((Height-i-1), j)]=pTemp[Pos((Height-i-1), j-1)];
					x_temp=pTemp[Pos((Height-i-1), j-1)];
					flag[x_temp]+=1;
				}
				else//没有
				{				
					++x_sign;
					m_temp=x_sign;
					pTemp[Pos((Height-i-1), j)] = m_temp;
					flag[m_temp]=1;	
				}
			}//end if
		}// 每列
	}//end 每行	
}




  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值