加入星計劃,您可以享受以下權益:

  • 創(chuàng)作內容快速變現
  • 行業(yè)影響力擴散
  • 作品版權保護
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入

【RT-Thread作品秀】基于ART-Pi的人臉識別系統(tǒng)

2020/12/19
1261
服務支持:
技術交流群

完成交易后在“購買成功”頁面掃碼入群,即可與技術大咖們分享疑惑和經驗、收獲成長和認同、領取優(yōu)惠和紅包等。

虛擬商品不可退

當前內容為數字版權作品,購買后不支持退換且無法轉移使用。

加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點資訊討論
放大
方塊圖(2)
相關方案
  • 方案介紹
  • 相關文件
  • 相關推薦
  • 電子產業(yè)圖譜
申請入駐 產業(yè)圖譜

作者:Signx

概述

當前的人臉識別攝像頭,價格昂貴,擬改造成stm32單片機版本的,節(jié)省成本

功能:

1.連接攝像頭OV2640,用fish指令開啟攝像頭

2.將攝像頭數據傳到電腦顯示圖片

3.將攝像頭數據傳到spi顯示屏顯示(未完成)

4.用人臉識別算法識別人臉開鎖(未完成)

5.可登錄到tencent Cloud云平臺,實現上云

開發(fā)環(huán)境:

硬件:Art-pi+OV2640

RT-Thread版本:4.0.2

開發(fā)工具及版本:rt-stuidio V2.0.0

RT-Thread使用情況概述:

硬件框架:art-pi官方開發(fā)板+OV2640(dma+DCMI)

軟件框架說明:

見思維導圖

軟件模塊說明:

見思維導圖

該系統(tǒng)的思維腦圖如下:

 

演示效果:

視頻:

實物圖如下:

實現的效果如圖:

連接電路如圖所示:

實現功能:

1.連接攝像頭OV2640,用fish指令開啟攝像頭

2.將攝像頭數據傳到電腦顯示圖片

3.將攝像頭數據傳到spi顯示屏顯示(未完成)

4.用人臉識別算法識別人臉開鎖(未完成)

5.可登錄到tencent Cloud云平臺,實現上云主要碰到的技術難點:

1.art-pi組建庫里有ov2640的軟件包,本以為直接能用的,結果發(fā)現有很多缺失

首先是io口的確實,沒有定義到足夠的io口,所以代碼里又加上了io口的定義以及初始化:

io口定義代碼:

typedef enum   
{
  BMP_QQVGA             =   0x00,        /* BMP Image QQVGA 160x120 Size */
  BMP_QVGA              =   0x01,      /* BMP Image VGA 800*480 Size */
  JPEG_160x120          =   0x02,        /* JPEG Image 160x120 Size */
  JPEG_176x144          =   0x03,        /* JPEG Image 176x144 Size */
  JPEG_320x240          =   0x04,        /* JPEG Image 320x240 Size */
  JPEG_352x288          =   0x05        /* JPEG Image 352x288 Size */
}ImageFormat_TypeDef;

/*攝像頭接口 */
//IIC SCCB
//#define CAMERA_I2C                          I2C1
//#define CAMERA_I2C_CLK_ENABLE()             __HAL_RCC_I2C1_CLK_ENABLE()
//
//#define CAMERA_I2C_SCL_PIN                  GPIO_PIN_8
//#define CAMERA_I2C_SCL_GPIO_PORT            GPIOB
//#define CAMERA_I2C_SCL_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()
//#define CAMERA_I2C_SCL_AF                   GPIO_AF4_I2C1
//
//#define CAMERA_I2C_SDA_PIN                  GPIO_PIN_9
//#define CAMERA_I2C_SDA_GPIO_PORT            GPIOB
//#define CAMERA_I2C_SDA_GPIO_CLK_ENABLE()    __HAL_RCC_GPIOB_CLK_ENABLE()
//#define CAMERA_I2C_SDA_AF                   GPIO_AF4_I2C1

//VSYNC
#define DCMI_VSYNC_GPIO_PORT                GPIOI
#define DCMI_VSYNC_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOI_CLK_ENABLE()
#define DCMI_VSYNC_GPIO_PIN                 GPIO_PIN_5
#define DCMI_VSYNC_AF                            GPIO_AF13_DCMI
// HSYNC
#define DCMI_HSYNC_GPIO_PORT                GPIOH
#define DCMI_HSYNC_GPIO_CLK_ENABLE()        __HAL_RCC_GPIOH_CLK_ENABLE()
#define DCMI_HSYNC_GPIO_PIN                 GPIO_PIN_8
#define DCMI_HSYNC_AF                            GPIO_AF13_DCMI
//PIXCLK
#define DCMI_PIXCLK_GPIO_PORT                GPIOA
#define DCMI_PIXCLK_GPIO_CLK_ENABLE()       __HAL_RCC_GPIOA_CLK_ENABLE()
#define DCMI_PIXCLK_GPIO_PIN                 GPIO_PIN_6
#define DCMI_PIXCLK_AF                          GPIO_AF13_DCMI
//PWDN
#define DCMI_PWDN_GPIO_PORT                  GPIOH
#define DCMI_PWDN_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOH_CLK_ENABLE()
#define DCMI_PWDN_GPIO_PIN                   GPIO_PIN_3

//RST
//#define DCMI_RST_GPIO_PORT                  GPIOH
//#define DCMI_RST_GPIO_CLK_ENABLE()          __HAL_RCC_GPIOH_CLK_ENABLE()
//#define DCMI_RST_GPIO_PIN                   GPIO_PIN_8

//數據信號線
#define DCMI_D0_GPIO_PORT                    GPIOC
#define DCMI_D0_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOC_CLK_ENABLE()
#define DCMI_D0_GPIO_PIN                     GPIO_PIN_6
#define DCMI_D0_AF                              GPIO_AF13_DCMI

#define DCMI_D1_GPIO_PORT                    GPIOC
#define DCMI_D1_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOC_CLK_ENABLE()
#define DCMI_D1_GPIO_PIN                     GPIO_PIN_7
#define DCMI_D1_AF                              GPIO_AF13_DCMI

#define DCMI_D2_GPIO_PORT                    GPIOG
#define DCMI_D2_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOG_CLK_ENABLE()
#define DCMI_D2_GPIO_PIN                     GPIO_PIN_10
#define DCMI_D2_AF                              GPIO_AF13_DCMI

#define DCMI_D3_GPIO_PORT                    GPIOG
#define DCMI_D3_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOG_CLK_ENABLE()
#define DCMI_D3_GPIO_PIN                     GPIO_PIN_11
#define DCMI_D3_AF                              GPIO_AF13_DCMI

#define DCMI_D4_GPIO_PORT                    GPIOH
#define DCMI_D4_GPIO_CLK_ENABLE()             __HAL_RCC_GPIOH_CLK_ENABLE()
#define DCMI_D4_GPIO_PIN                     GPIO_PIN_14
#define DCMI_D4_AF                              GPIO_AF13_DCMI

#define DCMI_D5_GPIO_PORT                    GPIOI
#define DCMI_D5_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOI_CLK_ENABLE()
#define DCMI_D5_GPIO_PIN                     GPIO_PIN_4
#define DCMI_D5_AF                              GPIO_AF13_DCMI

#define DCMI_D6_GPIO_PORT                    GPIOB
#define DCMI_D6_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOB_CLK_ENABLE()
#define DCMI_D6_GPIO_PIN                     GPIO_PIN_8
#define DCMI_D6_AF                              GPIO_AF13_DCMI

#define DCMI_D7_GPIO_PORT                    GPIOI
#define DCMI_D7_GPIO_CLK_ENABLE()         __HAL_RCC_GPIOI_CLK_ENABLE()
#define DCMI_D7_GPIO_PIN                     GPIO_PIN_7
#define DCMI_D7_AF                              GPIO_AF13_DCMI

io口初始化代碼:

void OV2640_HW_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    /***DCMI引腳配置***/
    /* 使能DCMI時鐘 */
    DCMI_PWDN_GPIO_CLK_ENABLE();
    DCMI_VSYNC_GPIO_CLK_ENABLE();
    DCMI_HSYNC_GPIO_CLK_ENABLE();
    DCMI_PIXCLK_GPIO_CLK_ENABLE();    
    DCMI_D0_GPIO_CLK_ENABLE();
    DCMI_D1_GPIO_CLK_ENABLE();
    DCMI_D2_GPIO_CLK_ENABLE();
    DCMI_D3_GPIO_CLK_ENABLE();    
    DCMI_D4_GPIO_CLK_ENABLE();
    DCMI_D5_GPIO_CLK_ENABLE();
    DCMI_D6_GPIO_CLK_ENABLE();
    DCMI_D7_GPIO_CLK_ENABLE();

    /*控制/同步信號線*/
    GPIO_InitStructure.Pin = DCMI_VSYNC_GPIO_PIN;
    GPIO_InitStructure.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStructure.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    GPIO_InitStructure.Pull = GPIO_PULLUP ;
    GPIO_InitStructure.Alternate = DCMI_VSYNC_AF;
    HAL_GPIO_Init(DCMI_VSYNC_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_HSYNC_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_VSYNC_AF;
    HAL_GPIO_Init(DCMI_HSYNC_GPIO_PORT, &GPIO_InitStructure);
 

    GPIO_InitStructure.Pin = DCMI_PIXCLK_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_PIXCLK_AF;
    HAL_GPIO_Init(DCMI_PIXCLK_GPIO_PORT, &GPIO_InitStructure);
    
    /*數據信號*/
    GPIO_InitStructure.Pin = DCMI_D0_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D0_AF;
    HAL_GPIO_Init(DCMI_D0_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_D1_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D1_AF;
    HAL_GPIO_Init(DCMI_D1_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_D2_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D2_AF;
    HAL_GPIO_Init(DCMI_D2_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_D3_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D3_AF;
    HAL_GPIO_Init(DCMI_D3_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_D4_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D4_AF;
    HAL_GPIO_Init(DCMI_D4_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_D5_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D5_AF;
    HAL_GPIO_Init(DCMI_D5_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_D6_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D6_AF;
    HAL_GPIO_Init(DCMI_D6_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_D7_GPIO_PIN;
    GPIO_InitStructure.Alternate = DCMI_D7_AF;
    HAL_GPIO_Init(DCMI_D7_GPIO_PORT, &GPIO_InitStructure);

    GPIO_InitStructure.Pin = DCMI_PWDN_GPIO_PIN;
    GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_PP;    
    HAL_GPIO_Init(DCMI_PWDN_GPIO_PORT, &GPIO_InitStructure);
    /*PWDN引腳,高電平關閉電源,低電平供電*/
    HAL_GPIO_WritePin(DCMI_PWDN_GPIO_PORT,DCMI_PWDN_GPIO_PIN,GPIO_PIN_RESET);
    
}

2.官方源代碼里沒有打開dcmi使能,導致編譯的時候會報錯,根據報錯的情況把對應的使能開開就行;

3.官方代碼導入之后并沒有開啟dcmi的中斷,又要打開中斷:

static rt_err_t rt_hw_dcmi_init(DCMI_HandleTypeDef *device)
{
    RT_ASSERT(device != RT_NULL);

    __HAL_RCC_DCMI_CLK_ENABLE();//signx

    device->Instance               = DCMI;
    device->Init.SynchroMode       = DCMI_SYNCHRO_HARDWARE;
    device->Init.PCKPolarity       = DCMI_PCKPOLARITY_RISING;
    device->Init.VSPolarity        = DCMI_VSPOLARITY_LOW;
    device->Init.HSPolarity        = DCMI_HSPOLARITY_LOW;
    device->Init.CaptureRate       = DCMI_CR_ALL_FRAME;
    device->Init.ExtendedDataMode  = DCMI_EXTEND_DATA_8B;

    device->Init.JPEGMode          = DCMI_JPEG_ENABLE;
    device->Init.ByteSelectMode    = DCMI_BSM_ALL;
    device->Init.ByteSelectStart   = DCMI_OEBS_ODD;
    device->Init.LineSelectMode    = DCMI_LSM_ALL;
    device->Init.LineSelectStart   = DCMI_OELS_ODD;

    if (HAL_DCMI_Init(device) != HAL_OK)
    {
        LOG_E("dcmi init error!");
        return RT_ERROR;
    }

    DCMI->IER = 0x0;

    __HAL_DCMI_ENABLE_IT(device, DCMI_IT_FRAME);
    __HAL_DCMI_ENABLE(device);

    HAL_NVIC_SetPriority(DCMI_IRQn, 0x00, 0x05);
    HAL_NVIC_EnableIRQ(DCMI_IRQn);;

    return RT_EOK;
}

4.官方的代碼沒有打開dma的中斷,又把dma的中斷打開:

static void rt_hw_dcmi_dma_init(void)
{
    __HAL_RCC_DMA2_CLK_ENABLE();

    hdma_dcmi.Instance                 = DMA2_Stream1;
    hdma_dcmi.Init.Request             = DMA_REQUEST_DCMI;
    hdma_dcmi.Init.Direction           = DMA_PERIPH_TO_MEMORY;
    hdma_dcmi.Init.PeriphInc           = DMA_PINC_DISABLE;
    hdma_dcmi.Init.MemInc              = DMA_MINC_ENABLE;
    hdma_dcmi.Init.PeriphDataAlignment = DMA_PDATAALIGN_WORD;
    hdma_dcmi.Init.MemDataAlignment    = DMA_MDATAALIGN_WORD;
    hdma_dcmi.Init.Mode                = DMA_CIRCULAR;
    hdma_dcmi.Init.Priority            = DMA_PRIORITY_HIGH;
    hdma_dcmi.Init.FIFOMode            = DMA_FIFOMODE_ENABLE;
    hdma_dcmi.Init.FIFOThreshold       = DMA_FIFO_THRESHOLD_FULL;
    hdma_dcmi.Init.MemBurst            = DMA_MBURST_SINGLE;
    hdma_dcmi.Init.PeriphBurst         = DMA_PBURST_SINGLE;

    HAL_DMA_Init(&hdma_dcmi);

    __HAL_LINKDMA(&rt_dcmi.DCMI_Handle, DMA_Handle, hdma_dcmi);

    HAL_NVIC_SetPriority(DMA2_Stream1_IRQn, 0x00, 0x00);
    HAL_NVIC_EnableIRQ(DMA2_Stream1_IRQn);;

}

然后就把攝像頭驅動起來了,這過程用去了3個周末的時間,吐槽一下官方庫,沒做好就沒必要放出來嘛,放出來個有問題的,找問題比從頭寫更費勁

比賽感悟:

1.學習到了如何用單片機控制OV2640乃至其他的攝像頭,學習到了DMA和HDCI的操作,這其中涉及到HDCI的引腳定義,需要查找手冊書

2.Rt-thread真的是一款非常好用的實時系統(tǒng),不光是功能強大,而且接口簡潔明了,類linux的明明風格更是讓開發(fā)者上手簡單,先進的面向對象設計思想讓我的代碼公里也見長進

3.感謝RT和電路城提供這么好的機會,能讓我有機會親自操作ART-PI,當然STM32H750和開發(fā)板的強大性能還擁有很大的開發(fā)潛力,

4.由于時間關系(年底事情多,好多項目等著結項),原定的實現人臉識別開鎖的功能做不了了,但是這么好的art-pi不能浪費了,所以接下來還會繼續(xù)開發(fā),直到完成所有的功能為止.學會了rtthread官方包的導入

  • 電路圖.png
    描述:電路圖
  • smartLock.zip
    描述:源代碼
  • 代碼地址.txt
  • 基于art-pi的人臉識別系統(tǒng).docx
    描述:文檔電子版

相關推薦

電子產業(yè)圖譜