1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

画像ファイルのXY座標を取得する(1個の場合)

1
Last updated at Posted at 2025-07-04

概要

車の展示会場での人流データの分析時、あまりにお化けデータが多いので(人じゃなくて看板のキラキラを拾ったりしてる)そのままでは使えない。
まず最初に車の位置にたまってるデータを除外するために、車の座標内のお化けをサクッと消すことにしました。

ここでは座標の取得方法を紹介します(とりあえず1個の場合から)

image.png

概要

python3.x
jupyter lab

画像の準備

使用する画像はパイソンファイルと同じ場所に置きます
また、画像サイズは1380×840 にしました

image.png

コード

import cv2
import subprocess

#=============================================
# 画像名指定 1380×840
#=============================================
in_a = "aa.png"

#---ポチポチ数(画像の形によって変更します
kazu = 16

#=============================================
# ポインタ等の細かい指定とか
#=============================================
def onMouse(event, x, y, flag, params):
    raw_img = params["img"]
    wname = params["wname"]
    point_list = params["point_list"]
    point_num = params["point_num"]
    
    # 左クリックでポイント追加
    if event == cv2.EVENT_LBUTTONDOWN:
        if len(point_list) < point_num:
            point_list.append([x, y])
              
    # 右クリックでポイント削除
    if event == cv2.EVENT_RBUTTONDOWN:
        if len(point_list) > 0:
            point_list.pop(-1)
    
    # 画像描画
    img = raw_img.copy()
    h, w = img.shape[0], img.shape[1]
    cv2.line(img, (x, 0), (x, h), (255, 0, 0), 1)
    cv2.line(img, (0, y), (w, y), (255, 0, 0), 1)

    # 点と線の描画
    for i in range(len(point_list)):
        cv2.circle(img, (point_list[i][0], point_list[i][1]), 3, (0, 0, 255), 3)
        if i > 0:
            cv2.line(
                img,
                (point_list[i][0], point_list[i][1]),
                (point_list[i - 1][0], point_list[i - 1][1]),
                (0, 255, 0),
                2,
            )
        if i == point_num - 1:
            cv2.line(
                img,
                (point_list[i][0], point_list[i][1]),
                (point_list[0][0], point_list[0][1]),
                (0, 255, 0),
                2,
            )

    if 0 < len(point_list) < point_num:
        cv2.line(
            img,
            (x, y),
            (point_list[-1][0], point_list[-1][1]),
            (0, 255, 0),
            2,
        )

    # 座標表示
    cv2.putText(
        img,
        "({0}, {1})".format(x, y),
        (0, 20),
        cv2.FONT_HERSHEY_PLAIN,
        1,
        (255, 255, 255),
        1,
        cv2.LINE_AA,
    )

    cv2.imshow(wname, img)

#=============================================
# 取得した情報を保存
#=============================================
def save_point_list(path, point_list):
    with open(path, "w") as f:
        for p in point_list:
            f.write(f"{p[0]},{p[1]}\n")

#=============================================
# 画像の上にポチポチしていく
#============================================
def main():
    # 画像読み込み
    img = cv2.imread(in_a)
    if img is None:
        print("画像が読み込めません。パスを確認してください。")
        return

    wname = "MouseEvent"
    point_list = []
    point_num = kazu

    params = {
        "img": img,
        "wname": wname,
        "point_list": point_list,
        "point_num": point_num,
    }

    cv2.namedWindow(wname)
    cv2.setMouseCallback(wname, onMouse, params)
    cv2.imshow(wname, img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

    if len(point_list) == point_num:
        txt_path ="points.csv"
        save_point_list(txt_path, point_list)
        print("Saved csv file:", txt_path)

if __name__ == "__main__":
    main()

# エクセルで開く
EXCEL = r"points.csv"
subprocess.Popen(["start", EXCEL], shell=True)

実行すると画像が表示されるので、指定した個数分(kazu)マウスでポチポチして

image.png

右上の✖を押して画像を閉じると
image.png

座標が書き込まれたpoints.csvが起動
A列:x、B列:y
image.png

まとめ

ちょっと失敗だったと思うところは、
points.csvを開いたまま処理すると書き込みが出来ずエラーなること

自分だけが使ってたので、まあいっか~と放置してました

複数の画像を連続で定義する場合、A列は識別Noを入れてます。
連続については、また別途紹介します。

image.png

おまけ

すぐにXY座標が知りたい場合

#=============================================
# 画像の上にポチポチしていくと、座標値が表示される
#============================================
import cv2

def onMouse(event, x, y, flags, param):
    if event == cv2.EVENT_LBUTTONDOWN:
        print(x, y)

img = cv2.imread('aa.png')
cv2.imshow('aa', img)
cv2.setMouseCallback('aa', onMouse)
cv2.waitKey(0)
cv2.destroyAllWindows()

こんな感じで表示されます
image.png

1
1
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
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?