找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 7228|回復: 9
收起左側

stm32f4與ov2640二維碼識別源碼

  [復制鏈接]
ID:299647 發(fā)表于 2018-10-19 19:54 | 顯示全部樓層 |閱讀模式
大家可以試著嘗試一下,因為是源碼

單片機源程序如下:
  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "lcd.h"
  4. #include "usart.h"
  5. #include "sram.h"   
  6. #include "malloc.h"   
  7. #include "string.h"       
  8. #include "dcmi.h"       
  9. #include "ov2640.h"
  10. #include "led.h"
  11. #include "key.h"
  12. #include "beep.h"
  13. #include "sdio_sdcard.h"  
  14. #include "ff.h"  
  15. #include "w25qxx.h"   
  16. #include "exfuns.h"   
  17. #include "fontupd.h"
  18. #include "text.h"       
  19. #include "atk_qrdecode.h"

  20. u16 qr_image_width;                                                //輸入識別圖像的寬度(長度=寬度)
  21. u8         readok=0;                                                        //采集完一幀數據標識
  22. u32 *dcmi_line_buf[2];                                        //攝像頭采用一行一行讀取,定義行緩存  
  23. u16 *rgb_data_buf;                                                //RGB565幀緩存buf
  24. u16 dcmi_curline=0;                                                //攝像頭輸出數據,當前行編號

  25. //攝像頭數據DMA接收完成中斷回調函數
  26. void qr_dcmi_rx_callback(void)
  27. {  
  28.         u32 *pbuf;
  29.         u16 i;
  30.         pbuf=(u32*)(rgb_data_buf+dcmi_curline*qr_image_width);//將rgb_data_buf地址偏移賦值給pbuf
  31.        
  32.         if(DMA2_Stream1->CR&(1<<19))//DMA使用buf1,讀取buf0
  33.         {
  34.                 for(i=0;i<qr_image_width/2;i++)
  35.                 {
  36.                         pbuf[i]=dcmi_line_buf[0][i];
  37.                 }
  38.         }else                                                                                 //DMA使用buf0,讀取buf1
  39.         {
  40.                 for(i=0;i<qr_image_width/2;i++)
  41.                 {
  42.                         pbuf[i]=dcmi_line_buf[1][i];
  43.                 }
  44.         }
  45.         dcmi_curline++;
  46. }

  47. //imagewidth:<=240;大于240時,是240的整數倍
  48. //imagebuf:RGB圖像數據緩沖區(qū)
  49. void qr_decode(u16 imagewidth,u16 *imagebuf)
  50. {
  51.         static u8 bartype=0;
  52.         u8 *bmp;
  53.         u8 *result=NULL;
  54.         u16 Color;
  55.         u16 i,j;       
  56.         u16 qr_img_width=0;                                                //輸入識別器的圖像寬度,最大不超過240!
  57.         u8 qr_img_scale=0;                                                //壓縮比例因子
  58.        
  59.         if(imagewidth>240)
  60.         {
  61.                 if(imagewidth%240)return ;        //不是240的倍數,直接退出
  62.                 qr_img_width=240;
  63.                 qr_img_scale=imagewidth/qr_img_width;
  64.         }else
  65.         {
  66.                 qr_img_width=imagewidth;
  67.                 qr_img_scale=1;
  68.         }  
  69.         result=mymalloc(SRAMIN,1536);//申請識別結果存放內存
  70.         bmp=mymalloc(SRAMCCM,qr_img_width*qr_img_width);//CCM管理內存為60K,這里最大可申請240*240=56K
  71.         mymemset(bmp,0,qr_img_width*qr_img_width);
  72.         for(i=0;i<qr_img_width;i++)               
  73.         {
  74.                 for(j=0;j<qr_img_width;j++)                //將RGB565圖片轉成灰度
  75.                 {       
  76.                         Color=*(imagebuf+((i*imagewidth)+j)*qr_img_scale); //按照qr_img_scale壓縮成240*240
  77.                         *(bmp+i*qr_img_width+j)=(((Color&0xF800)>> 8)*76+((Color&0x7E0)>>3)*150+((Color&0x001F)<<3)*30)>>8;
  78.                 }               
  79.         }
  80.         atk_qr_decode(qr_img_width,qr_img_width,bmp,bartype,result);//識別灰度圖片(注意:單次耗時約0.2S)
  81.        
  82.         if(result[0]==0)//沒有識別出來
  83.         {
  84.                 bartype++;
  85.                 if(bartype>=5)bartype=0;
  86.         }
  87.         else if(result[0]!=0)//識別出來了,顯示結果
  88.         {       
  89.                 BEEP=1;//打開蜂鳴器
  90.                 delay_ms(100);
  91.                 BEEP=0;
  92.                 POINT_COLOR=BLUE;
  93.                 LCD_Fill(0,(lcddev.height+qr_image_width)/2+20,lcddev.width,lcddev.height,BLACK);
  94.                 Show_Str(0,(lcddev.height+qr_image_width)/2+20,lcddev.width,
  95.                                                                 (lcddev.height-qr_image_width)/2-20,(u8*)result,16,0                                                       
  96.                                                 );//LCD顯示識別結果
  97.                 printf("\r\nresult:\r\n%s\r\n",result);//串口打印識別結果                
  98.         }
  99.         myfree(SRAMCCM,bmp);                //釋放灰度圖bmp內存
  100.         myfree(SRAMIN,result);        //釋放識別結果       
  101. }

  102. int main(void)
  103. {                                                 
  104.         u8 key;                                                  
  105.         u8 i;       
  106.        
  107.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//設置系統(tǒng)中斷優(yōu)先級分組2
  108.         delay_init(168);                          //初始化延時函數
  109.         uart_init(115200);
  110.         LED_Init();
  111.         BEEP_Init();
  112.         KEY_Init();
  113.         LCD_Init();
  114.         FSMC_SRAM_Init();                          //初始化外部SRAM.
  115.         my_mem_init(SRAMIN);                //初始化內部內存池
  116.         my_mem_init(SRAMEX);                //初始化內部內存池  
  117.         my_mem_init(SRAMCCM);                //初始化CCM內存池
  118.         W25QXX_Init();                                  //初始化W25Q128
  119.         POINT_COLOR=RED;        //設置字體為紅色
  120.         LCD_Clear(BLACK);       
  121.         while(font_init())                         //檢查字庫
  122.         {            
  123.                 LCD_ShowString(60,50,lcddev.width,16,16,(u8*)"Font Error!");
  124.                 delay_ms(200);                                  
  125.                 LCD_Fill(60,50,lcddev.width,66,WHITE);//清除顯示
  126.                 delay_ms(200);
  127.         }
  128.         Show_Str_Mid(0,0,(u8*)"探索者F4開發(fā)板",16,lcddev.width);                                              
  129.         Show_Str_Mid(0,20,(u8*)"二維碼/條形碼識別實驗",16,lcddev.width);       
  130.         while(OV2640_Init())                //初始化OV2640
  131.         {
  132.                 LCD_ShowString(60,50,lcddev.width,16,16,(u8*)"OV2640 Error!");
  133.                 delay_ms(200);                                  
  134.                 LCD_Fill(60,50,lcddev.width,66,WHITE);//清除顯示
  135.                 delay_ms(200);
  136.         }       
  137.         OV2640_Special_Effects(0);//正常
  138.         OV2640_RGB565_Mode();                        //RGB565模式
  139.         My_DCMI_Init();                                                //DCMI配置
  140.        
  141.         qr_image_width=lcddev.width;
  142.         if(qr_image_width>480)qr_image_width=480;//這里qr_image_width設置為240的倍數
  143.         if(qr_image_width==320)qr_image_width=240;
  144.         Show_Str(0,(lcddev.height+qr_image_width)/2+4,240,16,(u8*)"識別結果:",16,1);
  145.        
  146.         dcmi_line_buf[0]=mymalloc(SRAMIN,qr_image_width*2);                                                //為行緩存接收申請內存       
  147.         dcmi_line_buf[1]=mymalloc(SRAMIN,qr_image_width*2);                                                //為行緩存接收申請內存
  148.         rgb_data_buf=mymalloc(SRAMEX,qr_image_width*qr_image_width*2);//為rgb幀緩存申請內存
  149.        
  150.         dcmi_rx_callback=qr_dcmi_rx_callback;//DMA數據接收中斷回調函數
  151.         DCMI_DMA_Init(
  152.                                                                         (u32)dcmi_line_buf[0],(u32)dcmi_line_buf[1],        \
  153.                                                                         qr_image_width/2,DMA_MemoryDataSize_HalfWord,DMA_MemoryInc_Enable                                                                                       
  154.                                                          );//DCMI DMA配置
  155.        
  156.         OV2640_OutSize_Set(qr_image_width,qr_image_width);
  157.         DCMI_Start();
  158.         printf("SRAM IN:%d\r\n",my_mem_perused(SRAMIN));
  159.         printf("SRAM EX:%d\r\n",my_mem_perused(SRAMEX));
  160.         printf("SRAM CCM:%d\r\n",my_mem_perused(SRAMCCM));
  161.        
  162.         atk_qr_init();//初始化識別庫,為算法申請內存
  163.        
  164.         printf("1SRAM IN:%d\r\n",my_mem_perused(SRAMIN));
  165.         printf("1SRAM EX:%d\r\n",my_mem_perused(SRAMEX));
  166.         printf("1SRAM CCM:%d\r\n",my_mem_perused(SRAMCCM));
  167.         while(1)
  168.         {       
  169.                 key=KEY_Scan(0);//不支持連按
  170.                 if(key)
  171.                 {
  172.                         if(key==KEY2_PRES)break;//按KEY2結束識別
  173.                 }
  174.                 if(readok==1)                        //采集到了一幀圖像
  175.                 {               
  176.                         readok=0;
  177.                         LCD_Color_Fill( (lcddev.width-qr_image_width)/2,(lcddev.height-qr_image_width)/2,        \
  178.                                                                                         (lcddev.width+qr_image_width)/2-1,(lcddev.height+qr_image_width)/2-1,
  179.                                                                                         rgb_data_buf );//顯示圖像
  180.                        
  181.                         qr_decode(qr_image_width,rgb_data_buf);//識別圖像
  182.                        
  183.                 }
  184.                 i++;
  185.                 if(i==20)//DS0閃爍.
  186.                 {
  187.                         i=0;
  188.                         LED0=!LED0;
  189.                 }
  190.         }
  191.         atk_qr_destroy();//釋放算法內存
  192.         printf("3SRAM IN:%d\r\n",my_mem_perused(SRAMIN));
  193.         printf("3SRAM EX:%d\r\n",my_mem_perused(SRAMEX));
  194.         printf("3SRAM CCM:%d\r\n",my_mem_perused(SRAMCCM));
  195.         while(1)
  196.         {
  197.                 LED0=!LED0;
  198.                 delay_ms(200);
  199.         }
  200. }
復制代碼

所有資料51hei提供下載:
(標準庫版,適合探索者F407開發(fā)板)擴展實驗SE01 ATK-QR二維碼、條形碼識別實驗.rar (1.41 MB, 下載次數: 166)


評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

回復

使用道具 舉報

ID:251731 發(fā)表于 2018-11-1 20:13 | 顯示全部樓層
你好,請問你用ov2640采集的圖像轉灰度后會不會有很多雜點,我現在正在做基于stm32的車牌識別系統(tǒng),用ov2640攝像頭采集圖像轉黑白后效果不是很好,我用的是將yuv取其y轉灰度的
回復

使用道具 舉報

ID:441242 發(fā)表于 2018-12-19 22:25 | 顯示全部樓層
這個會不會有讀假點的現象啊
回復

使用道具 舉報

ID:378903 發(fā)表于 2019-9-10 01:28 | 顯示全部樓層
2640的數據需要多大分辨率的呢
回復

使用道具 舉報

ID:217614 發(fā)表于 2019-9-14 13:41 | 顯示全部樓層
非常好謝謝
回復

使用道具 舉報

ID:632263 發(fā)表于 2019-10-29 20:40 | 顯示全部樓層
非常感謝
回復

使用道具 舉報

ID:427723 發(fā)表于 2020-6-16 10:10 | 顯示全部樓層
謝謝分享!
回復

使用道具 舉報

ID:909679 發(fā)表于 2021-4-21 15:08 | 顯示全部樓層
你好,請問一下ov2640是怎么采集的
回復

使用道具 舉報

ID:923412 發(fā)表于 2021-5-18 17:56 | 顯示全部樓層
請問,二維碼掃描后的數據怎么傳輸出去呀
回復

使用道具 舉報

ID:1061377 發(fā)表于 2023-1-18 17:00 | 顯示全部樓層
支持,非常好的資料,學習。還不能下載,努力中
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表