LoginSignup
2
5

[Python]マウスドラッグで範囲指定→座標取得→画像の切り抜き

Posted at
import tkinter
import time
import pyautogui
from PIL import Image, ImageTk
import numpy as np
resize_ratio = 4  # 縮小倍率の指定


# ドラッグ開始した時のイベント - - - - - - - - - - - - - - - - - - - - - - - - - -
def get_start_point(event):
    global x1, y1, i, rect

    i += 1
    rect = (f'rect{i}')

    # canvas1上に四角形を描画
    canvas1.create_rectangle(event.x,
                             event.y,
                             event.x + 1,
                             event.y + 1,
                             outline="red",
                             tag=rect)

    # グローバル変数に座標を格納
    x1, y1 = event.x, event.y


# ドラッグ中のイベント - - - - - - - - - - - - - - - - - - - - - - - - - -
def draw_rectangle(event):

    # ドラッグ中のマウスポインタが領域外に出た時の処理
    if event.x < 0:
        x2 = 0
    else:
        x2 = min(img_resized.width, event.x)

    if event.y < 0:
        y2 = 0
    else:
        y2 = min(img_resized.height, event.y)

    # "rect"タグの画像を再描画
    canvas1.coords(rect, x1, y1, x2, y2)


# ドラッグを離したときのイベント - - - - - - - - - - - - - - - - - - - - - - - - - -
def release_action(event):

    global coordinates

    # "rect1"タグの画像の座標を元の縮尺に戻して取得
    x1, y1, x2, y2 = [
        int(n * resize_ratio) for n in canvas1.coords(rect)
    ]

    # 取得した座標を表示
    pyautogui.alert("x1 : " + str(x1) + "\n" + "y1 : " + str(y1) + "\n" +
                    "x2 : " + str(x2) + "\n" + "y2 : " + str(y2) +
                    "\n" + "i : " + str(i))

    coord = [x1, y1, x2, y2]
    coordinates.append(coord)


# メイン処理 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

i = 0
coordinates = []

# 表示する画像の取得(スクリーンショット)
img = Image.open("./pic.jpg")
# 画像をリサイズ
img_resized = img.resize(size=(int(img.width / resize_ratio),
                               int(img.height / resize_ratio)),
                         resample=Image.BILINEAR)

root = tkinter.Tk()
root.attributes("-topmost", True)  # tkinterウィンドウを常に最前面に表示

# tkinterで表示できるように画像変換
img_tk = ImageTk.PhotoImage(img_resized)

# Canvasウィジェットの描画
canvas1 = tkinter.Canvas(root,
                         bg="black",
                         width=img_resized.width,
                         height=img_resized.height)

# Canvasウィジェットに取得した画像を描画
canvas1.create_image(0, 0, image=img_tk, anchor=tkinter.NW)

# Canvasウィジェットを配置し、各種イベントを設定
canvas1.pack()
canvas1.bind("<ButtonPress-1>", get_start_point)
canvas1.bind("<Button1-Motion>", draw_rectangle)
canvas1.bind("<ButtonRelease-1>", release_action)

root.mainloop()

np_coordinates = np.array(coordinates).astype('int')
np.savetxt('./coordinates.txt', np_coordinates)
import cv2
import numpy as np
path = "./pic.jpg"
before_img = cv2.imread(path)
img = cv2.cvtColor(before_img, cv2.COLOR_BGR2RGB)


#座標の取得
coordinates = np.loadtxt('./coordinates.txt').astype('int')

#繰り返し回数=行の数を取得
n, _ = coordinates.shape

for i in range(n):
    cropped = img[coordinates[i, 1]:coordinates[i, 3], coordinates[i, 0]:coordinates[i, 2]]
    rgb = cv2.cvtColor(cropped, cv2.COLOR_BGR2RGB)
    cv2.imwrite(f'./fig/{str(i).zfill(2)}.png',rgb)
2
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
5