クリスマスが近づいています。この西洋のお祭りを祝うことはできませんが、それでも楽しいことに参加しなければなりません。すでにクリスマスハット関連の周辺機器がたくさん出回っていると思います。今日は自分たちでやって、アバターにクリスマスハットをプレゼント
コンピューターでは、画像は行が最初、列が二番目のマトリックスの形式で保存されます。したがって、幅 × 高さ × カラー チャネル = 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 部分を残して、気にしない部分をカバーすることに相当します。上記のアルファはマスクとして使用できます。
行列のインデックス作成、スライスなどについては、ここではあまり詳しくないので詳しくは説明しません。友達が自分で学ぶことができます。
基本的な知識を理解した後、コードを簡単に見てみましょう。
最初に、使用する必要のある 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 を使って遊ぶことができます。
最初にやらなければならないのは帽子の処理です。以下
最初に帽子の画像の 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 アルファ グラフ 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]]
顔検出
# 人脸检测 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 抽出
# 用alpha通道作为mask mask = cv2.resize(a, (resized_hat_w, resized_hat_h)) mask_inv = cv2.bitwise_not(mask)
マスク変数は帽子の領域を取り出します。
mask_inv 変数は、顔画像から帽子が取り付けられている領域を削除するために使用されます。
次に、顔写真から帽子が取り付けられている領域 (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 型に変換して演算し、最後に元に戻します。
合成画像
黒い部分が帽子を置きたい場所です。
帽子の写真から帽子の部分を抽出します。
# 提取帽子区域 hat = cv2.bitwise_and(resized_hat, resized_hat, mask=mask)
リサイズしたばかりの帽子の画像を使用して抽出します。
可以看到,除了帽子部分,其他区域已经掩模处理了。
以上就是提取ROI的过程,比较难懂,需要好好琢磨,尤其是矩阵的切片、mask处理部分。
最后一步就是把人脸Python を使用してサンタの帽子を贈ろう与帽子合成到一起了,也就是把人脸空余帽子部分的Python を使用してサンタの帽子を贈ろう区域和帽子只展示帽子区域的Python を使用してサンタの帽子を贈ろう区域(有点拗口)合并在一起。
# 相加之前保证两者大小一致(可能会由于四舍五入原因不一致) hat = cv2.resize(hat, (bg_roi.shape[1], bg_roi.shape[0])) # 两个ROI区域相加 add_hat = cv2.add(bg, hat)
效果如下:
刚刚好,完美叠加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 を使用してサンタの帽子を贈ろうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。