↓もし、良かったらSNSでの紹介よろしくお願いします。

OpenCV(Python)GUI基礎編、画像の拡大表示

bootstrap

画像の拡大表示

test

OpenCV GUIの基礎編、4回目です。今回はOpenCVのGUI内で画像の拡大表示をできるようにしてみました。

1回目 画像を表示
2回目 線を描く(マウス操作の解説)
3回目 ペイントツールを作ってみた(トラックバーの解説)

準備

img.jpgというファイル名で画像を用意してください。今回は下記の画像を使用して解説します。また、保存した画像と同じディレクトリでスクリプトを実行していきます。

img

画像の拡大

このスクリプトを実行するとウィンドが表示されます。右クリックで短冊領域を選択することができて、選択した領域をウィンドに拡大表示します。

# -*- coding: utf-8 -*-
import cv2
#画像を読み込む
img = cv2.imread("img.jpg")
img_win = img.copy()
rect = (0, 0, img.shape[1], img.shape[0])
#マウスの操作のコールバック関数
def callback(event, x, y, flags, param):
    global img, img_win, sx, sy, rect, abs_x, abs_y, abs_sx, abs_sy
    abs_x, abs_y = rect[0] + x, rect[1] + y
    #右クリックしたとき、拡大領域の始点を決める
    if event == cv2.EVENT_RBUTTONDOWN:
        sx, sy = x, y
        abs_sx, abs_sy = abs_x, abs_y
    #マウスの右ボタンをドラッグすると拡大領域の選択される
    if flags == cv2.EVENT_FLAG_RBUTTON:
        img_win = img.copy()[rect[1]:rect[1]+rect[3], rect[0]:rect[0] + rect[2]]
        cv2.rectangle(img_win, (sx, sy), (x, y), (0, 0, 0), 2)
    #拡大結果の出力
    if event == cv2.EVENT_RBUTTONUP:
        rect_x = min(abs_sx, abs_x)
        rect_y = min(abs_sy, abs_y)
        rect_w = abs(abs_sx - abs_x)
        rect_h = abs(abs_sy - abs_y)
        rect = (rect_x, rect_y, rect_w, rect_h)
        img_win = img.copy()[rect[1]:rect[1]+rect[3], rect[0]:rect[0] + rect[2]]
cv2.namedWindow("img", cv2.WINDOW_NORMAL)
cv2.setMouseCallback("img", callback)
while(1):
    cv2.imshow("img", img_win)
    k = cv2.waitKey(1)
    #Escキーを押すと終了
    if k == 27:
        break
    #拡大をリセット
    if k == ord("r"):
        rect = (0, 0, img.shape[1], img.shape[0])
        img_win = img.copy()

解説

def callback(event, x, y, flags, param):
    global img, img_win, sx, sy, rect, abs_x, abs_y, abs_sx, abs_sy

重要な変数の説明

  • img_winはウィンドに表示する画像です。
  • x, yウィンド内のマウスの位置です。
  • sx, syウィンド内の拡大領域の始点です。
  • rectは現在表示されている領域の位置とサイズです。
  • abs_x, abs_y画像内のマウスの位置です。
  • abs_sx, abs_sy画像内の拡大領域の始点です。

そのほかの変数(event, flags, param)は下記の記事で解説してます。

OpenCV(Python)GUIの基礎、線を描く。

    #右クリックしたとき、拡大領域の始点を決める
if event == cv2.EVENT_RBUTTONDOWN:
    sx, sy = x, y
    abs_sx, abs_sy = abs_x, abs_y

マウスの右ボタンをクリックcv2.EVENT_RBUTTONDOWNして拡大領域の始点が決まります。

    #マウスの右ボタンをドラッグすると拡大領域の選択される
if flags == cv2.EVENT_FLAG_RBUTTON:
    img_win = img.copy()[rect[1]:rect[1]+rect[3], rect[0]:rect[0] + rect[2]]
    cv2.rectangle(img_win, (sx, sy), (x, y), (0, 0, 0), 2)

cv2.rectangleは長方形を描画する関数です。ここでは、拡大領域がわかるように
正方形を描画しています。
マウスが動くたびにimg_winに現在選択中の短冊領域(rect)が示す画像を代入します。
そうすることでマウスの動きに合わせて選択領域が更新されていきます。

    #拡大結果の出力
if event == cv2.EVENT_RBUTTONUP:
    rect_x = min(abs_sx, abs_x)
    rect_y = min(abs_sy, abs_y)
    rect_w = np.clip(abs(abs_sx - abs_x), 1, img.shape[1] - rect_x)
    rect_h = np.clip(abs(abs_sy - abs_y), 1, img.shape[0] - rect_y)
    rect = (rect_x, rect_y, rect_w, rect_h)
    img_win = img.copy()[rect[1]:rect[1]+rect[3], rect[0]:rect[0] + rect[2]]

選択領域をグローバル変数に格納して、選択した短冊領域の画像がウィンドに表示されます。

    #拡大をリセット
if k == ord("r"):
    rect = (0, 0, img.shape[1], img.shape[0])
    img_win = img.copy()

‘r’を押すと拡大表示が解除されます。

追記

2017年8月14日:下記の記事で新しい機能を付けました。

  • 画面外が選択されたときに表示を調整する。
  • 画面の移動ができるようにする。


zoom2
OpenCV(Python)GUI基礎編、画像の拡大表示2