📄 ob_track.c.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 + -