搜索
bottom↓
回复: 1

求解摄像头采集问题

[复制链接]

出0入0汤圆

发表于 2014-4-21 21:35:50 | 显示全部楼层 |阅读模式
本帖最后由 lidreamer 于 2014-4-21 21:45 编辑

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


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

#define BLACK  0x00
#define WHITE  0xfe
#define ThreadHold  0x30
#define rowStart 10       //图像处理起始行数
#define rowEnd   50      //图像处理终止行数
#define rowNum   rowEnd-rowStart  //有效处理行数,原始采集行数为ROW(在Include.h中定义)
#define proPix   5        //边缘跟踪搜索边界有效像素  
#define CENTURE  154      //中心值



#define   EDGE  WHITE-BLACK    //边界值大小

u8 Buffer1[ROW][COL]={0};      //通过DMA采集(在isr.c中行中断中触发DMA采集)二维图像存储于Buffer1数组中,ROW,COL在Include.h中定义
void  Send_Image();
u32 zuo[rowNum] = {0};         //存放有效处理行中双线左边缘的列坐标,初始化为0
u32 you[rowNum] = {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[ROW]={0};
u8 ImageBuf[ROW][COL];
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[j] <= ThreadHold)
             ImageBuf[j]=BLACK;
          else
             ImageBuf[j]=WHITE;
         }
       }
   //----------------边缘搜索开始-----------------//   
   //--------搜索rowStart前一行左右边缘点作为基准----------
   for(i=rowStart-1,time= 100;time>0 ;time--)   //至多搜索100次 防止1次未搜索到边缘
   {
    for(j=49;j>1;j--)           //左边缘搜索
    {
      if(Buffer1[j]-Buffer1[j-1] == EDGE )    //从白跳变到黑  WHITE-BLACK
      {
        zuoPos = j;
        break;
      }
      else
      {
         zuoPos = j;  //未搜索到边界
         continue;
      }
    }
       //-------------左边缘搜索END------------------           
        //------------右边缘搜索------------------
    for(j=50;j<COL-1;j++)           //右边缘搜索
    {
      if(Buffer1[j]-Buffer1[j+1] == 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[j]-Buffer1[j-1] == EDGE )   //EDGE=WHITE-BLACK   黑白变化量。
          {
            zuo[i-rowStart] = 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[j+1]-Buffer1[j] == EDGE )   //EDGE=WHITE-BLACK   黑白变化量。
            {
              zuo[i-rowStart] = j;
              turn++;                 //turn 弯道
              zuoEdgeFlag = 1;
              break;
            }
            else
            {
              continue;
           }
          }
        }      
       //---右边缘跟踪
        for(j=youPos;j>youPos-proPix;j--)
        {
          if(j<=0)  break;   //断言
         
          if(Buffer1[j-1]-Buffer1[j] == EDGE )//右边缘向左搜索     //EDGE=WHITE-BLACK   黑白变化量。
          {
            you[i-rowStart] = j;
            turn --;
            youEdgeFlag = 1;
            break;
          }
          else
          {
            continue;
          }
        }
        if( youEdgeFlag == 0)
        {
          for(j=youPos;j<youPos+proPix;j++)   //右边缘向右搜索
          {
            if(j>=COL-1)  break;   //断言
         
            if(Buffer1[j]-Buffer1[j+1] == EDGE)    //EDGE=WHITE-BLACK   黑白变化量。
            {
              you[i-rowStart] = j;
              turn++;
              youEdgeFlag = 1;
              break;
            }
            else
            {
              continue;
            }
          }
        }      
        if( zuoEdgeFlag == 0 )      //左边未找到边缘
          //根据趋势预测左边缘值
        {
          if(turn>0)        zuoPos++;
          else if(turn<0)   zuoPos--;
          else;
        }
     
        else
          zuoPos = zuo[i-rowStart];
        
        if( youEdgeFlag == 0 )    //右边未找到边缘
          //根据趋势预测左边缘值
        {
          if(turn>0)        youPos++;
          else if(turn<0)   youPos--;
          else;
         
        }
        else
          youPos = you[i-rowStart];
        
        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;   //求车体当前位置    求中线。     
      }
         }
}
}
void  Send_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[centure]=BLACK;
          else if(ImageBuf[j] <= ThreadHold)
            ImageBuf[j]=BLACK;
          else
            ImageBuf[j]=WHITE;
         
         }   

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

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2014-5-1 10:04:58 | 显示全部楼层
K60采集200*100的都木问题,建议楼主还是自己写程序吧,卖家给的程序都比较坑爹,现在距比赛还有两个多月,时间足够了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-6 09:13

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表