求解摄像头采集问题
本帖最后由 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; //禁止中断
} K60采集200*100的都木问题,建议楼主还是自己写程序吧,卖家给的程序都比较坑爹,现在距比赛还有两个多月,时间足够了
页:
[1]