加入星計(jì)劃,您可以享受以下權(quán)益:

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

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

2020/12/19
1282
服務(wù)支持:
技術(shù)交流群

完成交易后在“購(gòu)買成功”頁(yè)面掃碼入群,即可與技術(shù)大咖們分享疑惑和經(jīng)驗(yàn)、收獲成長(zhǎng)和認(rèn)同、領(lǐng)取優(yōu)惠和紅包等。

虛擬商品不可退

當(dāng)前內(nèi)容為數(shù)字版權(quán)作品,購(gòu)買后不支持退換且無(wú)法轉(zhuǎn)移使用。

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

作者:Signx

概述

當(dāng)前的人臉識(shí)別攝像頭,價(jià)格昂貴,擬改造成stm32單片機(jī)版本的,節(jié)省成本

功能:

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

2.將攝像頭數(shù)據(jù)傳到電腦顯示圖片

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

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

5.可登錄到tencent Cloud云平臺(tái),實(shí)現(xiàn)上云

開發(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)

軟件框架說(shuō)明:

見思維導(dǎo)圖

軟件模塊說(shuō)明:

見思維導(dǎo)圖

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

 

演示效果:

視頻:

實(shí)物圖如下:

實(shí)現(xiàn)的效果如圖:

連接電路如圖所示:

實(shí)現(xiàn)功能:

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

2.將攝像頭數(shù)據(jù)傳到電腦顯示圖片

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

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

5.可登錄到tencent Cloud云平臺(tái),實(shí)現(xiàn)上云主要碰到的技術(shù)難點(diǎn):

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

首先是io口的確實(shí),沒有定義到足夠的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

//數(shù)據(jù)信號(hào)線
#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時(shí)鐘 */
    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();

    /*控制/同步信號(hào)線*/
    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);
    
    /*數(shù)據(jù)信號(hào)*/
    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引腳,高電平關(guān)閉電源,低電平供電*/
    HAL_GPIO_WritePin(DCMI_PWDN_GPIO_PORT,DCMI_PWDN_GPIO_PIN,GPIO_PIN_RESET);
    
}

2.官方源代碼里沒有打開dcmi使能,導(dǎo)致編譯的時(shí)候會(huì)報(bào)錯(cuò),根據(jù)報(bào)錯(cuò)的情況把對(duì)應(yīng)的使能開開就行;

3.官方代碼導(dǎo)入之后并沒有開啟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);;

}

然后就把攝像頭驅(qū)動(dòng)起來(lái)了,這過(guò)程用去了3個(gè)周末的時(shí)間,吐槽一下官方庫(kù),沒做好就沒必要放出來(lái)嘛,放出來(lái)個(gè)有問題的,找問題比從頭寫更費(fèi)勁

比賽感悟:

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

2.Rt-thread真的是一款非常好用的實(shí)時(shí)系統(tǒng),不光是功能強(qiáng)大,而且接口簡(jiǎn)潔明了,類linux的明明風(fēng)格更是讓開發(fā)者上手簡(jiǎn)單,先進(jìn)的面向?qū)ο笤O(shè)計(jì)思想讓我的代碼公里也見長(zhǎng)進(jìn)

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

4.由于時(shí)間關(guān)系(年底事情多,好多項(xiàng)目等著結(jié)項(xiàng)),原定的實(shí)現(xiàn)人臉識(shí)別開鎖的功能做不了了,但是這么好的art-pi不能浪費(fèi)了,所以接下來(lái)還會(huì)繼續(xù)開發(fā),直到完成所有的功能為止.學(xué)會(huì)了rtthread官方包的導(dǎo)入

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

相關(guān)推薦

電子產(chǎn)業(yè)圖譜