⛳️ 需求來源
好友 A:橡皮擦,可否提供網頁,上傳帶人像的圖檔,然後可以直接摳圖,最好直接生成 PNG 圖檔下載下傳。
橡皮擦:每天需要調用多少次?
好友 A:大概 100 次吧。
橡皮擦:妥了,給你寫個免費的吧。
本案例的實戰需求是對圖檔進行摳圖,每日請求量為 100,來源依舊是好友求助,既然日請求量不大,那某智能雲的人像分隔接口就可以使用了,申請之後,其贈送了 10000 次,每秒限制 2 次請求,足夠使用。
從官方下載下傳 Python API SDK 之後,得到下圖所示目錄:
然後進入該目錄執行下述指令安裝 SDK
python setup.py build
python setup.py install
安裝成功之後就可以通過
pip list
檢視相關資料。
接下來需要建立一個
AipBodyAnalysis
,該對象是後續處理人像分析的核心對象。
建立
show_people.py
檔案,輸入如下代碼:
from aip import AipBodyAnalysis
""" 你的 APPID AK SK """
APP_ID = '你的 App ID'
API_KEY = '你的 Api Key'
SECRET_KEY = '你的 Secret Key'
client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
其中
App ID
,
Api Key
,
Secret Key
都需要提前在平台方申請使用。
接下來就可以使用人像分隔主體函數了,代碼如下:
client = AipBodyAnalysis(APP_ID, API_KEY, SECRET_KEY)
""" 讀取圖檔 """
def get_file_content(filePath):
with open(filePath, 'rb') as fp:
return fp.read()
image = get_file_content('./demo.png')
""" 調用人像分割 """
ret = client.bodySeg(image)
print(ret)
代碼用到的測試圖為:
運作後提示
ModuleNotFoundError: No module named 'chardet'
,使用
pip install chardet
安裝缺少子產品。
上述
client.bodySeg(image)
函數的參數如下所示:
-
:圖像資料,base64 編碼,要求 base64 編碼後大小不超過 4M,最短邊至少 15px,最長邊最大 4096px,支援 jpg/png/bmp 格式;image
-
:可以通過設定 type 參數,自主設定傳回哪些結果圖,避免造成帶寬的浪費type
- 可選值說明:
- labelmap - 二值圖像,需二次處理方能檢視分割效果
- scoremap - 人像前景灰階圖
- foreground - 人像前景摳圖,透明背景
- type 參數值可以是可選值的組合,用逗号分隔;如果無此參數預設輸出全部 3 類結果圖
- 可選值說明:
基于上述配置,在方法調用時添加參數,擷取人像前景摳圖。
""" 如果有可選參數 """
options = {}
options["type"] = "foreground"
""" 帶參數調用人像分割 """
ret = client.bodySeg(image, options)
print(ret)
傳回參數清單如下所示:
-
:分割結果圖檔,base64 編碼之後的二值圖像,需二次處理方能檢視分割效果labelmap
-
:分割後人像前景的 scoremap,歸一到 0-255,不用進行二次處理,直接解碼儲存圖檔即可。Base64 編碼後的灰階圖檔案,圖檔中每個像素點的灰階值 = 置信度 * 255,置信度為原圖對應像素點位于人體輪廓内的置信度,取值範圍[0, 1]scoremap
-
:分割後的人像前景摳圖,透明背景,Base64 編碼後的 png 格式圖檔,不用進行二次處理,直接解碼儲存圖檔即可。将置信度大于 0.5 的像素摳出來,并通過 image matting 技術消除鋸齒foreground
-
:檢測到的人體框數目person_num
-
:人體框資訊person_info
此時輸出
person_num
就可以獲得人像數量,測試代碼如下所示。
ret = client.bodySeg(image, options)
print(ret["person_num"]) # 輸出 1
""" 帶參數調用人像分割 """
ret = client.bodySeg(image, options)
data = ret["foreground"]
data = base64.b64decode(data)
# 生成圖檔
with open("./fore.png",'wb') as f:
f.write(data)