生成AIで作成した人物だけ明るく修正!黒いフチや合成の違和感も自然に消すPythonテクニック

31

こんにちは!Python初心者さん向けに書きます🌷

みなさん、こんにちは!
画像加工にチャレンジしている麻衣子です☺️

最近は、生成AIで可愛い美少女をたくさん召喚できるようになって、とっても便利ですよね。でも実際にやってみると、美少女が少し暗めに生成された経験はありませんか?そこで麻衣子は人物だけ切り抜いて(例えばrembgなど使って)何とか女性だけ明るくしようと思ったりしてチャレンジしていたけど「切り抜いた人の周りに黒いフチが出る」とか、「人物だけ明るくしたいのに、合成すると違和感が出る…」って悩んだことありませんか? 私もすっごく悩みました!

この画像がまさにそれ!左が元画像で右が人物のみ明るした画像です。少し違和感ありませんか?それは背景と人物の境界に黒い線が入っているからなんです。

これです!

今日はそんな悩みをぜ〜んぶ解決できる、Pythonコードと工夫ポイントを、初心者さんにも分かりやすく、丁寧に説明します💡

これが違和感なく合成できた写真比較です。背景と人物の境界が自然だと思いませんか?

このように自然な境界に出来ます!

この記事でできること

  • 生成AI作成した人物だけ明るくできる
  • 合成しても「黒いフチ」が消せる!
  • 境界が自然になじんで違和感がなくなる!
  • 初心者さんでもコピペでOK!
  • コードの「なぜこうしてるの?」も丁寧に解説

どうして違和感や黒い線が出るの?

rembgなどで人物を切り抜くと、人物のまわりに黒っぽい輪郭が残ったり、カット線がはっきりしちゃうことがよくあります。これ、**「マットフリンジ(matting fringe)」とか「黒マット」**って呼ばれる現象なんです。

アルファチャンネルという透明度のデータが関係していて、半透明な部分の色が「元の背景(たいてい黒)」と混ざっちゃうから、フチが黒ずんで見えるんです。

今回やることの流れ

  1. rembgで人物を自動切り抜き
  2. 切り抜いた人物だけ明るくする
  3. 「黒いフチ」を除去してなじませる
  4. 背景と自然に合成する
  5. 合成した画像の境界だけやさしくぼかす
  6. ビフォーアフター画像も作ってみよう!

コード全文(コピペOK)

まずは全部のコードです。
(下で詳しく解説します!)

from rembg import remove, new_session
from PIL import Image, ImageEnhance, ImageFilter
import numpy as np

# 1. モデルセッション
session = new_session("birefnet-portrait")  # 人物切り抜き用

# 2. 画像読み込み
input_path = '1.jpg'
original = Image.open(input_path).convert("RGBA")

# 3. rembgで人物切り抜き
person = remove(original, session=session)

# 4. 明るさ調整
enhancer = ImageEnhance.Brightness(person)
person_brighter = enhancer.enhance(1.3)

# 5. 黒いフチ(マット)除去
def remove_black_matte(img):
    arr = np.array(img).astype(np.float32)
    rgb = arr[..., :3]
    alpha = arr[..., 3:4] / 255.0
    rgb = np.where(alpha > 0,
                   (rgb - (1 - alpha) * 0) / (alpha + 1e-6),
                   rgb)
    arr[..., :3] = np.clip(rgb, 0, 255)
    return Image.fromarray(arr.astype(np.uint8), "RGBA")

person_brighter = remove_black_matte(person_brighter)

# 6. 背景部分生成
background = original.copy()
person_mask = person_brighter.split()[-1]
background_np = np.array(background)
background_np[..., 3] = 255 - np.array(person_mask)
background = Image.fromarray(background_np)

# 7. 合成
result = Image.alpha_composite(background, person_brighter)

# 8. 境界だけぼかす
def blur_edges(image, mask, blur_radius=8, edge_width=12):
    mask_blur = mask.filter(ImageFilter.GaussianBlur(blur_radius//2))
    edge = Image.fromarray(
        np.abs(np.array(mask, dtype=np.int16) - np.array(mask_blur, dtype=np.int16)).astype(np.uint8)
    )
    edge_wide = edge.filter(ImageFilter.GaussianBlur(edge_width))
    blurred_image = image.filter(ImageFilter.GaussianBlur(blur_radius))
    edge_mask_np = np.array(edge_wide).astype(np.float32) / 255.0
    image_np = np.array(image).astype(np.float32)
    blurred_np = np.array(blurred_image).astype(np.float32)
    composite_np = (1 - edge_mask_np[..., None]) * image_np + edge_mask_np[..., None] * blurred_np
    composite_img = Image.fromarray(np.clip(composite_np, 0, 255).astype(np.uint8))
    return composite_img

result_blur = blur_edges(result, person_mask, blur_radius=8, edge_width=12)

# 9. 保存
result_rgb = result_blur.convert("RGB")
result_rgb.save('output.jpg')

# 10. ビフォーアフター画像
w, h = original.size
original_rgb = original.convert("RGB")
result_rgb = result_rgb.resize((w, h))
compare_img = Image.new("RGB", (w*2, h))
compare_img.paste(original_rgb, (0, 0))
compare_img.paste(result_rgb, (w, 0))
compare_img.save("compare.jpg")

コードのポイントをやさしく解説!

1. rembgで自動切り抜き

session = new_session("birefnet-portrait")
person = remove(original, session=session)

「birefnet-portrait」モデルを使うことで、人物だけをしっかり切り抜きます。

2. 切り抜いた人物だけ明るく!

pythonコピーする編集するenhancer = ImageEnhance.Brightness(person)
person_brighter = enhancer.enhance(1.3)

ここで人物だけを明るく加工します。1.3は30%明るくする意味。
背景はそのまま、人物だけ明るい写真にできます!

3. 黒いフチ(マットフリンジ)を除去

pythonコピーする編集するdef remove_black_matte(img):
    ...
person_brighter = remove_black_matte(person_brighter)

この関数がポイント!
アルファチャンネル(透明度)をもとに黒色成分を補正して、フチの黒ずみがなくなります。
画像合成するときの違和感の原因を、Pythonでしっかり解消しています。

4. 背景と人物を合成

pythonコピーする編集するbackground = original.copy()
person_mask = person_brighter.split()[-1]
background_np = np.array(background)
background_np[..., 3] = 255 - np.array(person_mask)
background = Image.fromarray(background_np)
result = Image.alpha_composite(background, person_brighter)

背景部分は人物マスクを使って透明にして、明るくした人物と合成します。
これで「人物だけ明るい」画像ができあがり!

5. 境界だけやさしくぼかす

pythonコピーする編集するdef blur_edges(image, mask, blur_radius=8, edge_width=12):
    ...
result_blur = blur_edges(result, person_mask, blur_radius=8, edge_width=12)

この関数がすごく大事!
境界線だけをやさしくぼかすことで、「切り抜いた感」がなくなってすごく自然に見えます。
フチ全体をぼかすと全体がボヤけちゃうので、「境界エリアだけ」に工夫してぼかしてるんです。

6. ビフォーアフター画像を作る

pythonコピーする編集するcompare_img = Image.new("RGB", (w*2, h))
compare_img.paste(original_rgb, (0, 0))
compare_img.paste(result_rgb, (w, 0))
compare_img.save("compare.jpg")

加工前・加工後の画像を横並びで比べられるから、変化がとっても分かりやすいですよ!

おわりに🌸

いかがでしたか?
Python初心者さんでも、このコードをそのまま使えば「人物だけ明るく、自然に合成」できちゃいます!
しかも、よく悩む「黒いフチ」や「切り抜きの違和感」も、しっかり消せるんです。

「画像加工ってむずかしそう…」って思ってる方も、ひとつずつ動かしてみればきっと大丈夫!
分からない部分や「ここがうまくいかない!」があれば、コメントやSNSで気軽に聞いてくださいね。

みなさんもぜひチャレンジして、素敵な画像をたくさん作ってみてください♪

ご覧いただきありがとうございました🌷
(この記事が役立ったら、シェアやいいねもらえると嬉しいです!)

質問や要望があれば、追記用の文も書きますので遠慮なくどうぞ!

関連記事

コメント

  1. この記事へのコメントはありません。

目次