写真合成

pythonによる写真の合成

更新日: 2021-04-30

2つの透かしが入った写真を合成し、透かしのない写真を生成する

課題 #

とあるサイトから写真を自動でダウンロードしてきたところ、写真には一定の場所に透かしが入っている。透かしは1枚の写真に対して2通りの入り方があり、両者ともダウンロード済みである。また透かしの入る位置は決まっている。この二つの透かしが入った写真から透かしのない写真を自動で合成したい。なお写真の解像度も決まっている。

方法 #

  • 透かしの位置はあらかじめ分かっているので、透かしの位置をマスクするための下記のような画像を用意する。 mask画像1
  • 写真(透かし1)と写真(透かし2)をマスク画像の位置だけ置き換える。
  • 透かし1、透かし2の両者をマスターとし上記を適用する。
  • できあがった写真のどちらか片方は透かしがなくなり、もう片方は透かしが2倍になる。
  • 出来上がった画像の平均値を計算する。
  • 透かしの色により、どちらかの平均値が小さくなる。
  • 小さいほうか、大きいほうどちらかを保存する。

実装 #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import glob, os
from PIL import Image, ImageDraw, ImageFilter, ImageChops, ImageMath, ImageStat

# 設定
dir = "PIC DIR"
mask_file = "MASK FILE DIR"
files = glob.glob(dir + "*.jpg")
no_of_files = len(files)
print(f'Number of files: {no_of_files}')

# 保存ディレクトリがなければ作成
save_dir = dir + "conv"
if not os.path.exists(save_dir):
    print('Make directory: {}'.format(save_dir))
    os.makedirs(save_dir)

# 横向き写真、縦向き写真それぞれに対してマスク画像を用意する
mask_img1 = Image.open(mask_file + "mask1.jpg").convert("L")
mask_img2 = Image.open(mask_file + "mask2.jpg").convert("L")
# 縦向き、横向きを判断し、合成写真を2種作る
# (透かしが明るいので)平均値を計算し、暗いほうを正しい写真と判断する。
for i in range(int(no_of_files / 2)):
    img1 = Image.open(files[2 * i])
    img2 = Image.open(files[2 * i + 1])
    if img1.height < img1.width:
        mask = mask_img1
    else:
        mask = mask_img2
    cnv_img1 = Image.composite(img1, img2, mask)
    cnv_img2 = Image.composite(img2, img1, mask)
    if ImageStat.Stat(cnv_img1).mean < ImageStat.Stat(cnv_img2).mean:
        img = cnv_img1
    else:
        img = cnv_img2
    save_file_name = save_dir + "/_" + str(i) + ".jpg"
    print('Save file name: {}'.format(save_file_name))
    img.save(save_file_name)
print("End of conversion")
comments powered by Disqus