• 用FPGA实现视频中物体边缘二值化


           对于高速视频图像中的物体轮廓提取中,图像的二值化,采用软件方式,速度无法满足需要,因此要采用FPGA方案,这样可以实现二值化速度和帧率一样,完全和视频同步。

    一、算法原理:  边缘二值化的算法很多,象sobel法,roberts法,拉普拉斯法,导数法。为了简单化,采用导数法。

           视频图像每帧扫描顺序如下图的黑色箭头所示  

         为了保证二值化和视频同步,必须要求视频每扫描一个点,就立刻进行二值化处理,也就是说每个像素点时钟进行一次。每个点(如上图红色点)进行锐化求导只能和已经出现过的相邻点(如图上图绿色4个点)进行,当前点的锐化导数值subv为:

                  subv=max(|v-v10|,|v-v00|,|v-v01|,|v-v02|) ,即和相邻点差值绝对值最大一个作为其锐化值

          当subv大于规定的值时,标记该点是1,否则是0,实现图像二值化。

    二、FPGA结构原理图如下:

    说明:

         1. CMOS摄像头连接camera接口上,该接口模块提取视频数据分成2路:1)保存到双口RAM1中,以便下一行点锐化用。2)和上一行里的4个数据进行比  较,得到锐化的二值化数据存放到双口ram2中。

         2. CMOS摄像头同时连接S3c2440(三星arm,带camera接口)    

         3 。数据读取模块根据TFT时序发生器送来的控制,选取RAM2或者S3c2440送来的视频数据。通过TFT时序发生器将两个视频数据合并同时显示在屏幕上。这种结构主要目的是把原始图像和处理后的图像同时显示,以便对比调试。

    三、verilog HDL 代码:

    // 定义了一个双口ram存放可存放640*480个二值化像素点

     RAM2PORT cambuf_ram(sharp_caminv,sharp_camreadAdr,ARM_DCLK,sharp_camadr,LVDS_PCLK,1,sharp_camoutv);
    //////////////////////////////////////////////////////////////////////
    always @( negedge LVDS_PCLK) //相机时钟下降沿,(这里的LVDS把相机所有信号传来)
    begin
            if (LVDS_VS==0)   //相机的帧时钟=0
                    begin
                              cam_pcnt=0;//每行点计数器清
                              cam_hcnt=0; //每帧行计数器清

                    end
            else
                    begin
                            if (LVDS_HS==0)  //相机的行时钟
                                    begin
                                            cam_pcnt=0;  //每行点有效点计数器清空
                                            hs1=0;
                                   end
                            else
                                    begin
                                            if (hs1==0)
                                            begin
                                                    hs1=1;
                                                    cam_hcnt=cam_hcnt+1; //每帧行计数器加
                                            end
                                          cam_pcnt=cam_pcnt+1;
                                          if ((cam_pcnt<1280)&&(cam_hcnt<480)) //注意每行有效点1280,不是640,因为YUV格式,每个点需要传送两个时钟
                                                    begin
                                                            camadr=cam_pcnt[15:1; 
                                                            sharp_camadr=cam_hcnt*640+camadr; //二值化双口RAM地址
                                                            
                                                            if(cam_pcnt%2==1)
                                                             begin
                                                                   camLastV10<= camLastV11;  //获取对应邻近点值V10
                                                                   camLastV11<=LVDS_D;        //当前点值v11是当前点
                                                                   
                                                                   camLastV00<= camLastV01;//获取对应邻近点值V00
                                                                   camLastV01<= camLastV02;////获取对应邻近点值V01
                                                                    camLastV02<=camLastV11buf[camadr+1]; //获取对应邻近点值V02,注意V02是从上一行的RAM
                                                                   camLastV11buf[camadr]<=LVDS_D;//保存当前点到上一行中
                                                                   
                                                                   //以下是和相邻的4个点进行比较,最大差值作为锐化导数值
                                                                  subv1=camLastV00>camLastV11?camLastV00-camLastV11:camLastV11-camLastV00;
                                                                  subv2=camLastV10>camLastV11?camLastV10-camLastV11:camLastV11-camLastV10;
                                                                  subv3=camLastV01>camLastV11?camLastV01-camLastV11:camLastV11-camLastV01;
                                                                  subv4=camLastV02>camLastV11?camLastV02-camLastV11:camLastV11-camLastV02;
                                                                  subv=subv1>subv2?subv1:subv2;
                                                                  subv=subv>subv3?subv:subv3;
                                                                  subv=subv>subv4?subv:subv4;
                                                                  sharp_caminv= (subv>sharpv0)?1:0; //二值化,结果保存到双口ram中
                                                                 
                                                             end
                                                    end
                                    end
                    end
    end

    四、运行结果照片和视频

          该FPGA软件方案在北京数磊的IEC03工业智能相机运行结果如下:

         1. 照片

         

       2.演示视频(录像时用手机录的,不是很清楚,请大家包涵了)

         http://v.youku.com/v_show/id_XNDQ1ODg1ODUy.html

          机器视觉产品 

    www.shuleikeji.com
  • 相关阅读:
    笨方法学python(本文为阅读时从此书摘录的笔记) 第一天
    关于C++中的虚拟继承的一些总结
    用提高效率的暴力法求3000以内的素数
    DAY 155 python中parse模块
    DAY 154 python自带的hmac模块
    DAY 153 Python中使用pymongo操作mongodb
    DAY 152 hmac模块
    DAY 151 parse模块
    DAY 150 setter&getter&@property
    DAY 149 property和setter装饰器
  • 原文地址:https://www.cnblogs.com/dongchunxiao/p/2666270.html
Copyright © 2020-2023  润新知