lidreamer 发表于 2014-4-21 21:35:50

求解摄像头采集问题

本帖最后由 lidreamer 于 2014-4-21 21:45 编辑

摄像头本来是能采集出来二值化图像的,
但是加了中线提取算法之后出来的图像就是这样的。
这难道是提取中线的程序太长?我用的是K60,摄像头采集100行40列,,
求指导。
附上我的来自岱默提取中线算法。


#include "common.h"
#include "include.h"

#define BLACK0x00
#define WHITE0xfe
#define ThreadHold0x30
#define rowStart 10       //图像处理起始行数
#define rowEnd   50      //图像处理终止行数
#define rowNum   rowEnd-rowStart//有效处理行数,原始采集行数为ROW(在Include.h中定义)
#define proPix   5      //边缘跟踪搜索边界有效像素
#define CENTURE154      //中心值



#define   EDGEWHITE-BLACK    //边界值大小

u8 Buffer1={0};      //通过DMA采集(在isr.c中行中断中触发DMA采集)二维图像存储于Buffer1数组中,ROW,COL在Include.h中定义
voidSend_Image();
u32 zuo = {0};         //存放有效处理行中双线左边缘的列坐标,初始化为0
u32 you = {COL-1};   //存放有效处理行中双线右缘的列坐标,初始化为COL-1

s32 zuoPos = 0;          //左边界位置[有符号数]
s32 youPos = 0;          //右边界位置[有符号数]
u32 centure = 0;         //计算出的当前车体的中心位置[无符号数]
s32 centureErr = 0;      //计算出的当前车体位置偏差 [有符号数]
s32 turn = 0;            //边界走势正为向左偏转负为向右偏转
u8 zuoEdgeFlag = 0;      //左边界确认标志,找到后边界置位
u8 youEdgeFlag = 0;      //右边界确认标志,找到后边界置位
u8 centure1;
u8 VSYN_Flag = 0;      //完成一场标识位0为未完成;1为完成
u8 time;
u8 Image_Center={0};
u8 ImageBuf;
void ImageProc();
void Send_Image();
volatile u8 VSYN = 1;
volatile u32 rowCnt = 0 ;

void main()
{
DisableInterrupts;
      sccb_init();   
      //----------SCCB寄存器配置---------------//
      sccb_regWrite(0x42,0x11,0x03);    //地址0X11-中断四分频(640*240)         PCLK:166ns   HREF:254.6us   VSYN:133.6ms
      sccb_regWrite(0x42,0x14,0x24);      //地址0X14-QVGA(320*120)                  PCLK:332ns   HREF:509.6us   VSYN:133.6ms
      sccb_regWrite(0x42,0x28,0x20);      //地址0X28-连续采集模式(320*240)            PCLK:666ns   HREF:509.6us   VSYN:133.6ms
      sccb_wait();   
    //----初始化图像数组----//
      uart_init (UART0, 115200);
      exti_init(PORTA, 9, rising_down);       //HREF----PORTA3 端口外部中断初始化 ,上升沿触发中断,内部下拉
   exti_init(PORTA, 27, falling_down);      //VSYN----PORTA5 端口外部中断初始化 ,上升沿触发中断,内部下拉
      
   // EnableInterrupts;
    while(1)
    {
      ImageProc();
      Send_Image();
      EnableInterrupts;
    }
}
void ImageProc()
{
u32 i,j;
//DisableInterrupts;            //禁止中断
      uart_putchar(UART0,0);

//---------图像二值化,小于阈值为BLACK,大于阈值为WHITE---------

      for(i=0; i<ROW; i++)
      {
      for(j=0;j<COL ;j++)
      {
          if(ImageBuf <= ThreadHold)
             ImageBuf=BLACK;
          else
             ImageBuf=WHITE;
         }
       }
   //----------------边缘搜索开始-----------------//   
   //--------搜索rowStart前一行左右边缘点作为基准----------
   for(i=rowStart-1,time= 100;time>0 ;time--)   //至多搜索100次 防止1次未搜索到边缘
   {
    for(j=49;j>1;j--)         //左边缘搜索
    {
      if(Buffer1-Buffer1 == EDGE )    //从白跳变到黑WHITE-BLACK
      {
      zuoPos = j;
      break;
      }
      else
      {
         zuoPos = j;//未搜索到边界
         continue;
      }
    }
       //-------------左边缘搜索END------------------         
      //------------右边缘搜索------------------
    for(j=50;j<COL-1;j++)         //右边缘搜索
    {
      if(Buffer1-Buffer1 == EDGE)   //从白跳变到黑WHITE-BLACK (1-0)
      {
      youPos = j;
      break;
      }
      else
      {
      youPos = j;//未搜索到边界
      continue;
      }
    }
      //-------------右边缘搜索END-----------------
    if( zuoPos == 2 && youPos == COL-2)//未搜到边界图像异常 继续搜索
      continue;   
    else
      break;       //搜索到退出
   }
//-------------基准点搜索结束----------//

//----搜索未超时,图像正常---------//
    if(time > 0)
    {
      //-----开始边缘跟踪--------
      for(i=rowStart;i<rowEnd;i++)
      {
      //----左边缘跟踪
      for(j=zuoPos;j>zuoPos-proPix;j--)//左边缘向左跟踪    减少程序的运行时间,提高效率。
      {
          if(j<=0)break;   //断言
         
          if(Buffer1-Buffer1 == EDGE )   //EDGE=WHITE-BLACK   黑白变化量。
          {
            zuo = j;
            turn--;
            zuoEdgeFlag = 1;    //左标志位 1
            break;
          }
          else
          {
            continue;   //没找到,继续。
          }
      }
      
      if( zuoEdgeFlag == 0 )
      {
          for(j=zuoPos;j<zuoPos+proPix;j++)//左边缘向右跟踪   proPix=5有什么特殊?这个可能是自己取的经验值
          {
            if(j>=COL-1)break;      //断言
         
            if(Buffer1-Buffer1 == EDGE )   //EDGE=WHITE-BLACK   黑白变化量。
            {
            zuo = j;
            turn++;               //turn 弯道
            zuoEdgeFlag = 1;
            break;
            }
            else
            {
            continue;
         }
          }
      }      
       //---右边缘跟踪
      for(j=youPos;j>youPos-proPix;j--)
      {
          if(j<=0)break;   //断言
         
          if(Buffer1-Buffer1 == EDGE )//右边缘向左搜索   //EDGE=WHITE-BLACK   黑白变化量。
          {
            you = j;
            turn --;
            youEdgeFlag = 1;
            break;
          }
          else
          {
            continue;
          }
      }
      if( youEdgeFlag == 0)
      {
          for(j=youPos;j<youPos+proPix;j++)   //右边缘向右搜索
          {
            if(j>=COL-1)break;   //断言
         
            if(Buffer1-Buffer1 == EDGE)    //EDGE=WHITE-BLACK   黑白变化量。
            {
            you = j;
            turn++;
            youEdgeFlag = 1;
            break;
            }
            else
            {
            continue;
            }
          }
      }      
      if( zuoEdgeFlag == 0 )      //左边未找到边缘
          //根据趋势预测左边缘值
      {
          if(turn>0)      zuoPos++;
          else if(turn<0)   zuoPos--;
          else;
      }
   
      else
          zuoPos = zuo;
      
      if( youEdgeFlag == 0 )    //右边未找到边缘
          //根据趋势预测左边缘值
      {
          if(turn>0)      youPos++;
          else if(turn<0)   youPos--;
          else;
         
      }
      else
          youPos = you;
      
      if(zuoPos<0)    zuoPos = 0;               //自己去边缘线?
      if(youPos>COL-1)youPos = COL-1;
      
       zuoEdgeFlag = 0;
       youEdgeFlag = 0;         
      //-----结束边缘跟踪--------
      
      //---边缘修正------
      for(i=0;i<rowNum;i++)
      {
      if(zuo== 0 && turn<0)       zuo=0;   //左边缘到了左边界
      if(zuo== 0 && turn>0)      zuo=COL-1;//左边缘到了右边界
      if(you== COL-1 && turn<0)      you=0;//右边缘到了左边界
      if(you== COL-1 && turn>0)      you=COL-1;//右边缘到了右边界
      }         
      //-----提取当前车体的偏移量
    for(i=0;i<rowNum;i++)   //rowNum = rowstar-rowstar ==100
      {   
      zuoPos += zuo;
      youPos += you;
      centure = (zuoPos + youPos)/2;   //求车体当前位置    求中线。   
      }
         }
}
}
voidSend_Image()
{
EnableInterrupts;
u32 i,j;
   uart_putchar(UART0,0xff);
   for(i=rowStart; i<rowEnd; i++)
      {
      for(j=0;j<COL ;j++)
      {
          if(j==centure)
            ImageBuf=BLACK;
          else if(ImageBuf <= ThreadHold)
            ImageBuf=BLACK;
          else
            ImageBuf=WHITE;
         
         }   

}
uart_putchar(UART0,ImageBuf);
//DisableInterrupts;            //禁止中断
}

tearedice 发表于 2014-5-1 10:04:58

K60采集200*100的都木问题,建议楼主还是自己写程序吧,卖家给的程序都比较坑爹,现在距比赛还有两个多月,时间足够了
页: [1]
查看完整版本: 求解摄像头采集问题