見出し画像

【Python】2つの画像を合成して比較しやすくする ~備忘録~

業務で印刷された文字の見比べに活用する際の負担軽減とチェックミス防止のための作成したものです。
データを直接取得できれば、WinMergeなどを使えばいいのですが、業務上印刷したデータしか取得できない場合に活用しています。
個人的の備忘録ですが、どなたかご活用できることがあれば幸いです。

目的・用途:

印刷した設定値Aと印刷した設定値Bを見比べる作業の負担軽減、チェックミス防止のため作成。

動作概要:

  • 画像Aと画像Bを合成し、resultフォルダに出力します。

  • 結果画像は、画像A・Bの一致箇所は黒で出力し、Aのみの部分は赤、Bのみの箇所は青にします。

  • おまけで赤色加工済み画像A、青色加工済み画像Bもresultに出力します。

使用方法:

  1. ソースファイルと同じ階層にフォルダ『A』『B』『result』を用意する。

  2. 合成したい画像をフォルダAとフォルダBにそれぞれ格納する。
    ※ ファイル名に全角文字が含まれていると動かないので注意
    ※ ファイルの数と並びは合わせておくこと。(AとBのN個目のファイル同士を画像合成するため)

  3. プログラムを実行する。

  4. 『result』フォルダの結果を確認する。


サンプルコード:

'''
準備:
同ディレクトリ内に3つのフォルダを準備する『A』『B』『result』
AとBに比較ファイルを入れる。
実行結果はresultに格納される。
'''

import cv2
import numpy as np
import os


##■---  指定フォルダ内のPNGファイルリスト取得
def get_image_files(dir_path):
  """
  指定されたディレクトリ内のPNGとJPGファイルを取得します。

  Args:
    dir_path: ディレクトリパス

  Returns:
    ファイルパスのリスト
  """
  files = os.listdir(dir_path)
  image_files = [f for f in files if f.endswith((".png", ".jpg", ".jpeg"))]
  return image_files


##■---  
'''
処理:画像合成、比較処理メイン
'''

file_pathes = ["A", "B", "result"]
image_files_A = get_image_files(file_pathes[0])
image_files_B = get_image_files(file_pathes[1])

page = 0
for image_file_A, image_file_B in zip(image_files_A, image_files_B):
    page += 1
    print(f"ファイル選択:{image_file_A} & {image_file_B}")
    
    # 画像A、画像Bを読み込む
    img_a = cv2.imread(file_pathes[0] + "\\" + image_file_A)  #
    img_b = cv2.imread(file_pathes[1] + "\\" + image_file_B)  #
    
    # 画像のサイズを同じサイズに揃える
    img_a = cv2.resize(img_a, (img_b.shape[1], img_b.shape[0]))  #
    img_b = cv2.resize(img_b, (img_a.shape[1], img_a.shape[0]))  #
    
    # 画像Aの黒画素を赤色に変更、条件に合わない箇所は白色に変更
    mask_a = np.sum(img_a, axis=2) <= 200 * 3  # 画像img_aの各ピクセルのBGR値の合計を計算
    img_a_colored = np.zeros_like(img_a)       # 画像img_aと同じ形状、サイズ、データ型を持つ、要素すべてが0の配列を作成
    img_a_colored[mask_a] = [0, 0, 255]  # 赤色
    img_a_colored[np.logical_not(mask_a)] = [255, 255, 255]  # 白色
    cv2.imwrite(file_pathes[2] + f'\\A_{page:02}.png', img_a_colored)
    
    # 画像Bの黒画素を青色に変更、条件に合わない箇所は白色に変更
    mask_b = np.sum(img_b, axis=2) <= 200 * 3  # 画像img_bの各ピクセルのBGR値の合計を計算
    img_b_colored = np.zeros_like(img_b)       # 画像img_bと同じ形状、サイズ、データ型を持つ、要素すべてが0の配列を作成  <<--  img_bの各ピクセルのBGR値の合計が600以下かどうかを判断し、結果をmask_bというマスク画像に格納
    img_b_colored[mask_b] = [255, 0, 0]  # 青色
    img_b_colored[np.logical_not(mask_b)] = [255, 255, 255]  # 白色
    cv2.imwrite(file_pathes[2] + f'\\B_{page:02}.png', img_b_colored)  #保存
    
    # 一致する画素を紫色に変更、その他の箇所は白色のまま
    result = cv2.addWeighted(img_a_colored, 0.5, img_b_colored, 0.5, 0)  
    result[np.logical_and(mask_a, mask_b)] = [0, 0, 0]  # 緑[0, 192, 0]  紫色[255, 0, 255]
    result *= 2  # 色を強調
 
    # テキストを描画する
    cv2.putText(result, f"{image_file_A} - {image_file_B}", (10, result.shape[0] - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 0), 2)

    # 結果画像を保存
    print(f"ファイル出力:{file_pathes[2]}\\result_{page:02}.png'")
    cv2.imwrite(file_pathes[2] + f'\\result_{page:02}.png', result)

結果は以下の画像のようになります。
ただ見比べるよりは、抜け漏れ、文字の違いが認識しやすくなります。


画像A
画像B


合成結果


この記事が気に入ったらサポートをしてみませんか?