撮影した写真に写っている物の長さを測る
1.任意の2点の長さを参考に,
2.知りたい2点間長さを表示する
Pythonプログラムを示す.
<実行手順>
1.VSCodeを起動して,measure_length_GUI.py を作成
2.VSCodeのpowershellにて,以下のコマンドを実行
例:(base) PS C:/measure_pixel/measure_length_GUI.py
3.ダイアログボックスが表示されるので,任意の画像ファイルを選択
4.基準となる長さの定義
下の図で,右上の2点(長さが分かっている)を選択して,
VSCodeのターミナル欄に,例:100 cm と入力する.
5.測定したい長さの2点を選択
オープンされた画像の距離を知りたい2点を選択
すると,先の参考長さ100cmをベースにピクセル換算された
測定したい2点間長さが表示される.
(下図の例では,113.19cm)
measure_length_GUI.py
import cv2
import numpy as np
import tkinter as tk
from tkinter import filedialog
def select_image_file():
root = tk.Tk()
root.withdraw() # Tk ウィンドウを表示しない
file_path = filedialog.askopenfilename(
title="画像ファイルを選択してください",
filetypes=[
("画像ファイル", "*.png;*.jpg;*.jpeg;*.bmp"),
("PNG", "*.png"),
("JPEG", "*.jpg;*.jpeg"),
("BMP", "*.bmp"),
("すべてのファイル", "*.*")
]
)
return file_path
def main():
# --- 画像ファイル選択ダイアログ ---
img_path = select_image_file()
if not img_path:
print("画像が選択されませんでした")
return
img = cv2.imread(img_path)
if img is None:
print("画像が読み込めませんでした")
return
disp = img.copy()
points = []
scale = None # px → cm 換算係数
def mouse_callback(event, x, y, flags, param):
nonlocal points, disp, scale
if event == cv2.EVENT_LBUTTONDOWN:
points.append((x, y))
cv2.circle(disp, (x, y), 4, (0, 0, 255), -1)
# --- 1回目の2点:スケール測定 ---
if len(points) == 2 and scale is None:
(x1, y1), (x2, y2) = points
px_len = ((x2 - x1)**2 + (y2 - y1)**2) ** 0.5
print(f"基準寸法のピクセル長: {px_len:.2f} px")
# 実寸(cm)をユーザーに入力させる
real_cm = float(input("この長さは何 cm ですか? → "))
scale = real_cm / px_len
print(f"スケール設定完了: 1 px = {scale:.5f} cm")
cv2.line(disp, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(disp, f"{real_cm:.2f} cm",
(x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX,
0.6, (255, 255, 255), 2)
points = []
# --- 2回目の2点:長さ測定 ---
elif len(points) == 2 and scale is not None:
(x1, y1), (x2, y2) = points
px_len = ((x2 - x1)**2 + (y2 - y1)**2) ** 0.5
cm_len = px_len * scale
print(f"距離: {px_len:.2f} px → {cm_len:.2f} cm")
cv2.line(disp, (x1, y1), (x2, y2), (0, 255, 255), 2)
cv2.putText(disp, f"{cm_len:.2f} cm",
(x1, y1 - 10), cv2.FONT_HERSHEY_SIMPLEX,
0.6, (255, 255, 255), 2)
points = []
cv2.namedWindow("my_picture")
cv2.setMouseCallback("my_picture", mouse_callback)
while True:
cv2.imshow("my_picture", disp)
key = cv2.waitKey(20) & 0xFF
# ウィンドウが閉じられたら終了
if cv2.getWindowProperty("my_picture", cv2.WND_PROP_VISIBLE) < 1:
break
if key == ord('q'):
break
if key == ord('r'):
disp = img.copy()
points = []
scale = None
print("リセットしました")
cv2.destroyAllWindows()
if __name__ == "__main__":
main()
