お役立ち

Python(OpenCV)同じウィンドウに画像を重ねて表示する

  • このエントリーをはてなブックマークに追加

今回やること

画像1に画像2を重ねて表示する。
画像1

background

画像2

foreground

結果のイメージ

result

簡単なサンプルコード

# -*- coding: utf-8 -*-
import cv2
#画像の上に画像を置く関数、x,yで書き込む位置を指定する
def clip_image(x, y):
    global back
    h, w, _ = fore.shape
    back[y:y+h, x:x+w] = fore
#前景画像の読み込み
fore = cv2.imread("foreground.jpg")
#背景画像の読み込み
back = cv2.imread("background.jpg")
#左から400ピクセル上から50ピクセルのところに描画
clip_image(400, 50)
cv2.imshow("result", back)
cv2.waitKey(-1)

境界値の判定を加える

上記のclip_image関数だと画像がはみ出した場合、エラーが出てしまいます。そこで境界地の判定を加えます。

def clip_image(x, y):
    global back
    b_h, b_w, _ = back.shape
    f_h, f_w, _ = fore.shape
    f_w = min(f_w, b_w - x)
    f_h = min(f_h, b_h - y)
    s_x = min(max(-x,0), f_w)
    s_y = min(max(-y,0), f_h)
    back[max(y,0):y + f_h, max(x,0):x + f_w] = fore[s_y:s_y + f_h, s_x:s_x + f_w]

マウスで画像を動かす

# -*- coding: utf-8 -*-
import cv2
#画像の上に画像を置く関数、x,yで書き込む位置を指定する
def clip_image(x, y):
    global result, f_x, f_y, f_w, f_h
    f_x, f_y = x, y
    b_h, b_w, _ = back.shape
    f_h, f_w, _ = fore.shape
    f_w = min(f_w, b_w - x)
    f_h = min(f_h, b_h - y)
    s_x = min(max(-x,0), f_w)
    s_y = min(max(-y,0), f_h)
    result = back.copy()
    result[max(y,0):y + f_h, max(x,0):x + f_w] = fore[s_y:s_y + f_h, s_x:s_x + f_w]
#マウスの操作のコールバック関数
def callback(event, x, y, flags, param):
    global mouse_sx, mouse_sy, f_sx, f_sy, on_img_click
    #左クリックしたら移動の始点を決定
    if event == cv2.EVENT_LBUTTONDOWN:
        if f_x < x and x < f_x + f_w and f_y < y and y < f_y + f_h:
            on_img_click = True
            f_sx, f_sy = f_x, f_y
            mouse_sx, mouse_sy = x, y
        else:
            on_img_click = False
    #マウスの動きに合わせて画像を移動
    if on_img_click and flags == cv2.EVENT_FLAG_LBUTTON:
        clip_image(f_sx + x - mouse_sx, f_sy + y - mouse_sy)
on_img_click = False
cv2.namedWindow("result", cv2.WINDOW_NORMAL)
cv2.setMouseCallback("result", callback)
#前景画像の読み込み
fore = cv2.imread("foreground.jpg")
#背景画像の読み込み
back = cv2.imread("background.jpg")
#左から400ピクセル上から50ピクセルのところに描画
clip_image(400, 50)
while(1):
    k = cv2.waitKey(1)
    #Escキーを押すと終了
    if k == 27:
        break
    #sを押すと画像を保存
    if k == ord("s"):
        cv2.imwrite("result.jpg", result)
    cv2.imshow("result", result)
  • このエントリーをはてなブックマークに追加