雲計算

電子相冊搭建(人臉、表情識別)

本章內容出自《5天入門視覺AI》電子書,點擊下載完整版

電子相冊搭建(人臉、表情識別)

一、項目簡介

我們首先來看一下項目運行出來的效果:訪問程序運營端口:127.0.0.1.8080/index.html

image.png

所以我們看到是三塊空白,然後這邊的話是我們可以通過點擊上傳,也可以通過拖拽去上傳圖片。下面我們來看一下效果,

image.png

本次算法進行了表情識別和場景識別:

image.png

第一部分我們多張圖片拖拽上傳,第二部分實現一個輪播圖,這時候可以看到有吃驚的表情,生氣的表情以及露營戶外或者是人物,可以看到對這個圖片分類利用了兩類的視覺的算法,一個是表情識別,然後另外一個是場景識別。然後我們可以去查看圖片。

二、項目實現

然後現在來看一下代碼,先講解一下它的整個結構:

image.png

  • Application:啟動的入口函數
  • common:一般就是存放公共的類或者常量,或者枚舉值
  • config:裝載或者是數據庫的配置,我們都會放在config下面, webAPPconfig是對我們的靜態資源,比如說css、js還有一些圖片,做了一個映射,比如說static,然後我們把它映射到classpath:/static目錄下。
  • Controller:我們接收外部的請求,比如參數校驗,之後通過接口調用或得到的數據返回給前端
  • Service:把不同的請求,不同的服務把它抽象成一個service,本項目有兩個service,也可以認為是兩個模塊。
  • Utils:存放公共的類或者工具函數。

接下來看一下具體的實現:
先從Controller來,看一下實現了哪些功能。

image.png

可以獲取圖片、獲取分類,通過分類以及標籤獲取圖片,通過分類獲取圖片列表以及上傳文件。
在上傳文件函數需要完成一個上傳,把上傳的文件保存到文件當中,需要調用兩個識別的函數,表情識別,場景識別。
另外需要注意一下,通過multipartFile獲取的是一個文件的輸入流,輸入流的話它只能讀取一次,然後如果要重複讀的話就會是空。 所以我們把它轉化成一個ByteArrayInputStream流,然後我們在每次用完之後,我們可以把它進行一個reset(),之後可以把流保存在我們的內存當中,一般不推薦使用這種方式,因為如果圖片的比較大的話,可能會佔用太多的內存空間。此外由於我們上傳的圖片可能會有重名,為了避免重名,我們對這個圖片的input的流,我們給它求一個md5值作為文件名。

接著來看一下ResourceService:

image.png

ResourceService是一個資源的管理器,先來看兩個函數,Postconstruct註解,我們會先去執行這個函數,取出保存在本地的數組並且加載到內存中去。 PreDestroy註解,在銷燬對象的時候,把這些數據保存到本地文件,也就是說保存在這個data上面,有一個 data.json數據,來看一下整個的數據存儲的結構。

image.png

allImg將所有上傳的圖片,放在數組裡面。
cateMap之後又分成兩個場景expression、scene,可以看到不同的分類,表情識別,場景識別,裡面存放所有識別出來的表情,比如說驚訝、生氣、開心,場景識別,存放運動、戶外,這樣存儲是為了我們能夠快速的進行查詢,比如說可以通過分類,快速的找到某一個分類下面的所有的識別,這個是 map的作用。
expressionMap是表示某類標籤下面都包括哪些圖片,senceMap也是同樣的意思。
imgLabels是一個反向的查找的過程,即通過一個圖片,識別出來了哪些場景,比如說我們可以看到它可能這張圖片它可能直接識別出來了,它是屬於人物場景,屬於運動場景,然後屬於生氣的表情,屬於演出等場景。

接著來看一下VisionService

image.png

VisionService,識別場景,表情。我們上傳圖片流,我們把整個圖片流傳到接口裡面,然後從服務端去識別這個場景。
我們是有兩種方式,早期的版本我們是通過url這種方式去上傳的,但是有一個限制就是說我們必須是利用這種oss的對象才能夠識別,新的版本的SDK我們就是開始支持通過本地上傳圖片來進行識別。

image.png

以上這個是後端的這些功能。下面來看一下前端頁面的實現:

我們前端頁面是通過vue,然後加上element-ui這個兩個組件來實現我們的前端的邏輯。我們大概可以看一下整個的結構,它可以分成三部分。

image.png

一部分就是我們通過一個上傳的組建來去實現我們剛才拖拽上傳,以及點選。

image.png

找到一個圖片,我們可以看到兩種方式,一種拖拽,一種是點擊上傳,這是通過一個組件來實現的。我們大概來介紹組件的實現,這是有不同的功能區分的。action是在上傳圖片要去訪問後端的upload接口,之後有一個事件,是在成功之後應該做哪些事情,也就是對應的要執行的函數。 比如UploadSuccess指上傳成功之後,我們要刷新頁面,添加下面的標籤分類等。

第二部分就是實現輪播圖的部分:

image.png

然後以及下面列表,通過是vue的一個組件。

image.png

vue-gallery,實現自定義的標籤名,之後定義了一個屬性:photos。photos從後臺去取回數據,之後把它渲染到前端的html頁面當中。由於我們這是一個組件,它會有對應的自己一個模板,這個就是我們整個的模板部分,之後對它進行背景圖片的處理,然後以及一些事件的定義。
vue,它的整個是一個事件的數據流,通過數據的不同的變化,然後我們就可以去觸發它的渲染,比如上傳一張圖片,它是可以對應不同的組件進行交互,利用不同的標籤,事件來驅動數據的變化。

image.png

mounted是會定義一些事件,比如圖片變化,怎麼調用,以及我們會監聽按下不同的鍵,應該做哪些操作?然後是前張圖片還是後一張圖片等。
methods定義的就是一些方法,比如點擊一個 next photo,我們就會去訪問下一張圖片。這些變化是對應的。
vue有自己的模板語言。

image.png
image.png
image.png

el是一個ID的綁定,比如#app,在這個標籤上層父級,定義了一個ID叫app,這時候可以把組件放在父級div下面,然後在這個裡面去根據模板進行渲染。

第三部分是自定義標籤的組件。

image.png

V-tag對應的是這塊,我們把它分成不同的分類,下面有不同的標籤是組件來實現的。

image.png

Data是指在初始化的時候,需要進行哪些渲染。這裡面自定義了不同的顏色。 cateMap,將返回的英文轉化成漢字去顯示出來。
它實現了幾個方法:

image.png

去取一個不同的ID,然後給它選成不同的顏色,通過取一個隨機的下標,然後去把它選成不同的顏色。
Tag是一個兩層map結構。就是第一層這裡面某比每層結構,表情,下面有幾種表情,場景下面有幾種場景,這是一個兩層的map結構。

image.png

所以在渲染的時候,會對兩層的map進行渲染,第一層完成之後,再渲染第二層數據。
實現不同的觸發,上傳文件,成功之後要進行不同的事件操作:

image.png

因為要實現不同的組件之間進行通信,自定義了一個虛擬的Event的vue的實例,然後通過Event將所有的不同的vue實例串聯起來。比如uploadSuccess去發送一個事件。通過upload vue實例去給其他的實例去發事件,在上傳成功之後,加載到輪播圖裡面。

image.png

on就對應去接收 emit傳過來的事件。如果我們得到了uploadSuccess事件,那麼就會通過從後端去獲取數據,對這個頁面進行一個刷新操作。

image.png

refresh也是同樣的道理,上傳成功之後,要對整個的tag進行一個刷新,把新識別出來的不同的場景,不同標籤,進行一個刷新。

前端的實現邏輯就是這樣的。

Leave a Reply

Your email address will not be published. Required fields are marked *