之前的學習中,曾經在香橙派上使用阿里云平臺的服務實現過類型識別:
使用香橙派并基于Linux實現最終版智能垃圾桶項目 --- 下_香橙派 項目-CSDN博客
現在,嘗試在樹莓派上通過阿里云平臺的服務實現人臉識別!
?
通過VScode遠程連接樹莓派
當然,使用SourceInsight來編寫代碼也可以,全看個人喜好。
我的個人理解是:
- VScode 更適合遠程編寫和調試
- SourceInsight 更適合本地編寫多文件的項目
對于本節想要實現的人臉識別,并不特別需要很多文件,且經常需要調試,如果使用SourceInsight就要經常涉及將文件傳給樹莓派這個操作,較為繁瑣。
關于如何連接,可以參考之前連接香橙派的博文,步驟幾乎一模一樣,唯一需要注意的是在.config文件中,樹莓派的用戶名是“pi”而不是“rasberrypi”:
小插曲 -- 使用Visual Studio Code遠程連接香橙派_visual code 連接 inspect-CSDN博客
VSCODE小操作回顧&補充
- “ALT + SHIFT":多行縮進
- “CTRL + S”:保存
- “CTRL + F”:變量名查找 / 替換
?連接成功后的樣子:
?
樹莓派Python版本檢查
python版本不夠的升級方法:
使用香橙派 在Linux環境中安裝并學習Python_如何在香橙派上運行python文件-CSDN博客
在之前就提到過,想要使用阿里云的人工智能模型,python版本最好是3開頭的,所以在樹莓派中同樣運行以下指令檢查python版本:
python --version
?
可見python版本已經是3.11了,那就不需要改動了!
并且由于這是自帶的python,所以其庫就在“/usr/bin”?下:
ls /usr/bin
配置環境變量
在后面的代碼中,涉及到C語言調用python,所以需要調用<Python.h>,因此需要配置環境變量,否則這個庫找不到:
vi ~/.bashrc #將以下內容加到最后,保存退出
export C_INCLUDE_PATH=/usr/include/python3.11
注意,配置后,要重啟樹莓派后才能生效?!!
阿里云的人臉識別方案
-
阿里云官網:阿里云|達摩院視覺智能開放平臺
-
如果之前沒有進行過注冊,則需要通過支付寶注冊,并獲取AccessKey ID和Secret
我之前就創建過賬號,現在再獲取一組 ID & Secret (如果之前有用之前的應該也可以):阿里云登錄 - 歡迎登錄阿里云,安全穩定的云計算服務平臺
AccessKey ID 和 密碼 一定要自己保存好!!
-
在樹莓派上下載相應的SDK:
關于人臉人體的SDK的查找:
如何獲取、安裝、使用視覺智能開放平臺PythonSDK及代碼示例_視覺智能開放平臺(VIAPI)-阿里云幫助中心
pip install alibabacloud_facebody20191230
此處發生了報錯:
解決辦法:
sudo mv /usr/lib/python3.11/EXTERNALLY-MANAGED /usr/lib/python3.11/EXTERNALLY-MANAGED.bak
-
?安裝完成后,根據自己實際的ACCESS_KEY_ID 和 ACCESS_KEY_SECRET,將以下內容寫入到家目錄下的.bashrc中:
vi ~/.bashrc #然后在末尾輸入以下內容:
export ALIBABA_CLOUD_ACCESS_KEY_ID="XXX" #根據自己實際的ID填寫
export ALIBABA_CLOUD_ACCESS_KEY_SECRET="XXXX" #根據自己實際的SECRET填寫
?
保存退出后,重啟樹莓派,再輸入“export”驗證:
可見,ACCESSKEY已經成功被配置成為環境變量!
-
?在官網的人臉識別中找到一個感興趣的模型,我此處找了“人臉比對1:1?”:能力展示-阿里云視覺智能開放平臺
- 點擊“立即開通”開通服務
- 點擊“立刻購買”購買服務(此處似乎有優惠,免費使用1年)
此時,就可以使用這個模型了!
-
下載示例代碼進行測試
不能直接在人臉比對1:1下使用那個python代碼例程,而是要在以下鏈接中找到“文件在本地或文件不在同一地域OSS”的例程:
人臉比對1:1示例代碼_視覺智能開放平臺(VIAPI)-阿里云幫助中心
在樹莓派”mjm_code“下創建一個“face_detect_test”文件夾,將示例代碼拷貝進來并稍作修改:
test.py:
# -*- coding: utf-8 -*-
# 引入依賴包
# 最低SDK版本要求:facebody20191230的SDK版本需大于等于4.0.8
# 可以在此倉庫地址中引用最新版本SDK:https://pypi.org/project/alibabacloud-facebody20191230/
# pip install alibabacloud_facebody20191230import os
import io
from urllib.request import urlopen
from alibabacloud_facebody20191230.client import Client
from alibabacloud_facebody20191230.models import CompareFaceAdvanceRequest
from alibabacloud_tea_openapi.models import Config
from alibabacloud_tea_util.models import RuntimeOptionsdef face_detect(): #定義成一個函數,方便調用!config = Config(# 創建AccessKey ID和AccessKey Secret,請參考https://help.aliyun.com/document_detail/175144.html。# 如果您用的是RAM用戶的AccessKey,還需要為RAM用戶授予權限AliyunVIAPIFullAccess,請參考https://help.aliyun.com/document_detail/145025.html。# 從環境變量讀取配置的AccessKey ID和AccessKey Secret。運行代碼示例前必須先配置環境變量。access_key_id=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_ID'),access_key_secret=os.environ.get('ALIBABA_CLOUD_ACCESS_KEY_SECRET'),# 訪問的域名endpoint='facebody.cn-shanghai.aliyuncs.com',# 訪問的域名對應的regionregion_id='cn-shanghai')runtime_option = RuntimeOptions()compare_face_request = CompareFaceAdvanceRequest()#場景一:文件在本地streamA = open(r'/home/pi/mjm_code/face_detect_test/mjm.png', 'rb') #預存的照片compare_face_request.image_urlaobject = streamAstreamB = open(r'/home/pi/mjm_code/face_detect_test/face.png', 'rb') #待測試的照片compare_face_request.image_urlbobject = streamBtry:# 初始化Clientclient = Client(config)response = client.compare_face_advance(compare_face_request, runtime_option)# 獲取整體結果print(response.body)except Exception as error:# 獲取整體報錯信息print(error)# 獲取單個字段print(error.code)# tips: 可通過error.__dict__查看屬性名稱# 關閉流streamA.close()streamB.close()if __name__ == '__main__': #寫一個main調用face_detect函數來測試face_detect()
我使用了我自己的照片作為標準,并使用了兩張照片進行測試,第一張是我本人的另一張照片;第二張是我同學的照片:
分別存在樹莓派本地:
-
/home/pi/mjm_code/face_detect_test/mjm.png //預存的照片
-
/home/pi/mjm_code/face_detect_test/face.png //待測試的照片
?可見,當我使用本人照片時,置信度約為77%,而當我使用同學照片時,置信度直接變為0%(我同學和我長的也太不一樣了哈哈哈),所以綜合來說測試成功!
-
置信度的提取和轉化
但是返回的結果是一個結構非常的數據體,所以嘗試將置信度單獨返回,并只保留整數部分
提取的代碼如下:
# 單獨提取置信度
confidence = response.body.to_map()['Data']['Confidence'] #to_map()函數很重要,不要忘記
score = int(confidence)
print(score)
return score
現在,就可以返回置信度的整數部分了!?而之后就可以根據這個整數score來進行判斷了!
編寫C語言調用python的人臉識別
在剛剛的測試中,寫出了調用阿里云人臉識別服務的pyhton程序,那么現在,嘗試寫C語言程序來調用python程序從而實現人臉識別!
-
①將剛剛的test.py中的main函數部分刪除并重命名為face.py
剛剛加入main函數是為了直接調用封裝好的face_detect函數,而現在要使用C語言來調用它,自然就不需要main函數了!
-
②編寫調用face_detect函數的C函數
回顧“C語言調用Python的步驟”:
詳見之前的博文:
使用香橙派并基于Linux實現最終版智能垃圾桶項目 --- 下_香橙派 項目-CSDN博客
face_cmp.c:?
#include <stdio.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <Python.h>#include "face_cmp.h"void face_init(void)
{Py_Initialize();PyObject *sys = PyImport_ImportModule("sys");PyObject *path = PyObject_GetAttrString(sys, "path");PyList_Append(path, PyUnicode_FromString("."));
}void face_final(void)
{Py_Finalize();
}int face_score(void) //python下face_detect函數返回的是已經經過提取和取證過的置信度score,是個int型
{PyObject *pModule = PyImport_ImportModule("face"); //加載python文件if (!pModule){PyErr_Print();printf("Error: failed to load module\n");goto FAILED_MODULE; //goto的意思就是如果運行到這里就直接跳轉到FAILED_MODULE}PyObject *pFunc = PyObject_GetAttrString(pModule, "face_detect"); //加載python文件中的對應函數if (!pFunc){PyErr_Print();printf("Error: failed to load function\n");goto FAILED_FUNC;}PyObject *pValue = PyObject_CallObject(pFunc, NULL);if (!pValue){PyErr_Print();printf("Error: function call failed\n");goto FAILED_VALUE;}int result = 0;if (!PyArg_Parse(pValue, "i", &result)) //ace_detect函數返回的是已經經過提取和取證過的置信度score,是個int型,用‘i’表示{PyErr_Print();printf("Error: parse failed");goto FAILED_RESULT;}/* 如果函數返回的是字符串,上面的PyArg_Parse則需要用‘s’來表示,且下面注釋的代碼非常重要,因為字符串名代表了其首地址,所以不能直接復制而是需要使用strncpy函數!!!category = (char *)malloc(sizeof(char) * (strlen(result) + 1) ); //開辟一個新的字符串常量。+1是為了留出空間給\0memset(category, 0, (strlen(result) + 1)); //初始化字符串strncpy(category, result, (strlen(result) + 1)); //將result的結果復制給新的字符串*/FAILED_RESULT:Py_DECREF(pValue);
FAILED_VALUE:Py_DECREF(pFunc);
FAILED_FUNC:Py_DECREF(pModule);
FAILED_MODULE:return result;
}
face_cmp.h:
#ifndef __face__H
#define __face__Hvoid face_init(void);
void face_final(void);
int face_score(void);#endif
- face_cmp的作用就是封裝C語言下的人臉識別函數
- C語言下的人臉識別函數的實現通過調用python代碼下的face_detect函數
-
③編寫C程序調用剛剛的C函數實現人臉識別
face_test.c:
#include <stdio.h>
#include <stdlib.h>
#include "face_cmp.h"int main()
{int score = 0;face_init();score = face_score();printf("score=%d\n", score);face_final();return 0;
}
-
④編譯并試運行?
運行以下代碼編譯:
gcc face_test.c face_cmp.c -I /usr/include/python3.11/ -l python3.11
可見,調用成功!?