LoginSignup
2
1
記事投稿キャンペーン 「2024年!初アウトプットをしよう」

IPPONグランプリのプロフィール画像を作りたい(という記事に触発されて).

Last updated at Posted at 2024-01-29

きっかけ

IPPONグランプリのプロフィール画像を作りたい(わけではなかったのです).の記事がおもしろかったので、つい。

変更点

ほぼ元記事のままの処理ですが、できるだけnumpyopencvの機能を使って簡潔なコードになるように努めました。また、ガウシアンフィルタによる平滑化で「ノッペリ」となるように前処理しました。

コード

rembgは導入済みが前提です。

import cv2
import numpy as np
from rembg import remove

# https://sipi.usc.edu/database/database.php?volume=misc&image=4#top
im = cv2.imread('4.1.04.tiff', cv2.IMREAD_COLOR)

# https://commons.wikimedia.org/wiki/File:Visit_of_Bill_Gates_to_the_European_Commission_-_P062021-967902.jpg
#im = cv2.imread('input.jpg', cv2.IMREAD_COLOR)

im = remove(im).copy() # 背景を削除

# 前景と背景のマスク情報  閾値は適当に127
cond_bg = (im[:,:,3] <= 127) # 背景
cond_fg = (im[:,:,3] >  127) # 前景

# 色分け用のグレイスケール画像
im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

# ガウシアンフィルタで平滑化
# カーネルサイズは画像サイズからテキトーに算出
kn = [int(max(v//256, 3)) for v in im.shape[:2]]
kn = [v+1 if v % 2 == 0 else v for v in kn] # サイズは奇数でなければならない
im = cv2.GaussianBlur(im, kn, 3)

# 結果のカラー(BGR)画像
img_res = np.zeros( list(im.shape)+[3], dtype=np.uint8)
img_res[:,:] = (0, 0, 255) # 動作(漏れ)チェック用に赤で塗りつぶし

# 前景の最明色=背景のようなのでそれにあわせる
CLR_BG = (0, 238, 238)
COLORS = [(0, 0, 0), (0, 206, 238), CLR_BG]

# とりあえず前景の最暗~最明の範囲で等分割
rng = np.linspace(im[cond_fg].min(), im[cond_fg].max(), len(COLORS)+1)
print(rng)
rng[0], rng[-1] = (0, 255) # 両端は真黒、真白に

# 色分け
for i, clr in enumerate(COLORS):
    cond = ((im >= rng[i]) & (im <= rng[i+1]))
    img_res[cond] = clr

# あらためて背景を塗りつぶす
img_res[cond_bg] = CLR_BG

cv2.imwrite('result.png', img_res)

結果例

4.1.04.png
result.png

その他

このラスタ画像から輪郭抽出してベクター化してみるのもおもしろそうです。

参考記事

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1