import cv2
import numpy as np
# --------------------------------------------------- #
# 画像合成 #
# --------------------------------------------------- #
def ImageComposition(img2, result):
img3 = cv2.cvtColor(img2,cv2.COLOR_BGR2GRAY) # グレースケール化
img3 = cv2.cvtColor(img3,cv2.COLOR_GRAY2BGR) # グレースケールのままカラー画像にする
# コントラスト、明るさを変更する。
img3 = adjust(img3, alpha=0.25)
add = cv2.add(img3, result) # 画像を合成する
return add
# α はゲイン (gain) 、βはバイアス (bias)
def adjust(img, alpha=1.0, beta=0.0):
# 積和演算を行う。
dst = alpha * img + beta
# [0, 255] でクリップし、uint8 型にする。
return np.clip(dst, 0, 255).astype(np.uint8)
def FitImageSize_small(img1, img2):
# height
if img1.shape[0] > img2.shape[0]:
height = img2.shape[0]
width = img1.shape[1]
img1 = img1[:height,:width] # ゼロ点合わせで大きい方の画像の下をカット
else:
height = img1.shape[0]
width = img2.shape[1]
img2 = img2[:height,:width]
# width
if img1.shape[1] > img2.shape[1]:
height = img1.shape[0]
width = img2.shape[1]
img1 = img1[:height,:width] # ゼロ点合わせで大きい方の画像の右をカット
else:
height = img2.shape[0]
width = img1.shape[1]
img2 = img2[:height,:width]
return img1, img2
try:
# === 画像位置合わせを実施 ===
# 使う画像は「サイゼリヤの間違い探し」: https://www.saizeriya.co.jp/entertainment/
# 参照: https://qiita.com/suuungwoo/items/9598cbac5adf5d5f858e
# https://qiita.com/h-yanai/items/1e33fd93e5cb1ac98398?utm_campaign=popular_items&utm_medium=feed&utm_source=popular_items
float_img = cv2.imread('img/zeria1.jpg')
ref_img = cv2.imread('img/zeria2.jpg')
akaze = cv2.AKAZE_create()
float_kp, float_des = akaze.detectAndCompute(float_img, None)
ref_kp, ref_des = akaze.detectAndCompute(ref_img, None)
bf = cv2.BFMatcher()
matches = bf.knnMatch(float_des, ref_des, k=2)
good_matches = []
for m, n in matches:
if m.distance < 0.75 * n.distance:
good_matches.append([m])
# 適切なキーポイントを選択
ref_matched_kpts = np.float32(
[float_kp[m[0].queryIdx].pt for m in good_matches]).reshape(-1, 1, 2)
sensed_matched_kpts = np.float32(
[ref_kp[m[0].trainIdx].pt for m in good_matches]).reshape(-1, 1, 2)
# ホモグラフィを計算
H, status = cv2.findHomography(
ref_matched_kpts, sensed_matched_kpts, cv2.RANSAC, 5.0)
# 画像を変換
warped_image = cv2.warpPerspective(
float_img, H, (float_img.shape[1], float_img.shape[0]))
#cv2.imwrite('warped.jpg', warped_image) # 確認用:変換後の画像を保存
# ==== ここから、間違い探し部分 ====
img_diffs = []
paddings = []
for padding in range(1, 50):
img1 = warped_image
img2 = ref_img
# 画像サイズを合わせる(小さい方に)
img1, img2 = FitImageSize_small(img1, img2)
# 2つの画像の差分を算出
img_diff = cv2.absdiff(img2, img1)
img_diff_sum = np.sum(img_diff)
img_diffs.append((img_diff, img_diff_sum))
paddings.append(padding)
# 差分が最も少ないものを選ぶ
img_diff, _ = min(img_diffs, key=lambda x: x[1])
index = img_diffs.index(min(img_diffs, key=lambda x: x[1]))
cv2.imshow("img_diff", img_diff)
cv2.imwrite('img_diff.jpg', img_diff)
padding = paddings[index]
img1 = float_img
img2 = ref_img
cv2.imshow("img1",img1)
cv2.imshow("img2",img2)
# 画像サイズを合わせる(小さい方に)
img2, img_diff = FitImageSize_small(img2, img_diff)
# 画像合成
add = ImageComposition(img2, img_diff)
cv2.imshow("add",add)
cv2.imwrite('img_diff_add.jpg', add)
cv2.waitKey(0)
cv2.destroyAllWindows()
except:
import sys
print("Error:", sys.exc_info()[0])
print(sys.exc_info()[1])
import traceback
print(traceback.format_tb(sys.exc_info()[2]))
最近のコメント