ホームページ  >  記事  >  バックエンド開発  >  Python を使用してサンタの帽子を贈ろう

Python を使用してサンタの帽子を贈ろう

WBOY
WBOY転載
2023-04-12 17:22:101719ブラウズ

クリスマスが近づいています。この西洋のお祭りを祝うことはできませんが、それでも楽しいことに参加しなければなりません。すでにクリスマスハット関連の周辺機器がたくさん出回っていると思います。今日は自分たちでやって、アバターにクリスマスハットをプレゼント

基礎知識の準備

コンピューターでは、画像は行が最初、列が二番目のマトリックスの形式で保存されます。したがって、幅 × 高さ × カラー チャネル = 480 × 256 × 3 の画像は、256 × 480 × 3 の 3 次元テンソルに格納されます。画像処理もこの考え方(OpenCVでの画像処理を含む)、つまり高さ×幅×カラーチャンネルに従って計算されます。

デジタル画像

デジタル画像の場合、私たちが見ているのは肉眼で見える実際の画像ですが、コンピューターにとっては、この画像はさまざまな明るさの集まりにすぎません。サイズが M × N の画像は M × N 行列で表すことができ、行列要素の値はその位置の画素の明るさを表し、一般に画素値が大きいほどその点は明るくなります。

一般に、グレースケール画像は 2 次元行列で表され、カラー (マルチチャネル) 画像は 3 次元行列 (M × N × 3) で表されます。

画像チャネル

ピクセルを記述します。グレースケールの場合、それを記述するために必要な値は 1 つだけです。これが 1 つのチャネルです。ピクセルが 3 つの色 (RGB) で表現されている場合、ピクセルには 3 つのチャネルがあります。 4 チャンネルの画像は、R、G、B に A チャンネルを加えたもので、透明度を示します。一般にアルファチャンネルと呼ばれ、透明度を示します。

ROI とマスク

関心領域 (ROI) の設定。専門用語に翻訳すると、関心領域を設定します。マスクは画像のマスキング処理であり、ROI 部分を残して、気にしない部分をカバーすることに相当します。上記のアルファはマスクとして使用できます。

行列 (Numpy) の知識

行列のインデックス作成、スライスなどについては、ここではあまり詳しくないので詳しくは説明しません。友達が自分で学ぶことができます。

環境の準備

基本的な知識を理解した後、コードを簡単に見てみましょう。

最初に、使用する必要のある OpenCV ライブラリと dlib ライブラリをインストールし、pip を使用してそれぞれをインストールします。

pip install python-opencv

pip install dlib

次に、データ モデル ファイルshape_predictor_5_face_landmarks.datをインターネットから手動でダウンロードします。 , アドレスは次のとおりです: http://dlib.net/files/, ダウンロードしてプロジェクト ディレクトリに置きます。

興味のある学生は、顔上の最大 68 個のキー ポイントを認識するshape_predictor_68_face_landmarks.dat を使って遊ぶことができます。

Python を使用してサンタの帽子を贈ろう

コード処理

帽子の処理

最初にやらなければならないのは帽子の処理です。以下

Python を使用してサンタの帽子を贈ろう

最初に帽子の画像の rgb 値とアルファ値を抽出します

# 帽子Python を使用してサンタの帽子を贈ろう
hat_img3 = cv2.imread("hat.png", -1)
r, g, b, a = cv2.split(hat_img3)
rgb_hat = cv2.merge((r, g, b))
cv2.imwrite("rgb_hat.jpg", rgb_hat)
cv2.imwrite("alpha.jpg", a)
print(a)
print(hat_img3.shape)
print(rgb_hat.shape)

得られる効果は次のとおりです。

#rgb image

Python を使用してサンタの帽子を贈ろう

アルファ グラフ

Python を使用してサンタの帽子を贈ろう

a の出力値は次のとおりです。

##

[[0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 ...
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]
 [0 0 0 ... 0 0 0]]

顔検出

次は、dlib 処理を使用した顔検出です。

# 人脸检测
dets = self.detector(img, 1)
x, y, w, h = dets[0].left(), dets[0].top(), dets[0].right() - dets[0].left(), dets[0].bottom() - dets[0].top()
# 关键点检测
shape = self.predictor(img, dets[0])
point1 = shape.parts()[0]
point2 = shape.parts(2)
# 求两点中心
eyes_center = ((point1.x + point2.x) // 2, (point1.y + point2.y) // 2)

次のステップは、帽子の画像を縮小することです

# 帽子和人脸转换比例
hat_w = int(round(dets[0].right()/1.5))
hat_h = int(round(dets[0].bottom() / 2))
if hat_h > y:
hat_h = y - 1
hat_newsize = cv2.resize(rgb_hat, (hat_w, hat_h))
mask = cv2.resize(a, (hat_w, hat_h))
mask_inv = cv2.bitwise_not(mask)
dh = 0
dw = 0

bg_roi = img[y+dh-hat_h:y+dh,(eyes_center[0]-hat_w//3):(eyes_center[0]+hat_w//3*2)]

ROI 抽出

ROI 抽出を実行します

# 用alpha通道作为mask
mask = cv2.resize(a, (resized_hat_w, resized_hat_h))
mask_inv = cv2.bitwise_not(mask)

マスク変数は帽子の領域を取り出します。

Python を使用してサンタの帽子を贈ろうmask_inv 変数は、顔画像から帽子が取り付けられている領域を削除するために使用されます。

Python を使用してサンタの帽子を贈ろう次に、顔写真から帽子が取り付けられている領域 (ROI) を取り出します。

# 原图ROI
# bg_roi = img[y+dh-resized_hat_h:y+dh, x+dw:x+dw+resized_hat_w]
bg_roi = img[y + dh - resized_hat_h:y + dh,
 (eyes_center[0] - resized_hat_w // 3):(eyes_center[0] + resized_hat_w // 3 * 2)]

次に、顔写真 帽子の形の部分を取り出します。

# 原图ROI中提取放帽子的区域
bg_roi = bg_roi.astype(float)
mask_inv = cv2.merge((mask_inv, mask_inv, mask_inv))
alpha = mask_inv.astype(float) / 255
# 相乘之前保证两者大小一致(可能会由于四舍五入原因不一致)
alpha = cv2.resize(alpha, (bg_roi.shape[1], bg_roi.shape[0]))
# print("alpha size: ",alpha.shape)
# print("bg_roi size: ",bg_roi.shape)
bg = cv2.multiply(alpha, bg_roi)
bg = bg.astype('uint8')

ここでは、画像のデフォルトの uint8 型を float 型に変換して演算し、最後に元に戻します。

合成画像

Python を使用してサンタの帽子を贈ろう黒い部分が帽子を置きたい場所です。

帽子の写真から帽子の部分を抽出します。

# 提取帽子区域
hat = cv2.bitwise_and(resized_hat, resized_hat, mask=mask)

リサイズしたばかりの帽子の画像を使用して抽出します。

Python を使用してサンタの帽子を贈ろう

可以看到,除了帽子部分,其他区域已经掩模处理了。

以上就是提取ROI的过程,比较难懂,需要好好琢磨,尤其是矩阵的切片、mask处理部分。

合成Python を使用してサンタの帽子を贈ろう

最后一步就是把人脸Python を使用してサンタの帽子を贈ろう与帽子合成到一起了,也就是把人脸空余帽子部分的Python を使用してサンタの帽子を贈ろう区域和帽子只展示帽子区域的Python を使用してサンタの帽子を贈ろう区域(有点拗口)合并在一起。

# 相加之前保证两者大小一致(可能会由于四舍五入原因不一致)
hat = cv2.resize(hat, (bg_roi.shape[1], bg_roi.shape[0]))
# 两个ROI区域相加
add_hat = cv2.add(bg, hat)

效果如下:

Python を使用してサンタの帽子を贈ろう

刚刚好,完美叠加Python を使用してサンタの帽子を贈ろう。

最后把这个片段放回人脸原图中,展示Python を使用してサンタの帽子を贈ろう

img[y+dh-hat_h:y+dh, (eyes_center[0]-hat_w//3):(eyes_center[0]+hat_w//3*2)] = add_hat

Python を使用してサンタの帽子を贈ろう

美美的Python を使用してサンタの帽子を贈ろう就出来啦!

我们再尝试几张不同的Python を使用してサンタの帽子を贈ろう。

Python を使用してサンタの帽子を贈ろう

Python を使用してサンタの帽子を贈ろう

整体效果还不错哦,需要注意的是,在测试的时候,我们尽量选择人脸占比比较大的Python を使用してサンタの帽子を贈ろう来合成,效果要好很多哦~

以上がPython を使用してサンタの帽子を贈ろうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。