最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會員登陸 & 注冊

嵌入式物聯(lián)網(wǎng)畢業(yè)設計選題智能圖像識別項目-stm32mp157 linux開發(fā)板

2023-03-08 14:10 作者:華清遠見研發(fā)中心  | 我要投稿

stm32mp157開發(fā)板FS-MP1A是華清遠見自主研發(fā)的一款高品質、高性價比的Linux+單片機二合一的嵌入式教學級開發(fā)板。開發(fā)板搭載ST的STM32MP157高性能微處理器,集成2個Cortex-A7核和1個Cortex-M4 核,A7核上可以跑Linux操作系統(tǒng),M4核上可以跑FreeRTOS、RT-Thread等實時操作系統(tǒng)。開發(fā)板搭配仿真器、顯示屏、攝像頭、資源擴展板等豐富的擴展模塊,可拓展物聯(lián)網(wǎng)、人工智能等相關技術學習,還可以拓展豐富的項目實戰(zhàn),非常貼合企業(yè)當下開發(fā)需求,是一款嵌入式Linux入門進階必備開發(fā)板!

可學習技術:嵌入式Linux應用/系統(tǒng)/驅動開發(fā)、ARM裸機開發(fā)、Qt界面編程、STM32單片機、FreeRTOS、人工智能機器視覺等。其中ARM Cortex-A7裸機開發(fā)課程是華清遠見獨有特色課程,可關注:https://www.bilibili.com/video/BV1Xe4y1i7vm/,持續(xù)更新中。

14個Linux+Qt綜合項目案例,6個MP1A物聯(lián)網(wǎng)拓展項目

關注公眾號“華清遠見在線實驗室”,回復“mp157項目”,即可領取項目配套文檔及源碼。?

Linux+Qt綜合項目案例:華清遠見stm32mp157開發(fā)板優(yōu)勢特色部分,包括音樂播放器、智慧家庭、智能工業(yè)電表、智能出行助手、智能貓眼、環(huán)境監(jiān)測、智能安防、智能語音識別等10余個項目案例,涉及家居、醫(yī)療、農(nóng)業(yè)多種應用方向,在案例中使用了多種物聯(lián)網(wǎng)和嵌入式技術,包括OT開發(fā)、linux應用開發(fā)、linux驅動開發(fā)、物聯(lián)網(wǎng)云端接入、MQTT協(xié)議、json字符串等知識點。

基于Linux+Qt的智能圖像識別項目

項目簡介:

提到圖像識別,一般都會想到人工智能。雖然現(xiàn)在人工智能還在發(fā)展階段,但是有些技術已經(jīng)成熟,比如圖像識別、語音識別等。本項目將調用百度 AI 開發(fā)平臺 API 進行圖像識別。

開發(fā)平臺:

華清遠見stm32mp157開發(fā)板豪華套餐(開發(fā)板+仿真器+五寸屏+攝像頭+資源擴展板+tf卡+讀卡器)

項目實戰(zhàn):

Qt 開發(fā)環(huán)境搭建

主機開發(fā)環(huán)境說明

1) 本文檔主要介紹 linux 環(huán)境下的 Qt 程序開發(fā);

2) 主機 Qt 版本為 5.14.1;

主機 Qt 環(huán)境搭建及使用

Qt Creator 安裝

將 qt-creator-opensource-linux-x86_64-4.10.1.run(Qt 實驗源碼\工具軟件) 復制到 ubuntu 主機中,可以采用共享文件夾的方式也可以使用 tfp方式將文 件存入家目錄下的 Downloads 目錄。我們需要在終端中賦予安裝程序可執(zhí)行的權限

我們可以使用圖形化的文件管理器來查看

雙擊“qt-creator-opensource-linux-x86_64-4.10.1.run”圖標運行安裝程序。出現(xiàn)如下界面:

等待程序驗證完成后點擊“Next”

這里我們需要登錄或者注冊一個賬號,如果我們之前已經(jīng)注冊過直接登錄就可以。如果沒有注冊過則需要新注冊有一個賬號后登錄。這里筆者已經(jīng)注冊過賬號,所以直接登錄。 登錄成功后出現(xiàn)如下界面,點擊 Next

這里選擇安裝路徑

可以直接默認,Next

這路選擇安裝的組件,直接默認即可

這里我們需要同意用戶協(xié)議

這個界面告訴我們安裝完成后需要占用的空間。點擊”Install”按鈕后開始安裝。

安裝完成后出現(xiàn)如下界面

點擊“Finish”按鈕后將彈出 Qt Creator 主界面

點擊“Cancel”按鈕后即可正常使用


Qt5.14.1 安裝

復制到 qt-opensource-linux-x64-5.14.1.run(Qt 實驗源碼\工具軟件)到 ubuntu 主機中,可以采用共享文件夾的方式也可以使用 tfp 方式將文件存入家目錄下的 Downloads 目錄。進入所在文件夾,先給執(zhí)行權限

輸入命令

chmod +x ./qt-opensource-linux-x64-5.14.1.run

安裝在命令行輸入

./qt-opensource-linux-x64-5.14.1.run

會有可視化引導安裝,一直 next 就行了

在選擇安裝組件的時候要是不知道選擇那些就全選了 大概有 4 個 G 左右

下載 gcc g++

sudo apt-get install gcc g++

下載 cmake

sudo apt-get install cmake

下載鏈接庫

sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev

Qt Creator 配置

1)配置 GCC

運行 QtCreator 后,依次點擊"Tool"->"Options",出現(xiàn)選項對話框,在左側點擊"Kits",右 邊選擇"Compilers"標簽。 檢查有沒有下圖標注的 C++和 C ,般按上面步驟執(zhí)行后都會有

點擊右側"Add"按鈕,彈出下拉列表后,選擇"GCC"的"C"

填寫信息如下,"Name"為"Auto-GCC","Compiler path"點擊旁邊的"Browse.."按鈕選擇編譯器的路徑,例子中的路徑是 “/usr/bin/gcc”

2)配置 G++

點擊右側"Add"按鈕,彈出下拉列表后,選擇"GCC"的"C++",下面的文本框填寫"Name" 為"Auto-G++","Compiler path"點擊旁邊的"Browse.."按鈕選擇編譯器的路徑,例子中的路徑是" /usr/bin/g++"。

填寫完成后,點擊"Apply"。

3)配置 qmake

選擇"Qt Versions"標簽,如果有下面紅框中的文本,可以跳過下面步驟

如果沒有,在右側點擊"Add..."

會彈出 qmake 路徑選擇對話框,這里以"

/home/linux/Qt5.14.1/5.14.1/gcc_64/bin/qmake"為例子。 選擇”qmake”文件后,點擊"Open"按鈕

"Version name"改為" Qt %{Qt:Version} GCC"。然后點擊"Apply"按鈕。

4)配置 Kits

點擊左側"Kits",右側選擇"Kits"標簽。檢查有沒有下圖紅框選中的文本,如果有可以跳過下面步驟

然后沒有,點擊 Add:

在彈出的對話框中"Name"為"Desktop","Device Type"選擇"Desktop"選項, "Sysroot"選擇目標設備的系統(tǒng)目錄,"Compiler"選擇之前配置的名稱"Auto-GCC"和"Auto-G++","Qt version"選擇之前配 置的名稱"Qt 5.14.1GCC",其它默認即可,最后點擊"Apply"和"OK"按鈕。

Qt Creator 新建工程

注意:工程路徑最好不要包含中文、特殊字符、空格等。

我們可以新建一個“qt”文件夾,該文件夾用作我們以后存放源代碼。

打開 Qt Creator,在歡迎頁面點擊 “New”按鈕,來新建一個工程。

在出現(xiàn)的新建項目窗口中,我們選則“Application”->“Qt Widgets Application”,然后點擊右下方“Choose…”按鈕,來創(chuàng)建一個桌面 Qt 應用。

我們在這里設置項目介紹和源碼位置,我們這里創(chuàng)建一個名為“HelloWorld”的示例項目,設置完成之后點擊 next

直接點擊 next

隨后進行細節(jié)設置,主要設置要創(chuàng)建的源碼文件的基本類信息,包括類名等。這里我們可以根據(jù)自己的項目特點進行設置。需要說明的一點就是基類的選擇,這里基類有 QMainWindow、QWidget、QDialog 三種,它們的不同之處如下:

QMainWindow 類提供一個帶有菜單條,工具條和一個狀態(tài)條的主應用程序窗口。主窗口通常提供一個大的中央窗口部件,以及周圍菜單,工具條,和一個狀態(tài)欄。QMainWindow 窗口經(jīng)常被繼承,使得封裝中央部件,菜單,工具條,狀態(tài)欄等都變得很容易,當用戶點擊它的時候,相應的槽就會被調用;

QWidget 類是所有用戶界面對象的基類,窗口部件是用戶界面的一個基本單元,它從窗口系統(tǒng)接收鼠標,鍵盤和其他消息,并在屏幕上繪制自己。一個窗口部件可以被他的父窗口或者是其他窗口擋住一部分;

QDialog 類是對話框窗口的基類,對話框窗口主要用于短期任務和用戶進行短期通訊的頂級窗口,QDialog 可以是模態(tài)對話框或者是非模態(tài)對話框。QDialog 支持擴展并帶有返回值,他們可以帶有默認值;我們在這里選擇 QDialog 類即可,點擊 next 完成類信息設置。

直接點擊 next 按鈕即可。

然后進行工具選擇,該頁面可以選擇我們創(chuàng)建的工程可以使用的工具,選擇想要使用的編譯器模塊,例如下圖 。點擊 next

最后我們設置匯總信息,如果不需要版本控制等功能,直接點擊完成finish 即可。

隨后我們就進入到了主界面,這時候 Qt 已經(jīng)幫我們做好了一些準備工作,包括創(chuàng)建了一些文件,寫好了一些前置代碼等等。

我們可以點擊左邊 protect 欄,來查看我們的編譯選項。

我們可以在左下角選擇編譯 Debug 版或者 Release 版,即調試版或發(fā)行版。

左下角綠色剪頭是編譯并運行,錘子是僅編譯,我們可以直接點擊綠色小箭頭將我們導入的工程編譯并運行起來。

點擊運行按鈕后,我們可以看到 HelloWorld 窗口運行起來了。

導入工程

我們可以將已存在的 Qt 程序項目直接打開,這里以上一章節(jié)的HelloWorld 程序為例。首先我們確定源碼存在的位置,如 HelloWorld 程序源碼在 /home/linux/qt/helloworld 路徑下

點擊歡迎頁面的“Open” 按鈕可以打開已有的工程

找到我們剛才解壓好的源碼,選擇“helloworld.pro”文件并點擊打開

接下來我們就可以進入到代碼編輯界面了。

左上角是項目欄,點擊項目名稱左邊的小箭頭可以展開項目目錄

我們可以點擊左邊項目欄,來查看我們的編譯選項。需注意的是構建設置中的路徑應與工程路徑處于同級目錄下。

我們可以在左下角選擇編譯 Debug 版或者 Release 版,即調試版或發(fā)行版。

左下角綠色剪頭是編譯并運行,錘子是僅編譯,我們可以直接點擊綠色小箭頭將我們導入的工程編譯并運行起來

點擊運行按鈕后,我們可以看到 HelloWorld 窗口運行起來了。

Qt Creator 文件說明

通過上面兩個章節(jié),我們學習到了 Qt 程序的新建與導入的方法,也知道了Qt 會幫我們做一些基礎工作,比如幫我們建立了一些文件,那么這些文件都是干什么用的呢?我們以 HelloWorld 程序來說明一下。

以“.pro”為后綴名的文件,為 Qt 的項目管理文件,存儲項目設置的文件;

“Qt += core gui”表示項目中加入 core gui 模塊。core gui 是 Qt 用于GUI 設計的類庫模塊,如果創(chuàng)建的是控制臺(console)應用程序,就不需要添加 core gui。

Qt 類庫以模塊的形式組織各種功能的類,根據(jù)項目涉及的功能需求,在項目中添加適當?shù)念悗炷K支持。例如,如果項目中使用到了涉及數(shù)據(jù)庫操作的類就需要用到 sql(數(shù)據(jù)庫)模塊,在 pro 文件中需要在后面加上 sql:

1 Qt += core gui sql

“greaterThan(QT_MAJOR_VERSION, 4): QT += widgets”,這是個條件執(zhí)行語句,表示當 Qt 主版本大于 4 時,才加入 widgets 模塊。

“TARGET = HelloWorld”表示生成的目標可執(zhí)行文件的名稱,即編譯后生成的可執(zhí)行文件是 HelloWorld.exe。

“TEMPLATE = app”表示項目使用的模板是 app,是一般的應用程序。

后面的 SOURCES、HEADERS、FORMS 記錄了項目中包含的源程序文件、頭文件和窗體文件(.ui 文件)的名稱。這些文件列表是 Qt Creator 自動添加到項目管理文件里面的,用戶不需要手動修改。當添加一個文件到項目,或從項目里刪除一個文件時,項目管理文件里的條目會自動修改。

文件夾“Header”中,存放的是所設計的窗體類的頭文件;

文件夾“Sources”中,存放著源碼文件。main.cpp 是實現(xiàn) main()函數(shù)的程序文件,HelloWorld.cpp 是 widget.h 里定義類的實現(xiàn)文件。C++中,任何窗體或界面組件都是用類封裝的,一個類一般有一個頭文件(.h 文件)和一個源程序文件(.cpp 文件);

文件夾“Forms”中,存放著界面設計文件,“.ui”文件是一個 XML 格式存儲的窗體上的元件及其布局的文件,雙擊項目文件目錄樹中的文件 ui,會打開一個集成在 Qt Creator 中的 Qt Designer 對窗體進行可視化設計;

UI 設計器有以下一些功能區(qū)域:

組件面板:窗口左側是界面設計組件面板,分為多個組,如 Layouts、Buttons、Display Widgets 等,界面設計的常見組件都可以在組件面板里找到。

中間主要區(qū)域是待設計的窗體。如果要將某個組件放置到窗體上時,從組件面板上拖放一個組件到窗體上即可。

Signals 和 Slots 編輯器與 Action 編輯器是位于待設計窗體下方的兩個編輯器。Signals 和 Slots 編輯器用于可視化地進行信號與槽的關聯(lián),Action 編輯器用于可視化設計 Action。

布局和界面設計工具欄:窗口上方的一個工具欄,工具欄上的按鈕主要實現(xiàn)布局和界面設計。

對象瀏覽器(Object Inspector):窗口右上方是 Object Inspector,用樹狀視圖顯示窗體上各組件之間的布局包含關系,視圖有兩列,顯示每個組件的對象名稱(ObjectName)和類名稱。

屬性編輯器(Property Editor):窗口右下方是屬性編輯器,是界面設計時最常用到的編輯器。屬性編輯器顯示某個選中的組件或窗體的各種屬性及其取值,可以在屬性編輯器里修改這些屬性的值。屬性編輯器的內容分為兩列,左側為屬性的名稱,右側為屬性的值。屬性又分為多個組,實際上表示了類的繼承關系,位于下方的類屬性組繼承自位于上方的類屬性組;

如果我們需要新建資源文件、源碼文件等,可以在項目文件夾出點擊鼠標右鍵,選擇 Add New;如果我們有新的文件需要添加,可以在項目文件夾出點擊鼠標右鍵,選擇 Add Existing Files。

幫助文檔

Qt 的幫助文檔是伴隨我們學習 Qt 開發(fā)的好伙伴。在 Qt 開發(fā)過程中,我們會面臨圖形接口使用的問題,它不像 C 語言那樣就那么幾個函數(shù)接口,圖形接口的接口數(shù)量可以用海量來形容,常用的我們可能能記住,其它的就沒有必要去記了,用到什么就去幫助文檔查看用法是比較方便的。我們可以按 F1 按鍵,或通過上方導航欄的“help->contects”來進入幫助文檔。

上方的前進后退按鈕方便我們查看文檔,如返回到上一步,返回到下一步。

我們可以通過幫助文檔來查看以下幾個部分:類使用的相關介紹;

查看相關類的使用介紹,我們可以先進入到幫助文檔,然后在左上角選擇“Search”。筆者這里以 QWidget 類為例,輸入我們想要查找的類的名字,然后雙擊查找結果來查看說明。

也可以先將鼠標移動到想要查詢的類的位置,如圖所示,將鼠標移動至“QWidget”處,然后按“F1”鍵,即可跳轉到相應的幫助文檔。

我們可以通過再按一次“F1”鍵來全窗口查看幫助文檔,按“Esc”鍵可以退出。

部分常用的成員元素包括以下幾項:

公有成員函數(shù):操作部件屬性的相關函數(shù);

公有槽函數(shù):Qt 類中已經(jīng)定義好的槽函數(shù),直接可與信號相連接;

信號:軟中斷,如按下按鈕觸發(fā) pressed() 信號等;

保護成員函數(shù):通常事件所對應的虛函數(shù)放在此處;

事件:常用事件,如操作鼠標觸發(fā)的鼠標事件;

滾動鼠標滾輪,向下即可看到“Qwdget Class”類的相關說明了。

部分常用的成員元素包括以下幾項:

公有成員函數(shù):操作部件屬性的相關函數(shù);

公有槽函數(shù):Qt 類中已經(jīng)定義好的槽函數(shù),直接可與信號相連接;

信號:軟中斷,如按下按鈕觸發(fā) pressed() 信號等;

保護成員函數(shù):通常事件所對應的虛函數(shù)放在此處;

事件:常用事件,如操作鼠標觸發(fā)的鼠標事件;

滾動鼠標滾輪,向下即可看到“Qwdget Class”類的相關說明了。

1) 查看所用的部件的相應成員函數(shù)。

我們可以查找到該類所用部件的相應成員函數(shù)的使用方法、功能、參數(shù)、返回值等等,我們以“按鈕”控件,即“QPushButton Class”類為例,我們通過索引搜索的方式,來找到這個類

我們可以通過點擊“Public Functions” 來查看“QPushButton”這個類中的成員函數(shù)。

這里以“QPushButton(const QString &text, QWidget *parent =Q_NULLPTR)”為例,我們點擊函數(shù)名字可以進入到函數(shù)詳情中。我們可以看到相應的描述為:以“text”為顯示內容,以“parent”為父對象,構造一個push 按鈕?!皌ext”“parent”為函數(shù)參數(shù),由于是構造函數(shù),所以此函數(shù)沒有返回值。

還有一些函數(shù)是繼承自其它類的,例如“Public Functions”中有 21 個繼承自“QAbstractButton”類的函數(shù),我們點擊“QAbstractButton”即可查看。擊“QAbstractButton”即可查看

同樣我們可以點擊相應的函數(shù)進入查看詳情。如查看“voidsetText(const QString &text)”。

2) 查看所用的部件的信號。

我們這里還是以“PushButton”為例,我們點擊“Public Slots”。

可以看到“PushButton”本身有一個“void showMenu()”的信號,并且有很多繼承自其他類的信號。

一般來說我們用的“PushButton”的信號,最多的是用到其繼承自基類“QAbstractButton”中的幾個信號,分別是點擊(按下后抬起)、按壓(單按下)、釋放(單抬起)等

我們可以點擊相應信號查看詳情

3) 查看所用的部件的事件(所對應的虛函數(shù)如何編寫)。部件常用事件主要在 “QWidget”中聲明,選擇“Events”即可查看相關說明。

每個事件都對應著事件函數(shù)。

點擊事件函數(shù)可查看詳情

實驗步驟

UI 界面設計

由于我們配置的七寸屏幕是 1024*768 分辨率的,所以我們的 MainWindow主界面的尺寸設置為 1024*768。共使用如下幾個控件,使用 QTextEdit 控件textEdit 來顯示語音識別后返回的最佳匹配語音。使用 QPushButton 控件pushButton_video 點擊錄音和釋放識別,使用 pushButton_clear 來清空 QtextEdit的內容,使用 textEdit_2 來顯示傳感器的反饋。

邏輯實現(xiàn)

獲取圖像

在 pro 文件添加

QT += network

QT += multimedia

使用 V4L2 進行圖像采集,新建v4l2api.h 和 v4l2api.cpp。

采集/dev/video0 攝像頭設備的圖像,但是采集到的是 yuyv 格式的圖像,需要進行轉換成 rgb 格式才能顯示在 lcd 屏幕上面。

主要功能代碼如下:

void V4l2Api::run()

{

?char buffer[WIDTH*HEIGHT*3];

?char rgbbuffer[WIDTH*HEIGHT*3];

?int len;

?while(1)

?{

?grapImage(buffer, &len);

?yuyv_to_rgb888((unsigned char *)buffer, (unsigned char *)rgbbuffer);

?//把 RGB 數(shù)據(jù)轉為 QImage

?QImage image((uchar*)rgbbuffer, WIDTH, HEIGHT,

QImage::Format_RGB888);

?emit sendImage(image);

?msleep(5);

?}

}

Yuyv 轉 RGB 函數(shù)實現(xiàn)

bool V4l2Api::yuyv_to_rgb888(unsigned char *yuyvdata, unsigned char *rgbdata,

int picw, int pich)

{

?int i, j;

?unsigned char y1,y2,u,v;

?int r1,g1,b1,r2,g2,b2;

?//確保所轉的數(shù)據(jù)或要保存的地址有效

?if(yuyvdata == NULL || rgbdata == NULL)

{

?return false;

?}

?int tmpw = picw/2;

?for(i=0; i<pich; i++)

?{

?for(j=0; j<tmpw; j++)// 640/2 == 320

?{

?//yuv422

?//R = 1.164*(Y-16) + 1.159*(V-128);

?//G = 1.164*(Y-16) - 0.380*(U-128)+ 0.813*(V-128);

?//B = 1.164*(Y-16) + 2.018*(U-128));

?//下面的四個像素為:[Y0 U0 V0] [Y1 U1 V1] -------------[Y2 U2

V2] [Y3 U3 V3]

?//存放的碼流為: Y0 U0 Y1 V1------------------------Y2 U2 Y3

V3

?//映射出像素點為: [Y0 U0 V1] [Y1 U0 V1]--------------[Y2 U2

V3] [Y3 U2 V3]

?//獲取每個像素 yuyv 數(shù)據(jù) YuYv

?y1 = *(yuyvdata + (i*tmpw+j)*4); //yuv 像素的

Y

?u = *(yuyvdata + (i*tmpw+j)*4+1); //yuv 像素

的 U

?y2 = *(yuyvdata + (i*tmpw+j)*4+2);

?v = *(yuyvdata + (i*tmpw+j)*4+3);

?//把 yuyv 數(shù)據(jù)轉換為 rgb 數(shù)據(jù)

r1 = 1.164*(y1-16) + 2.018*(u-128);

?g1= 1.164*(y1-16) - 0.380*(v-128)- 0.394*(v-128);

?b1 = 1.164*(y1-16) + 1.159*(v-128);

?r2 = 1.164*(y2-16) + 2.018*(u-128);

?g2= 1.164*(y2-16) - 0.380*(v-128)- 0.394*(v-128);

?b2 = 1.164*(y2-16) + 1.159*(v-128);

?if(r1 > 255) r1=255;

?else if(r1 < 0) r1 = 0;

?if(g1 > 255) g1=255;

?else if(g1 < 0) g1 = 0;

?if(b1 > 255) b1=255;

?else if(b1 < 0) b1 = 0;

?if(r2 > 255) r2=255;

?else if(r2 < 0) r2 = 0;

?if(g2 > 255) g2=255;

?else if(g2 < 0) g2 = 0;

?if(b2 > 255) b2=255;

?else if(b2 < 0) b2 = 0;

?rgbdata[((i+1)*tmpw+j)*6] = (unsigned char)b1;

?rgbdata[((i+1)*tmpw+j)*6 + 1] = (unsigned char)g1;

?rgbdata[((i+1)*tmpw+j)*6 + 2] = (unsigned char)r1;

?rgbdata[((i+1)*tmpw+j)*6 + 3] = (unsigned char)b2;

?rgbdata[((i+1)*tmpw+j)*6 + 4] = (unsigned char)g2;

rgbdata[((i+1)*tmpw+j)*6 + 5] = (unsigned char)r2;

?}

?}

?memcpy(yuyvdata,rgbdata,HEIGHT*WIDTH*3);

?return true;

}

獲取、關閉獲取圖像、拍照按鈕槽函數(shù)

右鍵采集圖像按鈕,點擊轉到槽。其他兩個按鈕同樣。

函數(shù)實現(xiàn)如下:

申請百度 AI 開發(fā)平臺圖像識別應用

圖像識別是利用百度的 API 在線識別。所以需要申請項目 ID。

首先登陸 http://ai.baidu.com/tech/imagerecognition/general,進入到通用圖像分析的界面。選擇立即使用

登陸自己的百度賬號,可用手機號申請。

點擊創(chuàng)建應用:

依次輸入應用名稱,選擇類型,接口默認選擇圖像識別,添加應用描述,點擊立即創(chuàng)建。

至此,應用創(chuàng)建完畢,現(xiàn)在就可以使用該應用了。

點擊返回應用列表,我們記住其中的 API Key 和 Secret Key,下面會用到。

請求類實現(xiàn)

我們采集的圖像需要通過 HTTPS 協(xié)議上傳到百度 AI 開發(fā)平臺進行識別,之后 AI 平臺會返回給我們識別的結果。

http 類只需要封裝一個方法

static bool post_sync(QString url,QMap<QString,QString>header,QByteArray requestData,QByteArray &replyData);

使用這個方法去 URL 發(fā)送請求會收到 URL 的返回值。

http.h

#ifndef HTTP_H

#define HTTP_H

#include <QObject>

#include <QMap>

#include <QNetworkAccessManager>

#include <QNetworkRequest>

#include <QNetworkReply>

#include <QEventLoop>

#include <QDebug>

class Http : public QObject

{

?Q_OBJECT

public:

?explicit Http(QObject *parent = nullptr);

?static bool post_sync(QString

url,QMap<QString,QString>header,QByteArray requestData,QByteArray

&replyData);

signals:

};

#endif // HTTP_H

http.cpp

這個方法的第一個參數(shù)是 post 方法發(fā)送請求的 URL,第二個參數(shù)是請求的方法頭,第三個參數(shù)是請求的數(shù)據(jù),第四個參數(shù)是返回的數(shù)據(jù)。這里要說的是必須要設置 openssl 簽名配置,否則在 ARM 上會報錯

bool Http::post_sync(QString url,QMap<QString,QString>header,QByteArray

requestData,QByteArray &replyData)

{

// 發(fā)送請求的對象

?QNetworkAccessManager manager;

// 請求 對象

?QNetworkRequest request;

?request.setUrl(url);

?QMapIterator<QString,QString> it(header);

?while (it.hasNext()) {

?it.next();

?request.setRawHeader(it.key().toLatin1() ,it.value().toLatin1());

?}

//設置 openssl 簽名配置,否則在 ARM 上會報錯

?QSslConfiguration conf = request.sslConfiguration();

?conf.setPeerVerifyMode(QSslSocket::VerifyNone);

#if (QT_VERSION > QT_VERSION_CHECK(5,0,0))

?conf.setProtocol(QSsl::TlsV1_0);

#else

?conf.setProtocol(QSsl::TlsV1);

#endif

?request.setSslConfiguration(conf);

?QNetworkReply *reply = manager.post(request,requestData);

QEventLoop l;

?//一旦服務器返回,reply 會發(fā)出信號

?connect(reply,&QNetworkReply::finished,&l,&QEventLoop::quit);

?l.exec();

?if(reply != nullptr && reply->error() == QNetworkReply::NoError)

?{

?replyData = reply->readAll();

?return true;

?}

?else

?{

?qDebug()<<"request error!";

?return false;

?}

}

采集到的圖像處理

查看百度 ai 開發(fā)平臺接口文檔,我們看到 http 請求的 image 需要進行處理,圖片需要 base64 編碼、去掉編碼頭后再進行 urlencode。

新建 ImageProcess 類實現(xiàn)以下函數(shù),返回 QbyteArray 類型的圖像。

QByteArray IamgeProcess::imageBaseTo64ToUrlEncode(QString imagePth)

{

?QImage image(imagePth);

?QByteArray byte;

?//用 QByteArray 構造 QBuffer

?QBuffer buf(&byte);

?buf.open(QIODevice::WriteOnly);

?image.save(&buf,"JPG");

?//對圖片做 base64 編碼(不包含編碼頭)

?QByteArray byteBase64 = byte.toBase64();

?QTextCodec *codec = QTextCodec::codecForName("UTF-8");

?QByteArray imgData =

codec->fromUnicode(byteBase64).toPercentEncoding();

?return imgData;

}

?MainWindow 類發(fā)送請求

需要向百度 AI 平臺發(fā)送兩個請求,第一個請求是獲取 access_token;第二個請求是向 URL 發(fā)送圖片資源。

1.獲取 access_token

我們復制示例中的 url 地址如下。

https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&

client_id=Va5yQRHlA4Fq5eR3LT0vuXV4&client_secret=0rDSjzQ20XUj5itV6WRtzn

PQSzr5pVw2&

把其中的 client_id 和 client_secret 后面的參數(shù)刪掉,通過二維碼掃描的方

式加入 URL 如下:

https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credenti

als&client_id=%1&client_secret=%2&

我們通過二維碼生成器把我們的 API Key 和 Secret Key 寫成 josn 的形式生成二維碼,如以下形式:

{

“client_id”:“xxxxxx”,

“client_secret”:“xxxxxx”

}

我們在下面開始實現(xiàn)通過識別二維碼填充 client_id 和 client_secret 到上述的URL 中。

右鍵轉到槽,選擇 clicked()。

在這里識別二維碼需要使用到 QZXing 庫進行識別。我們提 QZXing 庫的源代碼在實驗源碼下的 qzxing.tar.xz。

解壓后,將解壓后的文件放到 QT 源碼路徑下

在 pro 文件下添加 include(qzxing/src/QZXing.pri)保存后,在 mainwindow.h 加入

#include< QZXing >頭文件,這樣就可以使用 QZXing 庫了。下面開始編寫識別二維碼填充 URL。

在 mainwindow.cpp 添加下面 QString 定義。

void MainWindow::on_pushButton_ewm_clicked()

{

?if(picTorF == false)

?{

?QMessageBox::warning(this, "警告", "請先拍照保存圖片");

?return ;

?}

?QZXing zxing;

?QString imagePth ="./pic.jpg";

?QImage image(imagePth);

?QByteArray byte = zxing.decodeImage(image).toUtf8();// 該 方 法 返 回

QString 串,標識圖片二維碼的內容

?QJsonObject obj = QJsonDocument::fromJson(byte).object();

?client_id = obj.value("client_id").toString();

?secret_id = obj.value("secret_id").toString();

?qDebug()<< "client_id:"<<client_id;

?qDebug()<< "secret_id:"<<secret_id;

?if(client_id =="")

?{

?QMessageBox::warning(this, "警告", "請重新填充秘鑰");

?on_openBt_clicked();

?return ;

?}

?else

?{

?QMessageBox::information(this, "提示", "填充秘鑰成功");

?ui->pushButton_ewm->setText("填充完成");

ui->pushButton_ewm->setEnabled(false);

?Keypadding = true;

?picTorF = false;

?on_comboBox_activated(0);

?on_openBt_clicked();

?}

}

2.???? 上傳圖片資源

我們查看百度 ai 平臺文檔,可以看到每種物體識別都有不同的 URL

所以我們可以通過改變下拉框來改變圖片請求的 URL 從而實現(xiàn)不同物體的識別。

void MainWindow::on_comboBox_activated(int index)

{

?Q_UNUSED(index)

?QByteArray img = IamgeProcess::imageBaseTo64ToUrlEncode("pic.jpg");

//image=xxxxxxx

?QByteArray imgData = "image=" + img; //body

?//獲取 access_token

?QByteArray replyData; //保存回復信息

?QString url = QString(baiduTokenUrl).arg(client_id).arg(secret_id);

?QMap<QString, QString> header; //封裝頭部信息

?header.insert(QString("Content-Type"), QString("application/x-www-formurlencoded"));

bool result = Http::post_sync(url, header, imgData, replyData);

?if (result)

?{

?QJsonObject obj = QJsonDocument::fromJson(replyData).object();

?accessToken = obj.value("access_token").toString();

?}

?switch (ui->comboBox->currentIndex())

?{

?case 0:

?imgUrl = baiduImageUrl.arg("v1").arg("animal").arg(accessToken);

?break;

?case 1:

?imgUrl = baiduImageUrl.arg("v2").arg("logo").arg(accessToken);

?break;

?case 2:

?imgUrl =

baiduImageUrl.arg("v1").arg("classify/ingredient").arg(accessToken);

?break;

?case 3:

?imgUrl = baiduImageUrl.arg("v1").arg("plant").arg(accessToken);

?break;

?}

}

?{

?for(int i=0;i<3;i++)

?{

?QJsonValue first = val.toArray().at(i);

if (first.isObject())

?{

?QString name = first.toObject().value("name").toString();

?QString score = first.toObject().value("score").toString();


ui->textEdit->append(QString(QString::number(i+1)).append(". 名 稱 :

").append(name).append("\n 置信度: ").append(score));

?}

?}

// 顯示最終結果

?ui->label_3->setText("經(jīng)圖像分析最可能為");

ui->label_4->setText(val.toArray().at(0).toObject().value("name").toString());

?}

?else{

?ui->textEdit->append("識別不到,請重新拍照識別");

?}

?}

?else{

?ui->textEdit->append("識別不到,請重新拍照識別");

?}

}

右鍵圖像識別,轉到槽

void MainWindow::on_recognitionBt_clicked()

{

?ui->textEdit->clear();

?ui->label_3->clear();

?ui->label_4->clear();

?if(Keypadding ==false)

?{

?QMessageBox::warning(this, "警告", "請先填充秘鑰");

?return ;

?}

?if(picTorF == false)

?{

?QMessageBox::warning(this, "警告", "請先拍照保存圖片");

?return ;

?}

?QByteArray img = IamgeProcess::imageBaseTo64ToUrlEncode("pic.jpg");

//image=xxxxxxx

?QByteArray imgData = "image=" + img; //body

?//獲取 access_token

?QByteArray replyData; //保存回復信息

?QString url = QString(baiduTokenUrl).arg(client_id).arg(secret_id);

?QMap<QString, QString> header; //封裝頭部信息

?header.insert(QString("Content-Type"), QString("application/x-www-formurlencoded"));

?bool result = Http::post_sync(imgUrl, header, imgData, replyData);

?if (result)

?{

?QJsonObject obj = QJsonDocument::fromJson(replyData).object();

?QJsonValue val = obj.value("result");

?qDebug()<< obj;

?if (val.isArray())

實驗源碼

源碼路徑【11_智能圖像識別\實驗源碼\05-AiCamera】

注意事項

1.在開發(fā)板運行時,需要導入中文字庫,否則會因為識別不了中文。

將【11_智能圖像識別\工具軟件\wqy-zenhei-0.9.47-nightlybuild.tar.gz 或 wqy-zenhei-0.8.38-1.tar.gz】復制到 ubuntu 下。并使用 scp 命令將文件拷貝到開發(fā)板的 usr/share/fonts 目錄下,使用 tar 命令解壓后即可。?

linux@ubuntu:~$ scp wqy-zenhei-0.8.38-1.tar.gz

root@192.168.10.128:/usr/share/fonts/

2.如果使用 mipi 五寸屏運行此項目,需要進行屏幕旋轉以適應屏幕,具體步驟如下:

在/etc/profile.d/qt-eglfs.sh 添加環(huán)境變量如下:

下面變量的 event0 設備需要填實際的觸摸屏設備

這里即填 event0

export QT_QPA_EGLFS_ROTATION=90

export QT_QPA_EGLFS_NO_LIBINPUT=1

export

QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event0:rotate=90

嵌入式物聯(lián)網(wǎng)畢業(yè)設計選題智能圖像識別項目-stm32mp157 linux開發(fā)板的評論 (共 條)

分享到微博請遵守國家法律
武威市| 炉霍县| 武鸣县| 灵寿县| 区。| 深水埗区| 安义县| 海南省| 辽阳县| 饶阳县| 双辽市| 娱乐| 文水县| 石泉县| 金平| 莱州市| 德阳市| 天峨县| 万载县| 吉隆县| 正蓝旗| 广饶县| 滕州市| 晋城| 聂荣县| 凌源市| 河北区| 芦山县| 孟村| 开封市| 天峻县| 阳城县| 郁南县| 宁都县| 织金县| 济南市| 濮阳县| 株洲市| 马龙县| 正镶白旗| 安康市|