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

📄 ob_track.c.bak

📁 基于BF533的视频采集及显示
💻 BAK
字号:
/******************************************************************************/
//
// Name: 	BF533 Object Track
//
/******************************************************************************

File Name:	Ob_Track.c

Special Connections:  None

Purpose:		The file sets up all interrupts required 
				
*********************************************************************************/

#include "Ob_Track.h" 
#include "math.h"
void MinusDIB(unsigned char * psource, unsigned char * ptempBK,unsigned int iWidth, unsigned int iHeight)
{
	
	//循环变量
	int i;
	int j;

	for (j = 0;j < iHeight ;j++)
	{
		for(i = 0;i < iWidth ;i++)
		{
			psource[iWidth * j + i] = psource[iWidth * j + i] - ptempBK[iWidth * j + i] < 0   ? 0   : psource[iWidth * j + i] - ptempBK[iWidth * j + i];		
		}
	}

}
void DataSample(unsigned char * ptemp,unsigned char * psource, unsigned int iWidth, unsigned int iHeight)
{
	
	//循环变量
	int i;
	int j;
	for(j = 0;j < iHeight ;j+=2)
	{
		for (i = 0;i < iWidth ;i+=4)
		{
			
			ptemp[ iWidth * j /8 + i/4] = psource[iWidth * j + i];
		}
	}
	
}
void Template(unsigned char * psource, unsigned char * ptemp, const int ipArray[])
{	
	int	i,j;
	// 计算结果
	int	iResult;
	// 行(除去边缘几行)
	for(i = iTempMY; i < HEIGHT - iTempH + iTempMY + 1; i++)
	{
		// 列(除去边缘几列)
		for(j = iTempMX; j < WIDTH - iTempW + iTempMX + 1; j++)
		{
			iResult = 0;	
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 0)+ j - iTempMX + 0] * ipArray[0 * iTempW + 0];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 0)+ j - iTempMX + 1] * ipArray[0 * iTempW + 1];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 0)+ j - iTempMX + 2] * ipArray[0 * iTempW + 2];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 1)+ j - iTempMX + 0] * ipArray[1 * iTempW + 0];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 1)+ j - iTempMX + 1] * ipArray[1 * iTempW + 1];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 1)+ j - iTempMX + 2] * ipArray[1 * iTempW + 2];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 2)+ j - iTempMX + 0] * ipArray[2 * iTempW + 0];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 2)+ j - iTempMX + 1] * ipArray[2 * iTempW + 1];
			iResult += psource[WIDTH * (HEIGHT - 1 - i + iTempMY - 2)+ j - iTempMX + 2] * ipArray[2 * iTempW + 2];	
			// 取绝对值
			iResult =abs(iResult);
			// 判断是否超过255
			if(iResult > 255)
			{
				// 直接赋值为255
				ptemp[WIDTH * (HEIGHT - 1 - i) + j] = (unsigned char)255;
			}
			else
			{
				// 赋值
				ptemp[WIDTH * (HEIGHT - 1 - i) + j] = (unsigned char) (iResult + 0.5);
			}
		}
	}				
}
void SobelDIB(unsigned char * psource, unsigned char * ptemp1, unsigned char * ptemp2)
{ 
    int     iTemplate[9];// 模板数组
	iTemplate[0] = -1;
	iTemplate[1] = -2;
	iTemplate[2] = -1;
	iTemplate[3] = 0;
	iTemplate[4] = 0;
	iTemplate[5] = 0;
	iTemplate[6] = 1;
	iTemplate[7] = 2;
	iTemplate[8] = 1;
	Template(psource,ptemp1,iTemplate);
	// 设置Sobel模板参数
	iTemplate[0] = -1;
	iTemplate[1] = 0;
	iTemplate[2] = 1;
	iTemplate[3] = -2;
	iTemplate[4] = 0;
	iTemplate[5] = 2;
	iTemplate[6] = -1;
	iTemplate[7] = 0;
	iTemplate[8] = 1;
	Template(psource,ptemp2,iTemplate);
}
void MaxSobel(unsigned char * ptemp1, unsigned char * ptemp2,unsigned char * presult)
{
	int	i,j;
	//求两幅缓存图像的最大值
	for(i = 0; i < HEIGHT*WIDTH; i++)
	{			
			if(ptemp1[i] >= ptemp2[i])
				presult[i] = ptemp1[i];
			else
				presult[i] = ptemp2[i];
	}
	//去掉边框点
	for(j=0;j<HEIGHT;j+=HEIGHT - 1)
	{
		for(i=0;i<WIDTH;i++)
		{
			presult[j * WIDTH + i]= (unsigned char)0 ;	
		}
	}
    for(j=0;j<HEIGHT;j++)
	{
		for(i=0;i<WIDTH;i+=WIDTH - 1)
		{
			presult[j * WIDTH + i]= (unsigned char)0 ;	
		}
	}
}
void Threshold(unsigned char * psource,unsigned char * presult)
{
	int	i; 
	for(i = 0; i < HEIGHT*WIDTH; i++)
	{	
			// 判断是否小于阈值
			if (psource[i] < bThre)
			{
				// 直接赋值为0
				presult[i] = (unsigned char)0;
			}
			else
			{
				// 直接赋值为255
				presult[i] = (unsigned char)255;
			}	
	}
}
void Multiply(unsigned char * psource,unsigned char * presult)
{
	int i;
	//像素值
	unsigned char pixel,pixelBK;
	for (i = 0;i < HEIGHT*WIDTH ;i++)
	{
			pixel = (unsigned char)presult[i];
			pixelBK = (unsigned char)psource[i];
			presult[i] = pixel * pixelBK;
	}		
}
unsigned char GetMedianNum(unsigned char *bArray)
{
	int		i,j;
	// 中间变量
	unsigned char bTemp;
	// 用冒泡法对数组进行排序
	for (j = 0; j < iFilterLen - 1; j ++)
	{
		for (i = 0; i < iFilterLen - j - 1; i ++)
		{
			if (bArray[i] > bArray[i + 1])
			{
				// 互换
				bTemp = bArray[i];
				bArray[i] = bArray[i + 1];
				bArray[i + 1] = bTemp;
			}
		}
	}
	// 计算中值
	if ((iFilterLen & 1) > 0)
	{
		// 数组有奇数个元素,返回中间一个元素
		bTemp = bArray[(iFilterLen + 1) / 2];
	}
	else
	{
		// 数组有偶数个元素,返回中间两个元素平均值
		bTemp = (bArray[iFilterLen / 2] + bArray[iFilterLen / 2 + 1]) / 2;
	}	
	// 返回中值*/
	return bTemp;
}
void MedianFilter(unsigned char * psource,unsigned char * presult)
{	
	int	i,j;
	// 指向滤波器数组的指针
	unsigned char *aValue;
	// 分配内存
	aValue = (unsigned char*)calloc(iFilterLen,1);	
	//赋初值
	for(j=0;j<iFilterH;j++)
	{
		for(i=0;i<iFilterW;i++)	
		{
			aValue[iFilterW * i + j] = (unsigned char)255;
		}
	}		
	// 开始中值滤波
	// 行(除去边缘几行)
	for(i = iFilterMY; i < HEIGHT - iFilterH + iFilterMY + 1; i++)
	{
		// 列(除去边缘几列)
		for(j = iFilterMX; j < WIDTH - iFilterW + iFilterMX + 1; j++)
		{		
			aValue[0 * iFilterW + 0] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 0) + j - iFilterMX + 0];		
			aValue[0 * iFilterW + 1] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 0) + j - iFilterMX + 1];		
			aValue[0 * iFilterW + 2] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 0) + j - iFilterMX + 2];		
			aValue[1 * iFilterW + 0] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 1) + j - iFilterMX + 0];		
			aValue[1 * iFilterW + 1] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 1) + j - iFilterMX + 1];		
			aValue[1 * iFilterW + 2] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 1) + j - iFilterMX + 2];		
			aValue[2 * iFilterW + 0] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 2) + j - iFilterMX + 0];		
			aValue[2 * iFilterW + 1] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 2) + j - iFilterMX + 1];		
			aValue[2 * iFilterW + 2] = psource[WIDTH * (HEIGHT - 1 - i + iFilterMY - 2) + j - iFilterMX + 2];				
			// 获取中值
			presult[WIDTH *(HEIGHT - 1 - i) + j] = GetMedianNum(aValue);
		}
	}
	free(aValue);
}
void ErosionDIB(unsigned char * psource,unsigned char * presult)
{
	int i,j;
	//使用自定义的结构元素进行腐蚀
	for(j = 1; j <HEIGHT-1; j++)
	{
		for(i = 1;i <WIDTH-1; i++)
		{
			//由于使用3×3的结构元素,为防止越界,所以不处理最左边和最右边的两列像素
			//和最上边和最下边的两列像素
			//目标图像中的当前点先赋成黑色
			presult[WIDTH * j + i] = (unsigned char)0;
			if(psource[WIDTH*j + i]!=0||psource[WIDTH*j + i+1]!=0||psource[WIDTH*j + i-1]!=0||psource[WIDTH*(j+1) + i]!=0||psource[WIDTH*(j-1) + i]!=0)
            	presult[WIDTH * j + i] = (unsigned char)255;	
		}
	}
}
void DilationDIB(unsigned char * psource,unsigned char * presult)
{
	int i,j;
    //使用自定义的结构元素进行膨胀
	for(j = 1; j <HEIGHT-1; j++)
	{
		for(i = 1;i <WIDTH - 1; i++)
		{
			//由于使用3×3的结构元素,为防止越界,所以不处理最左边和最右边的两列像素
			//和最上边和最下边的两列像素
			//目标图像中的当前点先赋成黑色
			presult[WIDTH * j + i] = (unsigned char)255;
			if(psource[WIDTH*j + i]!=255||psource[WIDTH*j + i+1]!=255||psource[WIDTH*j + i-1]!=255||psource[WIDTH*(j+1) + i]!=255||psource[WIDTH*(j-1) + i]!=255)
            	presult[WIDTH * j + i] = (unsigned char)0;       			
		}
	}
}
void RegionMerge(unsigned char * psource,unsigned char * ptemp,int *pfeature)
{
	int i,i1,j,k;
	int fgroup;
	int ffind;
	int nNumberBlock[GROUPNUM];//存放块中的象素点数
	unsigned char group[GROUPNUM];//等价组(合并相连的组合)
	/////////////几何特征
	int AreaBlockNum;//总的区域块数
	int AreaBlockMax;//区域块中最大的点数
	int AreaCenterX[AREANUM];//运动区域的形心X坐标
	int AreaCenterY[AREANUM];//运动区域的形心Y坐标
	int AreaPixSum[AREANUM];//每个区域的面积
	int AreaMaxX[AREANUM];//区域右边界
	int AreaMinX[AREANUM];//区域左边界
	int AreaMaxY[AREANUM];//区域上边界
	int AreaMinY[AREANUM];//区域下边界
	int AreaBlockHeight[AREANUM];//每个区域块的高度
	int AreaBlockWidth[AREANUM];//每个区域块的宽度
	///////////////
	for(i=0;i<GROUPNUM;i++)
	{
		nNumberBlock[i]=0;
		group[i]=0;
	}
	for(i=0;i<WIDTH*HEIGHT;i++)
	{
		ptemp[i]=0;//临时存放象素点所在的组号
	}
	///////////////////////
	//按从左到右,从下到上对图像进行第一步扫描
	for(i=0;i<HEIGHT;i++)
		for(j=0;j<WIDTH;j++)
		{
			if(psource[i*WIDTH+j]==0)  //背景点
			{
				ptemp[i*WIDTH+j]=0;

			}
			else if(psource[i*WIDTH+j]!=0)  //图像点
			{
				if(i==0 || j==0 || j==WIDTH-1)
					ptemp[i*WIDTH+j] = 0;
				else   //非边界点
				{
					//step1:当前象素的值是"1"并且上述4个相邻象素都是"0",
					//给当前象素赋一个新的标记

					if(psource[i*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+j]==0
						&&psource[(i-1)*WIDTH+(j+1)]==0)
					{
						ptemp[i*WIDTH+j] = k++;
					}
					//如果只有一个相邻象素为"1",就把该象素的标记赋给当前象素。
					else if(psource[i*WIDTH+(j-1)]!=0
						&&psource[(i-1)*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+j]==0
						&&psource[(i-1)*WIDTH+(j+1)]==0)
					{
						ptemp[i*WIDTH+j] = ptemp[i*WIDTH+j-1];
					}
					else if(psource[i*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+(j-1)]!=0
						&&psource[(i-1)*WIDTH+j]==0
						&&psource[(i-1)*WIDTH+(j+1)]==0)
					{
						ptemp[i*WIDTH+j] = ptemp[(i-1)*WIDTH+j-1];
					}
					else if(psource[i*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+j]!=0
						&&psource[(i-1)*WIDTH+(j+1)]==0)
					{
						ptemp[i*WIDTH+j] = ptemp[(i-1)*WIDTH+j];
					}
					else if(psource[i*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+(j-1)]==0
						&&psource[(i-1)*WIDTH+j]==0
						&&psource[(i-1)*WIDTH+(j+1)]!=0)
					{
						ptemp[i*WIDTH+j] = ptemp[(i-1)*WIDTH+j+1];
					}
					//如果2个或多个相邻象素为"1",
					//	就将其中一个象素的标记赋给当前象素并做个记号表明它们等价
					else
					{
						fgroup = FALSE;
						if(psource[i*WIDTH+(j-1)]!=0)
						{
							ptemp[i*WIDTH+j] = ptemp[i*WIDTH+j-1];
							fgroup = TRUE;													
						}
						if(psource[(i-1)*WIDTH+(j-1)]!=0)
						{
							if(fgroup==TRUE)
							{
								if(ptemp[(i-1)*WIDTH+j-1]!=ptemp[i*WIDTH+j])
							    	group[ptemp[(i-1)*WIDTH+j-1]] = ptemp[i*WIDTH+j];

							}
							else
							{
								ptemp[i*WIDTH+j] = ptemp[(i-1)*WIDTH+j-1];
					            fgroup = TRUE;
							}
						}
						if(psource[(i-1)*WIDTH+j]!=0)
						{
							if(fgroup==TRUE)
							{
								if(ptemp[(i-1)*WIDTH+j]!=ptemp[i*WIDTH+j])
								group[ptemp[(i-1)*WIDTH+j]] = ptemp[i*WIDTH+j];									
						    
							}
							else
							{
								ptemp[i*WIDTH+j] = ptemp[(i-1)*WIDTH+j];
					            fgroup = TRUE;
							}
							
						}
						if(psource[(i-1)*WIDTH+j+1]!=0)
						{
							if(fgroup==TRUE)
							{
								if(ptemp[(i-1)*WIDTH+j+1]!=ptemp[i*WIDTH+j])
						    		group[ptemp[(i-1)*WIDTH+j+1]] = ptemp[i*WIDTH+j];									
												
							}
							else
							{
								ptemp[i*WIDTH+j] = ptemp[(i-1)*WIDTH+j+1];
					            fgroup = TRUE;
							}
							
						}
					}							
				}
			}
		}
    
	//统计各区域块象素点数,即合并等价组
	for(i=0;i<WIDTH*HEIGHT;i++)
	{
		for(i1=0;i1<GROUPNUM/2;i1++)
		{
			if(group[ptemp[i]]>0)
			{
		    	ptemp[i] = group[ptemp[i]];
			}
			else
				break;
		}
		nNumberBlock[ptemp[i]]++;
	}	
	//去点操作
	for(i=0;i<GROUPNUM;i++)
	{
		 if(nNumberBlock[i] < REGMAX)
		    nNumberBlock[i] = 0;
	}

	for(i=0;i<WIDTH*HEIGHT;i++)
	{
		if(nNumberBlock[ptemp[i]]==0)
			ptemp[i]=0;
		if(ptemp[i]>0 && psource[i]!=0)
		{
			psource[i] = (unsigned char) 255;		

		}
		else
			psource[i] = (unsigned char) 0;
	}
	///////////////////////////////////
	for(i=0;i<AREANUM;i++)
	{
		AreaPixSum[i] = 0;
	}	
	for(i=0;i<AREANUM;i++)
	{
		AreaMaxX[i] = 0;
		AreaMaxY[i] = 0;
	}

	for(i=0;i<AREANUM;i++)
	{
		 AreaMinX[i] = WIDTH;
		 AreaMinY[i] = HEIGHT;
	}
	for(i=0; i<AREANUM; i++)
	{
		AreaCenterX[i] = 0;
		AreaCenterY[i] = 0;
	}
	///重新安排组号(因为已经把那些不符合的组去掉)
	k = 0;
	for(i=0;i<GROUPNUM;i++)
	{
		group[i]=0;
	}
	for(i=HEIGHT-1;i>=0;i--)
	{
		for(j=0;j<WIDTH;j++)
		{
			if(psource[i*WIDTH+j]!=0)
			{
				ffind = FALSE;
				
	        	for(k=0;group[k]!=0;k++)
				{
					if(ptemp[i*WIDTH+j]==group[k])
					{
						AreaPixSum[k]++;//k组中点的个数
						AreaCenterX[k] += j;
			    		AreaCenterY[k] += i;

						if(AreaMaxX[k]<j)
							AreaMaxX[k] = j;
						else if(AreaMinX[k]>j)
							AreaMinX[k] = j;

						if(AreaMaxY[k]<i)
							AreaMaxY[k] = i;
						else if(AreaMinY[k]>i)
							AreaMinY[k] = i;

						ffind = TRUE;
						break;
					}
				}
				if(ffind==FALSE)//一组的第一个点
				{
					AreaPixSum[k]++;
					group[k] = ptemp[i*WIDTH+j];
					AreaCenterX[k] += j;
			    	AreaCenterY[k] += i;
						if(AreaMaxX[k]<j)
							AreaMaxX[k] = j;
						else if(AreaMinX[k]>j)
							AreaMinX[k] = j;
						if(AreaMaxY[k]<i)
							AreaMaxY[k] = i;
						else if(AreaMinY[k]>i)
							AreaMinY[k] = i;		
				} 	
		
			}
		}   
	} 
	AreaBlockMax = 0;
	for(i=0; AreaPixSum[i]!=0; i++)
	{
		if(AreaPixSum[i]>AreaBlockMax)
			AreaBlockMax = AreaPixSum[i];
	}
	AreaBlockNum = i;
	for(i=0; i<AreaBlockNum; i++)
	{
		AreaCenterX[i] = AreaCenterX[i]/AreaPixSum[i];
		AreaCenterY[i] = AreaCenterY[i]/AreaPixSum[i];
		AreaBlockHeight[i] = AreaMaxY[i] - AreaMinY[i] + 1;
		AreaBlockWidth[i] = AreaMaxX[i] - AreaMinX[i] + 1;
	}
	pfeature[0]= AreaBlockNum;
	pfeature[1]= AreaBlockMax;
	for(i=0; i<AreaBlockNum; i++)
	{
		pfeature[2 + i * 9 + 0]= AreaCenterX[i];
		pfeature[2 + i * 9 + 1]= AreaCenterY[i];
		pfeature[2 + i * 9 + 2]= AreaPixSum[i];
		pfeature[2 + i * 9 + 3]= AreaMaxX[i];
		pfeature[2 + i * 9 + 4]= AreaMinX[i];
		pfeature[2 + i * 9 + 5]= AreaMaxY[i];
		pfeature[2 + i * 9 + 6]= AreaMinY[i];
		pfeature[2 + i * 9 + 7]= AreaBlockHeight[i];
		pfeature[2 + i * 9 + 8]= AreaBlockWidth[i];										
	}
}

⌨️ 快捷键说明

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