This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

DM642图像处理问题

Other Parts Discussed in Thread: TVP5150

您好,我正在使用DM642进行图像处理方面的开发。前一阵子我测试了高斯滤波的程序,但出来的效果极不流畅,非常卡。经过一个多星期的学习和查资料,我发现在main函数中加入

 CACHE_setL2Mode(CACHE_128KCACHE);

   CACHE_clean(CACHE_L2ALL,0,0);

   CACHE_enableCaching(CACHE_EMIFA_CE00);

   CACHE_enableCaching(CACHE_EMIFA_CE01);

这四行代码后,实时的高斯滤波的流畅度有了大幅度的提升。我在此基础上加入了阈值分割的函数(转换成二值图),但不知道为什么程序运行后屏幕有近三分之二会闪烁,把CACHE_128KCACHE改成CACHE_64KCACHE或CACHE_32KCACHE后闪烁的区域会依次减小。把参数改为CACHE_256KSRAM闪烁现象消失,但流畅度又会极大降低。请问这是什么原因造成的?有什么办法解决吗?谢谢了!

  • 没人知道问题出在哪里吗?下面是我的源代码


    #include <csl.h>
    #include <csl_emifa.h>
    #include <csl_i2c.h>
    #include <csl_gpio.h>
    #include <csl_irq.h>
    #include <csl_chip.h>
    #include <csl_dat.h>
    #include "iic.h"
    #include "vportcap.h"
    #include "vportdis.h"
    #include "sa7121h.h"
    #include "TVP51xx.h"
    #include <csl_cache.h>

    /*VMD642的emifa的设置结构*/
    EMIFA_Config VMDEMIFConfig ={
        0x00052078,/*gblctl EMIFA(B)global control register value */
             /*将CLK6、4、1使能;将MRMODE置1;使能EK2EN,EK2RATE*/
        0xffffffd3,/*cectl0 CE0 space control register value*/
             /*将CE0空间设为SDRAM*/
        0x73a28e01,/*cectl1 CE1 space control register value*/
             /*Read hold: 1 clock;
               MTYPE : 0000,选择8位的异步接口
               Read strobe :001110;14个clock宽度
               TA:2 clock; Read setup 2 clock;
               Write hold :2 clock; Write strobe: 14 clock
               Write setup :7 clock
               --      ---------------
                \   14c  /1c
                \----------------/ */
        0x22a28a22, /*cectl2 CE2 space control register value*/
           0x22a28a42, /*cectl3 CE3 space control register value*/
        0x57226000, /*sdctl SDRAM control register value*/
        0x0000081b, /*sdtim SDRAM timing register value*/
        0x001faf4d, /*sdext SDRAM extension register value*/
        0x00000002, /*cesec0 CE0 space secondary control register value*/
        0x00000002, /*cesec1 CE1 space secondary control register value*/
        0x00000002, /*cesec2 CE2 space secondary control register value*/
        0x00000073 /*cesec3 CE3 space secondary control register value*/ 
    };

    /*VMD642的IIC的设置结构*/
    I2C_Config VMD642IIC_Config = {
        0,  /* master mode,  i2coar;采用主模式   */
        0,  /* no interrupt, i2cimr;只写,不读,采用无中断方式*/
        (20-5), /* scl low time, i2cclkl;  */
        (20-5), /* scl high time,i2cclkh;  */
        1,  /* configure later, i2ccnt;*/
        0,  /* configure later, i2csar;*/
        0x4ea0, /* master tx mode,     */
                /* i2c runs free,      */
                /* 8-bit data + NACK   */
                /* no repeat mode      */
        (75-1), /* 4MHz clock, i2cpsc  */
    };

    CHIP_Config VMD642percfg = {
     CHIP_VP2+\
     CHIP_VP1+\
     CHIP_VP0+\
     CHIP_I2C
    };

    I2C_Handle hVMD642I2C;
    int portNumber;
    extern SA7121H_ConfParams sa7121hPAL[45];
    extern SA7121H_ConfParams sa7121hNTSC[45];
    Uint8 vFromat = 0;
    Uint8 misc_ctrl = 0x6D;
    Uint8 output_format = 0x47;
    // 地址为0 for cvbs port1,选择复合信号做为输入
    Uint8 input_sel = 0x00;
    /*地址为0xf,将Pin27设置成为CAPEN功能*/ 
    Uint8 pin_cfg = 0x02;
    /*地址为1B*/
    Uint8 chro_ctrl_2 = 0x14;
    /*图像句柄的声明*/
    VP_Handle vpHchannel0;
    VP_Handle vpHchannel1;
    VP_Handle vpHchannel2;

    /*确定图像的参数*/
    int numPixels = 720;//每行720个像素
    int numLines  = 576;//每帧576行(PAL)

    int intThreshold=0x80;

    /*****平滑处理(高斯模板)函数声明*********/
    void GaussSmooth();
    #pragma CODE_SECTION(GaussSmooth,"ramfuncs1")
    void threshold();
    #pragma CODE_SECTION(threshold,"ramfuncs2")

     

    /*采集与显示缓冲区的首址*/
    Uint32 capYbuffer  = 0x80000000;
    Uint32 capCbbuffer = 0x800675c0;
    Uint32 capCrbuffer = 0x8009b0a0;
    #pragma DATA_ALIGN(capYbuffer,128)
    #pragma DATA_ALIGN(capCbbuffer,128)
    #pragma DATA_ALIGN(capCrbuffer,128)

    //Uint32 capCbbuffer = 0x6190; 
    //Uint32 capCrbuffer = 0x6190;

    Uint32 disYbuffer  = 0x81000000;
    Uint32 disCbbuffer = 0x810675c0;
    Uint32 disCrbuffer = 0x8109b0a0;
    #pragma DATA_ALIGN(disYbuffer,128)
    #pragma DATA_ALIGN(disCbbuffer,128)
    #pragma DATA_ALIGN(disCrbuffer,128)

    Uint32 tempSrcYbuffer    = 0x80200000;   //临时
    Uint32 tempDisYbuffer    = 0x81300000;   //临时

    #pragma DATA_SECTION(tempSrcYbuffer, ".tempSrcYbuffer")
    #pragma DATA_SECTION(tempDisYbuffer, ".tempDisYbuffer")

    #pragma DATA_ALIGN(tempSrcYbuffer,128)
    #pragma DATA_ALIGN(tempDisYbuffer,128)

    /*图像格式标志*/
    Uint8 NTSCorPAL = 0;
    extern far void vectors();
    extern volatile Uint32 capNewFrame;
    extern volatile Uint32 disNewFrame;


    /*此程序可将视频采集口1 CH1(第二个通道)的数据经过Video Port0送出*/
    void main()
    {
     Uint8 addrI2C;
     int i;
    /*-------------------------------------------------------*/
    /* perform all initializations                           */
    /*-------------------------------------------------------*/
     /*Initialise CSL,初始化CSL库*/
     CSL_init();
        CACHE_setL2Mode(CACHE_128KCACHE);
     CACHE_clean(CACHE_L2ALL,0,0);
        CACHE_enableCaching(CACHE_EMIFA_CE00);
        CACHE_enableCaching(CACHE_EMIFA_CE01);
        CHIP_config(&VMD642percfg);
     
     
    /*----------------------------------------------------------*/
     /*EMIFA的初始化,将CE0设为SDRAM空间,CE1设为异步空间
      注,DM642支持的是EMIFA,而非EMIF*/
     EMIFA_config(&VMDEMIFConfig);
    /*----------------------------------------------------------*/
     /*中断向量表的初始化*/
     //Point to the IRQ vector table
        IRQ_setVecs(vectors);
        IRQ_nmiEnable();
        IRQ_globalEnable();
        IRQ_map(IRQ_EVT_VINT1, 11);
        IRQ_map(IRQ_EVT_VINT0, 12);
        IRQ_reset(IRQ_EVT_VINT1);
        IRQ_reset(IRQ_EVT_VINT0);
        /*打开一个数据拷贝的数据通路*/
        DAT_open(DAT_CHAANY, DAT_PRI_LOW, DAT_OPEN_2D); 

    /*----------------------------------------------------------*/ 
     /*进行IIC的初始化*/
     hVMD642I2C = I2C_open(I2C_PORT0, I2C_OPEN_RESET);
     I2C_config(hVMD642I2C, &VMD642IIC_Config);

    /*----------------------------------------------------------*/
     /*进行TVP5150pbs的初始化*/
     /*选择TVP5150,设置视频采集第一通路ch0, 即U12*/

     /*将GPIO0不做为GPINT使用*/
     GPIO_RSET(GPGC, 0x0);

     /*将GPIO0做为输出*/
     GPIO_RSET(GPDIR, 0x1);

     /*GPIO0输出为高,选择IIC0总线*/
     GPIO_RSET(GPVAL, 0x0);

     /*选择第二个5150,U12*/
     addrI2C = 0xBA >> 1;
        _IIC_write(hVMD642I2C, addrI2C, 0x00, input_sel);
        _IIC_write(hVMD642I2C, addrI2C, 0x03, misc_ctrl);
        _IIC_write(hVMD642I2C, addrI2C, 0x0D, output_format);
        _IIC_write(hVMD642I2C, addrI2C, 0x0F, pin_cfg);
        _IIC_write(hVMD642I2C, addrI2C, 0x1B, chro_ctrl_2);
        /*回读当前摄像设备的格式*/
        _IIC_read(hVMD642I2C, addrI2C, 0x8c, &vFromat);
        vFromat = vFromat & 0xff;
     switch (vFromat)
     {
      case TVP51XX_NTSCM:
      case TVP51XX_NTSC443:
       NTSCorPAL = 1;/*系统为NTSC的模式*/
       break;
      case TVP51XX_PALBGHIN:
      case TVP51XX_PALM:
       NTSCorPAL = 0;/*系统为PAL的模式*/
       break;
      default:
       NTSCorPAL = 2;/*系统为不支持的模式*/
       break;
     }
     if(NTSCorPAL ==2)
     {
      /*系统不支持的模式,重新配置*/
      for(;;)
      {}
     } 
        
    /*----------------------------------------------------------*/ 
     /*进行SAA7121H的初始化*/

     /*GPIO0输出为低,选择IIC0总线,配置图像输出*/    
     GPIO_RSET(GPVAL, 0x0);
     /*选择第一个5150,即U10*/
     addrI2C = 0xB8 >> 1;
     /*将Video Port0的视频输入口的数据口设为高阻状态,
       使能SCLK,将第27脚设为输入*/
     _IIC_write(hVMD642I2C, addrI2C, 0x03, 0x1);

     /*配置SAA7121H*/
     /*GPIO0输出为低,选择IIC1总线,配置图像输出*/ 
     GPIO_RSET(GPVAL, 0x1);

     /*初始化Video Port0*/
     /*将Video Port0设为encoder输出*/
     portNumber = 0;
     vpHchannel0 = bt656_8bit_ncfd(portNumber);

     addrI2C = 0x88 >> 1;          
     for(i=0; i<43; i++)
     {
      if(NTSCorPAL == 1)
      {
       _IIC_write(hVMD642I2C,
            addrI2C,
            (sa7121hNTSC[i].regsubaddr),
            (sa7121hNTSC[i].regvule));
      }
      else
      {
       _IIC_write(hVMD642I2C,
            addrI2C,
            (sa7121hPAL[i].regsubaddr),
            (sa7121hPAL[i].regvule)); 
      }  
     }
     
    /*----------------------------------------------------------*/
     /*初始化Video Port1*/
     /*将Video Port1设为采集输入*/
     portNumber = 1;
     vpHchannel1 = bt656_8bit_ncfc(portNumber);

    /*----------------------------------------------------------*/
     bt656_capture_start(vpHchannel1);

     /*等待第一帧数据采集完成*/
     while(capNewFrame == 0){}
     /*将数据存入显示缓冲区,并清采集完成的标志*/
     capNewFrame = 0;

     for(i=0;i<numLines;i++)
     {
      /*传送临时Y缓冲区*/
      DAT_copy((void *)(capYbuffer + i * numPixels),
                  (void *)(tempSrcYbuffer + i * numPixels),
                  numPixels);
      /*传送临时Y缓冲区*/
      //DAT_copy((void *)(capYbuffer + i * numPixels),
                  //(void *)(tempDisYbuffer + i * numPixels),
                  //numPixels);     
      }


       /*平滑处理(高斯模板)*/
     GaussSmooth();

            threshold();

     /*给显示缓存区内的UV赋值*/
     for(i=0;i<0x33ae0;i++)
     {
         *((Uint8 *)(disCrbuffer +i)) =0x80;
         *((Uint8 *)(disCbbuffer +i)) =0x80;

     }
     
     
     for(i=0;i<numLines;i++)
     {
      /*传送Y缓冲区*/
      DAT_copy((void *)(tempDisYbuffer + i * numPixels),
                  (void *)(disYbuffer + i * numPixels),
                  numPixels);
     }

     /*启动显示模块*/
     bt656_display_start(vpHchannel0);
     /*建立显示的实时循环*/
     for(;;)
     {
      /*当采区的数据已经采集好,而显示缓冲区的数据已空*/
      if((capNewFrame == 1)&&(disNewFrame == 1))
      {
       /*将数据装入显示缓冲区,并清采集完成的标志*/
       capNewFrame =0;
       disNewFrame =0;


       for(i=0;i<numLines;i++)
       {
        /*传送临时Y缓冲区*/
        /*传送临时Y缓冲区*/
        DAT_copy((void *)(capYbuffer + i * numPixels),
                    (void *)(tempSrcYbuffer + i * numPixels),
                    numPixels);
           /*传送临时Y缓冲区*/
        //DAT_copy((void *)(capYbuffer + i * numPixels),
                    //(void *)(tempDisYbuffer + i * numPixels),
                    //numPixels);     
        }
           
      
        
         /*平滑处理(高斯模板)*/
         GaussSmooth();

                threshold();
       
             for(i=0;i<numLines;i++)
       {
        /*传送Y缓冲区*/
           DAT_copy((void *)(tempDisYbuffer + i * numPixels),
                    (void *)(disYbuffer + i * numPixels),
                    numPixels);    
        }   
      }
     }
    }    

     


    /*****平滑处理(高斯模板)*********/
    void GaussSmooth()
    {
     int i,j;
     float fTemp;
     int intTemp; 
     
     for(i=0;i<288;i++)
     {
         for(j=0;j<720;j++)
         {
          /*屏幕上奇数行进行处理*/
          /*用高斯模板进行处理*/
          fTemp = (*(Uint8 *)(tempSrcYbuffer + (287+i)*numPixels + (j-1))) +
                  2*(*(Uint8 *)(tempSrcYbuffer + (287+i)*numPixels + j)) +
                  (*(Uint8 *)(tempSrcYbuffer + (287+i)*numPixels + (j+1))) +
               2*(*(Uint8 *)(tempSrcYbuffer + i*numPixels + (j-1))) +
                  4*(*(Uint8 *)(tempSrcYbuffer + i*numPixels + j)) +
                  2*(*(Uint8 *)(tempSrcYbuffer + i*numPixels + (j+1))) +
                        (*(Uint8 *)(tempSrcYbuffer + (288+i)*numPixels + (j-1))) +
                  2*(*(Uint8 *)(tempSrcYbuffer + (288+i)*numPixels + j)) +
                  (*(Uint8 *)(tempSrcYbuffer + (288+i)*numPixels + (j+1)));
              
         intTemp = (int)(fTemp/16 + 0.5);
         
         if(intTemp<0)
         {
          intTemp = 0;
         }
         
         if(intTemp>255)
         {
          intTemp = 255;
         }
          
          //屏幕上奇数行进行处理
          *(Uint8 *)(tempDisYbuffer + i*numPixels + j) = intTemp;
          
          /*屏幕上偶数行进行处理*/
          /*用高斯模板进行处理*/
          fTemp = (*(Uint8 *)(tempSrcYbuffer + i*numPixels + (j-1))) +
                  2*(*(Uint8 *)(tempSrcYbuffer + i*numPixels + j)) +
                  (*(Uint8 *)(tempSrcYbuffer + i*numPixels + (j+1))) +
                  2*(*(Uint8 *)(tempSrcYbuffer + (i+288)*numPixels + (j-1))) +
                  4*(*(Uint8 *)(tempSrcYbuffer + (i+288)*numPixels + j)) +
                  2*(*(Uint8 *)(tempSrcYbuffer + (i+288)*numPixels + (j+1))) +     
                  (*(Uint8 *)(tempSrcYbuffer + (i+1)*numPixels + (j-1))) +
                  2*(*(Uint8 *)(tempSrcYbuffer + (i+1)*numPixels + j)) +
                  (*(Uint8 *)(tempSrcYbuffer + (i+1)*numPixels + (j+1)));
         
         intTemp = (int)(fTemp/16 + 0.5);
         
         if(intTemp<0)
         {
          intTemp = 0;
         }
         
         if(intTemp>255)
         {
          intTemp = 255;
         }
         
          //屏幕上偶数行进行处理
          *(Uint8 *)(tempDisYbuffer + (i+numLines/2)*numPixels + j) = intTemp;       
          
          
         }
     }
       
    }  

    void threshold()
    {
     int i,j;
     //方框内奇数行
     for(i=0;i<288;i++)//行数
     {
         for(j=0;j<720;j++) //像素数/每行
         {
             *(Uint8 *)(tempDisYbuffer + i*numPixels + j) = *(Uint8 *)(tempDisYbuffer + i*numPixels + j)<intThreshold?0x00:0xFF;
         } 
     }
     
     //方框内偶数行
     for(i=288;i<576;i++)//行数
     {
         for(j=0;j<720;j++) //像素数/每行
         {  
             *(Uint8 *)(tempDisYbuffer + i*numPixels + j) = *(Uint8 *)(tempDisYbuffer + i*numPixels + j)<intThreshold?0x00:0xFF;  
            }
     }  
    }

  • 你好,我也在使用DM642