一行命令自動給圖片戴上口罩,硬核操作!

2021-02-15 腳本之家


本文經授權轉自公眾號  Prodesire(ID:Prodesire)

2019 年底開始蔓延的新型肺炎疫情牽動人心,作為個體,我們力所能及的就是儘量待在家中少出門。

看到一些朋友叫設計同學幫忙給自己的頭像戴上口罩,作為技術人,心想一定還有更多人有這樣的訴求,不如開發一個簡單的程序來實現這個需求,也算是幫助設計姐姐減少工作量。

於是花了些時間,寫了一個叫做 face-mask[1] 的命令行工具,能夠輕鬆的給圖片中的人像戴上口罩,而且口罩的方向和大小都是適應人臉的哦~

使用

安裝 face-mask

確保 Python 版本在 3.6 及以上

使用 face-mask

直接指定圖片路徑即可為圖片中的人像戴上口罩,並會生成一個新的圖片(額外有 -with-mask 後綴):

face-mask /path/to/face/picture

通過指定 --show 選項,還可以使用默認圖片查看器打開新生成的圖片:

face-mask /path/to/face/picture --show

效果

給一個人戴上口罩

給多個人戴上口罩

給動漫人物戴上口罩

實現思路

要想實現上面的效果,我們應該怎麼做?不妨這麼想:

關於人臉識別,可以使用 face_recognition[2] 庫進行識別。

關於圖像處理,可以使用 Pillow[3] 庫進行處理。

代碼

有了思路之後,實現就是件相對輕鬆的事情。不過對庫的熟悉和圖片的變換計算可能要花些時間。

詳細的代碼請閱讀 face-mask[4]。這裡僅說明下最核心的步驟。

人臉識別

import face_recognition

face_image_np = face_recognition.load_image_file('/path/to/face/picture')
face_landmarks = face_recognition.face_landmarks(face_image_np)

藉助 face_recognition 庫可以輕鬆的識別出人像,最終得到的 face_landmarks 是一個列表,裡面的每個 face_landmark 都表示一個人像數據。

face_landmark 是一個字典,其中的鍵表示人像特徵,值表示該特徵的點的列表。比如:

鍵 nose_bridge 表示鼻梁

鍵 chin 表示臉頰

我們需要根據每個 face_landmark,給對應的頭像戴上口罩。

獲得鼻子和臉頰的特徵點

import numpy as np

nose_bridge = face_landmark['nose_bridge']
nose_point = nose_bridge[len(nose_bridge) * 1 // 4]
nose_v = np.array(nose_point)

chin = face_landmark['chin']
chin_len = len(chin)
chin_bottom_point = chin[chin_len // 2]
chin_bottom_v = np.array(chin_bottom_point)
chin_left_point = chin[chin_len // 8]
chin_right_point = chin[chin_len * 7 // 8]

表示上鼻梁的一個點 nose_point

表示臉左點 chin_left_point

表示臉右點 chin_right_point

表示臉底點 chin_bottom_point

拆分、縮放和合併口罩

from PIL import Image

_face_img = Image.fromarray(face_image_np)
_mask_img = Image.open('/path/to/mask/picture')

# split mask and resize
width = _mask_img.width
height = _mask_img.height
width_ratio = 1.2
new_height = int(np.linalg.norm(nose_v - chin_bottom_v))

# left
mask_left_img = _mask_img.crop((0, 0, width // 2, height))
mask_left_width = get_distance_from_point_to_line(chin_left_point, nose_point, chin_bottom_point)
mask_left_width = int(mask_left_width * width_ratio)
mask_left_img = mask_left_img.resize((mask_left_width, new_height))

# right
mask_right_img = _mask_img.crop((width // 2, 0, width, height))
mask_right_width = get_distance_from_point_to_line(chin_right_point, nose_point, chin_bottom_point)
mask_right_width = int(mask_right_width * width_ratio)
mask_right_img = mask_right_img.resize((mask_right_width, new_height))

# merge mask
size = (mask_left_img.width + mask_right_img.width, new_height)
mask_img = Image.new('RGBA', size)
mask_img.paste(mask_left_img, (0, 0), mask_left_img)
mask_img.paste(mask_right_img, (mask_left_img.width, 0), mask_right_img)

get_distance_from_point_to_line 用來獲取一個點到一條線的距離,具體實現可看原始碼。

width_ratio 是寬度係數,用來適當擴大口罩。原因我們是根據臉頰的寬度計算口罩的寬度,但口罩是待在耳朵上的,真實寬度應該要更寬。

旋轉口罩、並放到原圖適當位置

# rotate mask
angle = np.arctan2(chin_bottom_point[1] - nose_point[1], chin_bottom_point[0] - nose_point[0])
rotated_mask_img = mask_img.rotate(angle, expand=True)

# calculate mask location
center_x = (nose_point[0] + chin_bottom_point[0]) // 2
center_y = (nose_point[1] + chin_bottom_point[1]) // 2

offset = mask_img.width // 2 - mask_left_img.width
radian = angle * np.pi / 180
box_x = center_x + int(offset * np.cos(radian)) - rotated_mask_img.width // 2
box_y = center_y + int(offset * np.sin(radian)) - rotated_mask_img.height // 2

# add mask
_face_img.paste(mask_img, (box_x, box_y), mask_img)

旋轉新口罩,角度為中心線相對於 y 軸的旋轉角

計算口罩應該放置的坐標

將新口罩放在原圖的計算出的坐標下

最後就是將新圖片保存到本地路徑,代碼不再展示。

總結

我們藉助 face_recognition 庫可以輕鬆的識別出人像,然後根據臉頰的寬度和鼻梁位置計算出口罩的大小、方向和位置,並最終生成出戴上口罩的圖片。整個過程並不複雜,但在坐標計算上要格外小心,如此,我們便打造了一個短小精悍的「自動戴上口罩」程序!

參考資料:[1]face-mask: https://github.com/Prodesire/face-mask[2]face_recognition: https://github.com/ageitgey/face_recognition[3]Pillow: https://pillow.readthedocs.io/[4]face-mask: https://github.com/Prodesire/face-mask

更多精彩

在公眾號後臺對話框輸入以下關鍵詞

查看更多優質內容!

女朋友 | 大數據 | 運維 | 書單 | 算法

大數據 | JavaScript | Python | 黑客

AI | 人工智慧 | 5G | 區塊鏈

機器學習 | 數學 | 送書

相關焦點

  • 川普變了:我完全支持戴口罩,戴上就像獨行俠!
    美國新冠感染人數仍在逐日飆升,此前標榜不需戴口罩的美國總統川普終於鬆口。當地時間7月1日,川普首次表示他支持民眾都戴上口罩,「我絕對支持戴口罩,我覺得戴口罩挺好」。此外,他還稱自己有個深黑色的口罩,戴上它看起來像是獨行俠一樣。
  • 尋攻略 | 戴口罩也能解鎖Face ID,你不知道的神操作都在這!
    疫情當前,出門都必須戴上口罩,不過戴了口罩後問題來了:戴上口罩之後,我的iPhone不認識我了!Face ID解鎖不了啊!那就真的沒有辦法了嗎?自從iPhone用了人臉識別技術後,很多小夥伴都覺得這個功能非常方便,但是也有人反映現在出門戴個口罩就沒法識別了,這時你可以設置一個替用外貌。 這個是iOS 13系統新增的功能,比如戴口罩的小夥伴,可以錄一個沒戴口罩的主外貌,以及戴上口罩的替用外貌,提高識別率,這樣一來,無論你戴沒戴口罩,都能識別出來。
  • 蘋果推送IOS14.5,終於能戴口罩解鎖了!
    其中,對一般用戶影響最大的,可能是戴口罩想解鎖iPhone 時,終於可以省略Face ID 與密碼的手動輸入過程,搭配Apple Watch 自動完成解鎖。具體操作方式,是當用戶戴著口罩並啟動Face ID 時(過往通常會失敗並需要輸入密碼),若用戶配戴已解鎖的Apple Watch,iPhone 就會自動跳過驗證Face ID 與輸入密碼的過程,自動解鎖iPhone。
  • 戴口罩也能面容解鎖手機,原因是什麼?
    戴口罩已經成為我們生活中必不可少的一件重要事項了,但這可頭疼壞了iPhone手機的用戶們了,畢竟目前主流的iPhone手機都是用Face ID來解鎖的。如果戴上口罩,就必須經歷一次,面容識別失敗,手動輸入密碼的過程。那麼Face ID是否能夠認出戴口罩的你呢?由於不想頻繁手動輸入密碼來解鎖手機,許多腦洞大開的小夥伴就找到了戴口罩也能解鎖手機的方法。
  • 一鍵自動檢測和修復Windows系統+CMD命令行一行命令獲取公網ip
    一鍵自動檢測和修復Windows系統+CMD命令行一行命令獲取公網ip▲一鍵自動檢測和修復Windows系統▲在我們日常使用電腦時,有時候總能遇到系統卡頓、崩潰、未響應之類的問題。很多人在遇到問題時都會選擇直接重裝系統來解決,其實沒必要。今天就來教大家兩個比較實用的自動檢測和修復指令。
  • 英國人終於戴口罩了!
    雖然不是直接答覆的我本人,BBC畢竟還是正面回答了關於戴口罩的問題,可惜他們仍然堅持說,不需要戴口罩.
  • 與新冠患者相遇,雙方戴口罩與不戴口罩感染的概率是多少?
    因此,戴口罩遮住口、鼻保護好呼吸道非常重要!即便是接種了新冠肺炎疫苗,在進入人員密集或通風不良的公共場所時、乘坐電梯或公共運輸工具時、有發熱或咳嗽等症狀時、就醫時最好還是正確佩戴口罩。與新冠患者相遇,雙方戴口罩與不戴口罩感染的概率是多少?
  • 戴口罩解鎖iPhone背後,手機解鎖方式經歷了怎樣的變革?
    得益於 3D 結構光技術,Face ID 的準確度確實比普通的 2D 人臉識別要高,但是在使用場景上卻不如指紋識別。當時極客之選(微信:GeekChoice)就曾經做過測試,如果面部被遮擋,Face ID 會存在識別不出的情況。在疫情到來的時候,這個問題迎來了集中爆發。可能連蘋果也沒有想到,會有一天需要人人都戴口罩。
  • Python一行代碼就能實現的騷操作
    ,今天就來分享下這種一行代碼就可以搞定的 6 個騷操作,解決實際應用中的問題。1、一行代碼實現 ftp 服務假如需要臨時起個 ftp 服務或者臨時搭建個 ftp 用來傳輸文件,都能用 python 一行命令搞定:比如說 ftp 服務,需要先要安裝 pyftpdlib, 然後通過下面的一條命令就完成了當前目錄 ftp 服務的搭建:
  • 用這種方法,戴口罩也能解鎖你的手機
    那麼,在公共場所,戴口罩使用手機會給我們帶來諸多的不便,例如:消息來了,想要看一下,面容ID不認識你,只能輸入密碼;買個東西,使用微信掃碼支付,面容ID還是不認識你,還是得輸密碼。這些問題大家肯定都遇到過,並且深有體會(使用數字密碼、指紋解鎖的親們可以自動忽略)。下面小編就為大家具體講解,「戴口罩也能解鎖手機」具體應該如何操作(前提要有一部iPhone),快拿小本本記下來!
  • 長時間戴口罩引發乾眼症!附「夏季口罩佩戴指南」
    一方面,防疫現狀下不好好戴口罩會增大感染風險;另一方面,長時間戴口罩會給面部帶來不適,尤其是在炎熱的夏季。據日媒最新報導,長時間戴口罩還會引發乾眼症。他解釋,戴口罩時,人們呼出的氣體會接觸眼睛,使眼球表面變得乾燥,引發乾眼症。如果戴著口罩長時間看電腦和智慧型手機,會導致患乾眼症風險提高。2020年發表在美國《眼科與治療》雜誌的一篇研究同樣證實,長期戴口罩或引發乾眼症,並且戴口罩時間越長,眼乾症狀越明顯。
  • 戴口罩也能解鎖手機?快來試試這些方法!
    但戴口罩,模樣變化太大,iPhone就需要大量的時間進行訓練,因此每次戴口罩識別失敗後,再輸入密碼,其實就是訓練Face ID的時候。圖片來自網絡之所以不能像戴口罩一樣完全遮住下半張臉,是因為蘋果會判定「臉部有遮擋」。 至少要露出雙眼、一半鼻子和嘴角。然後按照Face ID的要求轉動頭部直至完成。
  • 【小技巧】iPhone戴口罩使用Face ID解鎖方法
    小編覺得Face ID確實挺好用,但是戴上口罩Face ID就不認人了,現在坐公交
  • 這樣做,出門戴口罩也能解鎖 Face ID
    雖然蘋果的官方說法是戴著口罩無法使用 Face ID,但已經有不少人成功戴著口罩解鎖了 iPhone。只不過這個學習過程屬於一個黑箱操作,誰也不知道嘗試多少次才能成功觸發。騰訊安全旗下的玄武實驗室提供了一種方法可以對 Face ID 進行「刻意訓練」,讓手機能夠快速學習戴口罩的面容。首先拿一個口罩對摺,戴在一邊的耳朵上;保持半遮面的狀態,設置 Face ID;成功錄入後,取下口罩解鎖手機。
  • 醫務人員戴口罩最新要求!
    導 語:《公眾和重點職業人群戴口罩指引(2021年8月版)》發布!
  • 又有幾十萬隻「三無」工業假口罩被查,戴上太危險了
    該批口罩有3個品種,分別為Kinmed、TopMax、DUST MASK FFP2口罩,以上所有產品外包裝上標有英文字母,沒有任何中文標識,更無廠名廠址,內有塑料包裝,塑料包裝上沒有任何標籤標識,內外包裝均未見產品合格證,屬「三無」產品。益陽市場監管部門已正式立案,目前該案正在進一步調查處理中。
  • 戴口罩,iPhone人臉識別就廢了?
    但目前由於一個特殊原因,可能會導致iPhone人臉識別完全不可用,那就是目前的武漢新型冠狀病毒肺炎,為了防止蔓延,最重要防護手段之一就是戴口罩,小智昨天也給大家介紹了如何帶對口罩。由於戴口罩會遮住大半張臉,iPhone人臉識別大概率會失效,只能用回密碼解鎖,讓人感覺很不方便。
  • 這些地方必須戴口罩
    3.新的戴口罩指引中,重點職業人群包括哪些,戴口罩有什麼新要求?新版戴口罩指引中,重點職業人群主要涉及境外輸入和汙染傳播高風險崗位、醫療機構工作人員和公共場所服務人員等三類人群。公眾日常要注意以下事項:一是正確佩戴口罩,確保口罩蓋住口鼻和下巴,鼻夾要壓實;二是口罩出現髒汙、變形、損壞、異味時需及時更換,每個口罩累計佩戴時間不超過8小時;三是在跨地區公共運輸工具上,或醫院等環境使用過的口罩不建議重複使用;四是需重複使用的口罩在不使用時宜懸掛於清潔、乾燥、通風處;五是戴口罩期間如出現憋悶、氣短等不適,應立即前往空曠通風處摘除口罩
  • 戴口罩的事問問天火同人
    疫情這件事已經延續了大半年了,感染和死亡數咱就不再重複提瞭然而,口罩這件事,雖然死了那麼多人,很多國家依舊不實行全民戴口罩
  • 戴上「福氣口罩」:牛年福氣,藏都藏不住!
    眼看就要春節了,帶上這款福氣口罩,特別應景,紅紅火火。除了自己和家人戴,很多人都買了這款口罩作為禮物送朋友。作為拜年禮zui合適,看著喜慶,而且對方肯定用得上,不用擔心送錯禮物對方不喜歡。中國人傳統過春節,都會在門上貼福字,寓意「五福臨門」。一福長壽、二福富貴、三福康寧、四福好德、五福善終。戴上福氣口罩,也祝願全家人都收穫福壽綿長、心靈安寧、寬厚寧靜、財富滿滿的新一年。口罩上大大的「牛」字,看起來就牛勁十足,寓意時來運轉、扭轉乾坤。來年一定會諸事順遂、稱心如意,2021牛年,鴻運當頭,牛運亨通~戴上它,新的一年日積小財、月累大財,日積月累財無窮。