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

📄 imageanalysis.cpp

📁 本软件是图象处理软件,能对图象进行简单的处理,如中值滤波、二值化变换、亮度增减、傅立叶变换、反色、取对数等
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 * 函数名称:
 *   DIBFREAMEWORK()
 *
 * 参数:
 *   CDib * pDib        - 指向CDib类的指针
 *
 * 返回值:
 *   BOOL               - 成功返回True,否则返回False。
 *
 * 说明:
 *   该函数利用棋盘距离,生成图象的骨架。
 *
 *************************************************************************/

BOOL DIBFREAMEWORK(CDib *pDib)
{
	// 指向源图像的指针
	BYTE *	lpSrc;

	//图象的宽度和高度
	LONG    lWidth;
	LONG    lHeight;

	// 图像每行的字节数
	LONG	lLineBytes;
	
	//得到图象的宽度和高度
	CSize   SizeDim;
	SizeDim = pDib->GetDimensions();
	lWidth  = SizeDim.cx;
	lHeight = SizeDim.cy;	
	
	//得到实际的Dib图象存储大小
	CSize   SizeRealDim;
	SizeRealDim = pDib->GetDibSaveDim();

	// 计算图像每行的字节数
	lLineBytes = SizeRealDim.cx;
	
	//图像数据的指针
	LPBYTE  lpDIBBits = pDib->m_lpImage;

	// 循环和临时变量
	int i,j;
	int temp, s;

	// 存储象素值的数组
	int *pnBinary, *pnStore;
	
	int nImageValue;

	pnBinary = new int[lHeight*lLineBytes];
	pnStore	 = new int[lHeight*lLineBytes];	

	// 将图象二值化
	for (j = 0; j < lHeight; j++)
	{
		for(i = 0; i < lWidth; i++)
		{
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;

			// 白色象素为背景,存成0
			if(*lpSrc > 200)
			{
				pnBinary[lLineBytes * j + i] = 0;
				pnStore [lLineBytes * j + i] = 0;
			}
			// 黑象素存成1
			else
			{
				pnBinary[lLineBytes * j + i] = 1;
				pnStore [lLineBytes * j + i] = 1;
			}
		}		
	}

	s = 1;

	while(s == 1)
	{
		s = 0;

		// 进行距离的累加
		for (j = 1; j < lHeight - 1; j++)
		{
			for(i = 1; i < lWidth - 1; i++)
			{
				nImageValue = pnBinary[lLineBytes * j + i];
				
				// 如果是背景,进行下一个循环
				if(nImageValue == 0)
					continue;
				
				// 如果当前象素值和四周的值一样,象素值增加一
				if(nImageValue==pnBinary[lLineBytes * (j-1) + i] && nImageValue==pnBinary[lLineBytes * (j+1) + i])
					if(nImageValue==pnBinary[lLineBytes * j + i-1] && nImageValue==pnBinary[lLineBytes * j + i+1])
					{
						pnStore[lLineBytes * j + i]++;
						s=1;								
					}
			}
		}
		
		// 在进行下一轮循环前将当前的结果储存
		for (j = 0; j < lHeight; j++)
			for(i = 1; i < lWidth; i++)
				pnBinary[lLineBytes * j + i] = pnStore[lLineBytes * j + i];
	}
	
	for (j = 0; j < lHeight; j++)
		for(i = 0; i < lWidth; i++)
			pnStore[lLineBytes * j + i] = 0;
	
	// 如果当前的象素值比周围的都要高,做为骨架	
	for (j = 1; j < lHeight - 1; j++)
		for(i = 1; i < lWidth - 1; i++)
		{
			nImageValue = pnBinary[lLineBytes * j + i] + 1;
			
			// 在四连通域进行比较
			if(nImageValue!=pnBinary[lLineBytes * (j-1) + i] && nImageValue!=pnBinary[lLineBytes * (j+1) + i])
					if(nImageValue!=pnBinary[lLineBytes * j + i-1] && nImageValue!=pnBinary[lLineBytes * j + i+1])
						pnStore[lLineBytes * j + i] = pnBinary[lLineBytes * j + i];
		}


	// 存储象素值,输出
	for(j = 0; j < lHeight; j++)
	{
		// 列
		for(i = 0; i < lWidth; i++)
		{
			// 骨架的象素值
		    temp = pnStore[j * lLineBytes + i] ;
			
			// 指向位图i行j列象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
			
			// 更新源图像,并将象素值进行变换,以便输出
			if(temp != 0)	
				* (lpSrc) = temp;
			else
				* (lpSrc) = 255;
		}
	}

	delete pnStore;
	delete pnBinary;

	return true;
}

/*************************************************************************
 *
 * 函数名称:
 *   DIBCHESSBOARDDISRESTORE()
 *
 * 参数:
 *   CDib * pDib        - 指向CDib类的指针
 *
 * 返回值:
 *   BOOL               - 成功返回True,否则返回False。
 *
 * 说明:
 *   该函数利用骨架对原图象进行恢复。
 *
 *************************************************************************/
BOOL DIBCHESSBOARDDISRESTORE(CDib *pDib)
{
	// 指向源图像的指针
	BYTE *	lpSrc;

	//图象的宽度和高度
	LONG    lWidth;
	LONG    lHeight;

	// 图像每行的字节数
	LONG	lLineBytes;
	
	//得到图象的宽度和高度
	CSize   SizeDim;
	SizeDim = pDib->GetDimensions();
	lWidth  = SizeDim.cx;
	lHeight = SizeDim.cy;	
	
	//得到实际的Dib图象存储大小
	CSize   SizeRealDim;
	SizeRealDim = pDib->GetDibSaveDim();

	// 计算图像每行的字节数
	lLineBytes = SizeRealDim.cx;
	
	//图像数据的指针
	LPBYTE  lpDIBBits = pDib->m_lpImage;

	// 循环变量
	int i, j, n, m;

	// 临时变量
	int temp, s;

	// 用来存放象素值的数组
	int *pnBinary, *pnStore;
	
	int nImageValue;

	pnBinary = new int[lHeight*lLineBytes];
	pnStore	 = new int[lHeight*lLineBytes];	

	// 数组赋值
	for (j = 0; j < lHeight; j++)
	{
		for(i = 0; i < lWidth; i++)
		{
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;

			pnBinary[lLineBytes * j + i] = 0;
			if((*lpSrc) != 255)
				pnStore [lLineBytes * j + i] = (*lpSrc);
			else
				pnStore [lLineBytes * j + i] = 0;
		}		
	}

	
	// 进行图象的恢复
	for (j = 1; j < lHeight - 1; j++)
	{
		for(i = 1; i < lWidth - 1; i++)
		{
			nImageValue = pnStore[lLineBytes * j + i];
			if(nImageValue == 0)
				continue;
			
			if(nImageValue == 1)
			{
				pnBinary[lLineBytes * j + i] = 1;
				continue;
			}
			
			// 如果象素值大于等于2,将以(2×nImageValue)+1的菱形范围的象素值赋1
			s = nImageValue;

			// 菱形的主轴
			for(m = -s; m <= s; m++)
			{
				pnBinary[lLineBytes * j + i + m] = 1;

			}

			// 菱形的上半部分
			for(n = -s; n < 0; n++)
				for(m = -s - n; m <=s + n; m++)
					pnBinary[lLineBytes * (j+n) + i+m] = 1;

			// 菱形的下半部分
			for(n = 1; n <= s; n++)
				for(m = -s + n; m <= s - n; m++)
					pnBinary[lLineBytes * (j+n) + i+m] = 1;
		
		}
	}

	// 存储象素值,输出
	for(j = 0; j < lHeight; j++)
	{
		// 列
		for(i = 0; i < lWidth; i++)
		{
			// 骨架的象素值
		    temp = pnBinary[j * lLineBytes + i] ;
			
			// 指向位图i行j列象素的指针
			lpSrc = (unsigned char*)lpDIBBits + lLineBytes * j + i;
			
			// 更新源图像
			if(temp != 0)	
				// 黑色象素输出
				* (lpSrc) = 0;
			else
				// 白色象素输出
				* (lpSrc) = 255;
		}
	}

	delete pnStore;
	delete pnBinary;

	return true;
}

/*************************************************************************
 *
 * 函数名称:
 *   DIBOUTLINE()
 *
 * 参数:
 *   CDib * pDib        - 指向CDib类的指针
 *
 * 返回值:
 *   BOOL               - 成功返回True,否则返回False。
 *
 * 说明:
 *   该函数对二值图象进行轮廓检出。
 *
 *************************************************************************
 */

BOOL DIBOUTLINE(CDib *pDib)
{
	
	// 指向源图像的指针
	BYTE *	lpSrc;

	//图象的宽度和高度
	LONG    lWidth;
	LONG    lHeight;

	// 图像每行的字节数
	LONG	lLineBytes;
	
	//得到图象的宽度和高度
	CSize   SizeDim;
	SizeDim = pDib->GetDimensions();
	lWidth  = SizeDim.cx;
	lHeight = SizeDim.cy;	
	
	//得到实际的Dib图象存储大小
	CSize   SizeRealDim;
	SizeRealDim = pDib->GetDibSaveDim();

	// 计算图像每行的字节数
	lLineBytes = SizeRealDim.cx;
	
	//图像数据的指针
	LPBYTE  lpDIBBits = pDib->m_lpImage;

	// 循环变量
	int i, j;

	int nPixelValue;

	int n1,n2,n3,n4,n5,n6,n7,n8;

	// 用来存放象素值的数组
	int *pnBinary;
	
	pnBinary = new int[lHeight*lLineBytes];

	// 将图象二值化
	for (j = 0; j < lHeight; j++)
	{
		for(i = 0; i < lWidth; i++)
		{
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;

			// 白色象素为背景,存成0
			if(*lpSrc > 200)
			{
				pnBinary[lLineBytes * j + i] = 0;
			}
			// 黑象素存成1
			else
			{
				pnBinary[lLineBytes * j + i] = 1;
			}
		}		
	}
	
	for (j = 1; j < lHeight - 1; j++)
	{
		for(i = 1; i < lWidth - 1; i++)
		{	
			nPixelValue = pnBinary[lLineBytes * j + i];
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;

			// 如果当前象素是白色,进入下一个循环
			if(nPixelValue == 0)
			{
				// 将相应的象素值改成零
			
				*lpSrc = 255;
				continue;
			}

			// 如果当前象素是黑色
			else
			{
				// 检查周边的8连通域
				n1 = pnBinary[lLineBytes * (j+1) + i + 1];
				n2 = pnBinary[lLineBytes * (j+1) + i - 1];
				n3 = pnBinary[lLineBytes * (j+1) + i];
				n4 = pnBinary[lLineBytes * (j-1)+ i + 1];
				n5 = pnBinary[lLineBytes * (j-1) + i - 1];
				n6 = pnBinary[lLineBytes * (j-1) + i];
				n7 = pnBinary[lLineBytes * j + i + 1];
				n8 = pnBinary[lLineBytes * j + i - 1];
				
				//如果相邻的八个点都是黑点
				if(n1&&n2&&n3&&n4&&n5&&n6&&n7&&n8 == 1)
				{
					*lpSrc = (unsigned char)255;
				}
			}
		}
	}

	delete pnBinary;

	// 返回
	return TRUE;
}


/*************************************************************************
 *
 * 函数名称:
 *   DIBTrace()
 *
 * 参数:
 *   CDib * pDib        - 指向CDib类的指针
 *
 * 返回值:
 *   BOOL               - 成功返回True,否则返回False。
 *
 * 说明:
 * 该函数用于对图像进行轮廓跟踪运算。
 *
 *************************************************************************
 */

BOOL WINAPI DIBTrace(CDib *pDib)
{
	
	// 指向源图像的指针
	BYTE *	lpSrc;

	//图象的宽度和高度
	LONG    lWidth;
	LONG    lHeight;

	// 图像每行的字节数
	LONG	lLineBytes;
	
	//得到图象的宽度和高度
	CSize   SizeDim;
	SizeDim = pDib->GetDimensions();
	lWidth  = SizeDim.cx;
	lHeight = SizeDim.cy;	
	
	//得到实际的Dib图象存储大小
	CSize   SizeRealDim;
	SizeRealDim = pDib->GetDibSaveDim();

	// 计算图像每行的字节数
	lLineBytes = SizeRealDim.cx;
	
	//图像数据的指针
	LPBYTE  lpDIBBits = pDib->m_lpImage;
	
	//循环变量
	long i;
	long j;

	//像素值
	int nPixelValue;

	//是否找到起始点及回到起始点
	bool bFindStartPoint;

	//是否扫描到一个边界点
	bool bFindPoint;

	// 用来边界起点和所有边界点的数组
	int nStartPointX, nStartPointY;
	int *nCurrPointX, *nCurrPointY;
	
	// 边界点的数目
	long lNum;

	// 用来存储二值象素的数组
	int *pnBinary;	

	//八个方向和起始扫描方向
	int Direction[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};
	int BeginDirect;

	// 分配内存
	pnBinary =new int[lLineBytes*lHeight];
	nCurrPointX = new int[lLineBytes*lHeight/4];
	nCurrPointY = new int[lLineBytes*lHeight/4];	

	// 将图象二值化
	for (j = 0; j < lHeight; j++)
	{
		for(i = 0; i < lWidth; i++)
		{
			// 指向源图像倒数第j行,第i个象素的指针			
			lpSrc = (unsigned char *)lpDIBBits + lLineBytes * j + i;

			// 白色象素为背景,存成0
			if(*lpSrc > 200)
			{
				pnBinary[lLineBytes * j + i] = 0;
				
			}
			// 黑象素存成1
			else
			{
				pnBinary[lLineBytes * j + i] = 1;
			}

			// 将已经扫描过的象素存成白色背景
			*lpSrc = 255;
		}		
	}	

	//先找到最左上方的边界点
	bFindStartPoint = false;

	for (j = 0; j < lHeight; j++)
	{
		for(i = 0;i < lWidth ;i++)
		{
			nPixelValue = pnBinary[lLineBytes * j + i];
			
			if(nPixelValue == 1)
			{
				bFindStartPoint = true;

				// 储存边界起始点
				nStartPointY = j;
				nStartPointX  = i;
				
				// 跳出循环
				j = lHeight;
				i = lLineBytes ;
			}		
		}
	}

	// 没有起始点,跳出
	if(bFindStartPoint == false)
		return false;

	//由于起始点是在左上方,起始扫描沿右侧方向
	BeginDirect = 0;
	//跟踪边界
	bFindStartPoint = false;

	//从初始点开始扫描
	lNum = 0;
	nCurrPointY[0] = nStartPointY;
	nCurrPointX[0] = nStartPointX;
	
	while(!bFindStartPoint)
	{
		bFindPoint = false;

		while(!bFindPoint)
		{
			nPixelValue = pnBinary[(nCurrPointY[lNum] + Direction[BeginDirect][1])*lLineBytes
									+ nCurrPointX[lNum] + Direction[BeginDirect][0]];

			// 找到下一个边界点
			if(nPixelValue == 1)
			{
				bFindPoint = true;

				// 位置存储
				nCurrPointY[lNum+1] = nCurrPointY[lNum] + Direction[BeginDirect][1];
				nCurrPointX[lNum+1] = nCurrPointX[lNum] + Direction[BeginDirect][0];
				lNum ++;

				if(nCurrPointY[lNum] == nStartPointY && nCurrPointX[lNum] == nStartPointX)
				{
					bFindStartPoint = true;
				}

				//扫描的方向逆时针旋转两格
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
				BeginDirect--;
				if(BeginDirect == -1)
					BeginDirect = 7;
			}
			else
			{
				//扫描方向顺时针旋转一格
				BeginDirect++;
				if(BeginDirect == 8)
					BeginDirect = 0;

			}

		}
	}

	// 存储显示边界点
	for(i = 0; i <= lNum; i++)
	{
		lpSrc  = (unsigned char *)lpDIBBits + nCurrPointY[i] *lLineBytes  + nCurrPointX[i];
		*lpSrc = 0;
	}

	delete pnBinary;

	// 返回
	return TRUE;
}

⌨️ 快捷键说明

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