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

📄 黑线提取(浙江大学参考).cpp

📁 黑线提取算法
💻 CPP
字号:
//思路:遇到交叉道上找到与原来已经找到的线偏差最小的线(十字交叉道问题)
char FindCenter(void)
{
int tmp,residual;

int extra=0;                       //前方黑线的增减值,这是用来做什么的? 
int black=0;                       //黑线等于0 
char i,j,p,q,k,lose_flg;           
char distance=0;                   //黑线宽度
char interval=20;                  //相邻两行的跳变
//int BlackNumber;
char L_column=0;                   //黑线左侧坐标 从左至右搜索
char R_column=0;                   //黑线右侧坐标
char L_column2=0;                  //黑线左侧坐标 从右至左搜索
char R_column2=0;                  //黑线右侧坐标
char L_next=0;                     //搜索尾部使用
char R_next=0;                     //搜索尾部使用 
char tolance=8;                    //断线可以忍受的最长距离 
char min_column=0;                 
int temp_error;                    //纠正系数,断线后纠正系数 
int error[ROW];                    //存储错误的行 
lose_flg=0;                        //丢失的标志 
S_falg=0;
for(i=ROW-1;i>=40;i--)        //表示从尾行开始遍历 
{
//BlackNumber=15-(ROW-i)*5/ROW;

//黑线左右坐标初始化 
   L_column=-1;
   R_column=-1;
   L_next=-1;
   R_next=-1;
 
   for(k=1;k<COLUMN;k++)            //从左边第一列开始 
   {
      for(j=k;j<COLUMN;j++)        //从当前列开始 
      {
         if((img[i][j])<=100 && img[i-1][j]<=100 && img[i-2][j]<=100)     
         //连续三行同列的数据均小于阙值,表示在底部找到了连续三行黑点的位置 
         {
             L_next=j;            //从左边记录出现此情况的列数 
             break;
         }
      }
      for(j++;j<COLUMN;j++)        //注意分析清楚L_NEXT和R_NEXT的作用,貌似很重要 
      {
         if((img[i][j])>100 || (img[i-1][j])>100 || (img[i-2][j])>100)      //向右移动一行,连续三行出现白线
                                                 //即:向右移动直至出现白线的情况  
         { 
             R_next=j-1;          //记录下黑线右边沿 
             break;
         }
      }
      if(R_next==-1&&L_next!=-1)     //have L_next ,but no R_next
                                      //表示没有黑线右边沿 
         R_next=COLUMN-1;             //直接赋值 
      if(R_next-L_next>=15 || L_next==-1 || R_next-L_next<=0)         //不符合要求,进行黑线宽度限定 
         continue;
      else if(R_next-L_next>distance)        //大于0 
      {
         R_column=R_next;                    //黑线左边宽度确定 
         L_column=L_next;                    //黑线右边宽度确定 
         distance=R_next-L_next;             //distance确定,本行黑线宽度 
      }
   }
   if(distance>2 && distance<15)             //在合适的范围内 
      break;
}
min_column=(L_column+R_column)/2;            // 
if(i>40) tail=i; //在23行以下,且在5行以上
else return -1; //do not find center
path[tail]=min_column;
distance=15; //黑线宽度
if((R_column==COLUMN-1 || L_column==1/* */||L_column==0) && distance<10)
distance=15;
for(i--;i>0;i--) //再往上搜
{
if(lose_flg==0)
{
p=L_column-8;//-5
q=R_column+8; //+5
if(p<0) p=0;
if(q>=COLUMN) q=COLUMN-1;
}
else
{
p=p-1;
q=q+1;

if(p<0)
p=0;
if(q>=COLUMN)
q=COLUMN-1;
}
L_column=-1;
R_column=-1;
//从左往右搜
//search_flag=0
if(i<=30)
extra=15;
else
extra=0;
for(j=p;j<=q;j++)
{
if(img[i][j]<=BALCKPOINT+extra) //wh
{
L_column=j;
break;
}
} //往上搜
for(j++;j<=q;j++)
{
if(img[i][j]>BALCKPOINT+extra)
{
R_column=j-1;
break;
}
}
if(L_column!=-1&&R_column==-1)
{
for(j=q;j<COLUMN;j++)
if(img[i][j]>BALCKPOINT+extra)
break;
R_column=j-1;
}
if(L_column==p)//L_column is at the most left point,search for the first black
point
{
for(j=p;j>=0;j--)
if(img[i][j]>BALCKPOINT+extra)
break;
L_column=j+1;

}//如果P是黑点,在继续往前搜
//从左往右搜结束
//记录数据
L_column2=-1;
R_column2=-1;
//从右往左搜
for(j=q;j>=p;j--)
{
if(img[i][j]<=BALCKPOINT+extra) //wh
{
R_column2=j;
break;
}
} //往上搜
for(j--;j>=p;j--)
{
if(img[i][j]>BALCKPOINT+extra)
{
L_column2=j+1;
break;
}
}
/****************************************/
if(R_column2!=-1&&L_column2==-1)
{
for(j=p;j>=0;j--)
if(img[i][j]>BALCKPOINT+extra)
break;
L_column2=j+1;
}
/******************************************/
if(R_column2==q)//L_column is at the most left point,search for the first black
point
{
for(j=q;j<COLUMN;j++)
if(img[i][j]>BALCKPOINT+extra)
break;
R_column2=j-1;
}//如果P是黑点,在继续往前搜
//从右往左搜结束

//左右已采稳
tmp=-1;
min_column=(R_column+L_column)/2;
if(L_column!=-1&&L_column2!=-1&&R_column!=-1&&R_column2!=-1&&(R_column!=R_colum
n2||L_column!=L_column2))
{
if(fabs((L_column+R_column)/2-path[i+1+lose_flg])>fabs((L_column2+R_column2)/2-
path[i+1+lose_flg]) )
{
min_column=(R_column2+L_column2)/2;
R_column=R_column2;
L_column=L_column2;
}
}
if(R_column-L_column<=(distance+5<15 ? distance+5:15)
&&R_column-L_column>=0 && min_column-path[i+1+lose_flg]<=10 &&
min_column-path[i+1+lose_flg]>=-10&& L_column!=-1)
{
path[i]=min_column;
while(lose_flg>0)
{
path[i+lose_flg]=(path[i]+path[i+lose_flg+1])/2;
lose_flg--;
}
interval=path[i]-path[i+1];
//////////////////////////////////////////////////WH
distance=R_column-L_column;
/***********************************************/
}
else
{
report_data("R_column-L_column-distance",R_column-L_column-distance);
report_data("path[tail]",path[tail]);
report_data("path[i+1+lose_flg]",path[i+1+lose_flg]);
report_data("path[i]",min_column);
if(i<=30)
tolance=6-(40-i)/10;
else
tolance=6;
lose_flg++;

if(lose_flg>=tolance)
break;
}
}
head=i+1+lose_flg;
report_data("head",head);
i=getchar();
if(i=='a')
report_img();
if(StartOn)
find_start();
if(!S_falg)
inc_lose();
for(i=head;i<=tail;i++) //图像修正
{
path[i]=(path[i]-CENTER_WH)*(i*i/4-29*i+950)/100;
}
return tail-head+1;
}
void find_start()
{
unsigned char i;
char j=0;
char p=0;
char q=0;
char n=0;
char LeftFlg=0;
char RightFlg=0;
char BlackFlg=0;
S_falg=0;
if(head+2>20)
n=head+2;
else
n=20;
for(i=tail;i>=n;i--)
{
p=path[i]-15;
q=path[i]+15;
if(p<0)
p=0;
if(q>=COLUMN)
q=COLUMN-1;
LeftFlg=0;

RightFlg=0;
BlackFlg=0;
/* for(j=0;j<10&&(p+j)<path[i]-10&&(q-j)>path[i]+10;j++)
{
if((img[i][p+j]&0x02)+(img[i-1][p+j]&0x02)+(img[i-2][p+j]&0x02)<=4 &&
(img[i][q-j]&0x02)+(img[i-1][q-j]&0x02)+(img[i-2][q-j]&0x02)<=4)
BlackFlg++;
else
BlackFlg=0;
if(BlackFlg>=3)
{
p=p+j;
q=q-j;
break;
}
} */
for(j=p;j<path[i]-7;j++)
if(Is_Black_Point(i,j))
{
BlackFlg++;
p=j;
break;
}
for(j=q;j>path[i]+7;j--)
if(Is_Black_Point(i,j))
{
BlackFlg++;
q=j;
break;
}
// if(Is_Black_Point(i,p) && Is_Black_Point(i,q))
// BlackFlg=1;
//if((img[i][p]&0x02)+(img[i-1][p]&0x02)+(img[i-2][p]&0x02)<=4 &&
(img[i][q]&0x02)+(img[i-1][q]&0x02)+(img[i-2][q]&0x02)<=4)
// BlackFlg=1;
if(BlackFlg>=2)
{
while(!Is_While_Point(i,p) && p<path[i]-2) p++;
while(Is_While_Point(i,p) && p<path[i])
{
LeftFlg++;
p++;
}

while(!Is_While_Point(i,q) && q>path[i]+2) q--;
while(Is_While_Point(i,q) && q>path[i])
{
q--;
RightFlg++;
}
if(LeftFlg>0 && RightFlg>0 && fabs(LeftFlg-RightFlg)<=4 &&
(Is_While_Point(i,1) || Is_While_Point(i,COLUMN-2)))
{
S_falg=1;
// PWMDTY23=0;
// report_data("i",i);
// report_img();
break;
}
}
}
if(!S_falg)
return;
if(lose_start==((int)start_line)*200)// 第 n 次看到起点
{
start_line++;
lose_start++;
if(start_line==rap)
EndFlg=1;
}
}
char Is_Black_Point(int i,int j)
{
if(img[i][j]<=120 || img[i-1][j]<=120 || img[i+1][j]<=120)
return 1;
else
return 0;
}
char Is_While_Point(int i,int j)
{
if(img[i][j]>=140 && img[i-1][j]>=140 && img[i+1][j]>=140)
return 1;
else
return 0;
}

void inc_lose(void)
{
if(lose_start<start_line*200 && lose_start!=0)
{
lose_start++;
}
}

⌨️ 快捷键说明

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