2024年12月24日火曜日

XYZ座標値付ランダム点群データ作成アプリの開発

 Development of an app to create random point cloud data with XYZ coordinate values


With the support of ChatGPT, I developed an app (Python script) to create random point cloud data with XYZ coordinate values ​​to create a 3D model of the terrain from the rock mass topography map of the shell layer on the north slope of the Ariyoshi Kita Kaizuka. This is expected to greatly improve the efficiency of point cloud data creation work.


有吉北貝塚北斜面貝層の地山地形図から地形3Dモデル作成のための、XYZ座標値付ランダム点群データ作成アプリ(Pythonスクリプト)をChatGPTの支援を受けて開発しました。点群データ作成作業の大幅な効率化が見込まれます。

1 XYZ座標値付ランダム点群データ作成アプリ(Pythonスクリプト)

import matplotlib.pyplot as plt
import matplotlib.image as mpimg
import csv
from matplotlib.widgets import TextBox

# 初期化
corner_points = []  # a(0,0)とb(1,1)の座標を格納
xyz_data = []  # クリックで取得したXYZデータを格納
current_point = None  # 現在の入力対象の点

# 画像ファイルのパス
image_path = "your_image_path_here.png"  # 適切な画像パスに変更

# 画像を読み込む
img = mpimg.imread(image_path)

# クリックイベントの処理
def on_click(event):
    global corner_points, xyz_data, current_point

    if event.inaxes is not None and event.inaxes != axbox:  # テキストボックスのクリックを無視
        x, y = event.xdata, event.ydata

        # 最初にa(0,0)とb(1,1)の角座標を取得
        if len(corner_points) < 2:
            corner_points.append((x, y))
            print(f"Corner point {len(corner_points)}: ({x:.2f}, {y:.2f})")

            if len(corner_points) == 2:
                print("Corners set! You can now start adding points.")
        else:
            # 入力範囲を0-1に正規化
            x_norm = (x - corner_points[0][0]) / (corner_points[1][0] - corner_points[0][0])
            y_norm = (y - corner_points[0][1]) / (corner_points[1][1] - corner_points[0][1])

            # 点を記録し、Z値入力を待つ
            current_point = (x_norm, y_norm)
            print(f"Point clicked: ({x_norm:.2f}, {y_norm:.2f}). Enter Z value in the text box.")

# Z値の入力イベント
def submit_z(text):
    global xyz_data, current_point

    if current_point is not None:
        try:
            z = float(text)
            xyz_data.append((*current_point, z))
            print(f"Point added: ({current_point[0]:.2f}, {current_point[1]:.2f}, {z})")

            # 赤丸を表示
            x_pixel = current_point[0] * (corner_points[1][0] - corner_points[0][0]) + corner_points[0][0]
            y_pixel = current_point[1] * (corner_points[1][1] - corner_points[0][1]) + corner_points[0][1]
            ax.plot(x_pixel, y_pixel, 'ro')
            plt.draw()
        except ValueError:
            print("Invalid Z value. Please enter a numeric value.")
        finally:
            current_point = None

# CSV出力
def save_to_csv(file_name):
    with open(file_name, mode='w', newline='') as file:
        writer = csv.writer(file)
        writer.writerow(["X", "Y", "Z"])
        writer.writerows(xyz_data)
    print(f"Data saved to {file_name}")

# 画像を表示
fig, ax = plt.subplots()
ax.imshow(img)
ax.set_title("Click to set corners and points")

# テキストボックスを作成
axbox = plt.axes([0.2, 0.01, 0.6, 0.05])  # テキストボックスの位置とサイズ
text_box = TextBox(axbox, "Z value:")
text_box.on_submit(submit_z)

# イベントの登録
fig.canvas.mpl_connect('button_press_event', on_click)

plt.show()  # 非ブロッキングで表示

# CSVファイルに保存
csv_file_name = "output_xyz_data.csv"
save_to_csv(csv_file_name)
XYZ座標値付ランダム点群データ作成アプリ(Pythonスクリプト)

38年前に作成された手書き地山地形図におけるグリッド内標高点表示からグリッド毎にXYZ座標値付き点群データを作成するアプリ(Pythonスクリプト)をChatGPTの支援を受けて開発しました。

2 アプリ操作イメージ


アプリを使ったXYZ座標値付き点群データ作成風景

操作イメージ

・グリッド別地山地形図画像を所定のフォルダーに配置

・Pythonスクリプト起動

・グリッド四角左上(a)クリック、右下(b)クリック→aを(0,0)、bを(1,1)として設定していて、以後クリックした場所を0-1の範囲で正規化できるようにしている。(注意:通常はグリッド四角左下(a)クリック→右上(b)クリックで使う。※)

・点クリック、標高は画面で手入力→赤丸が表示されデータ作成がチェックされる。

・点クリックを継続する。

・エンターキー押下→画像画面終了→データがcsvファイル出力

※ グリッド四角左上(a)クリック→右下(b)クリックで使ったのは自分の特殊な状況に対応するためです。このアプリを使う場合は一般にグリッド四角左下(a)クリック→右上(b)クリックで使えば、aが(0,0)、bが(1,1)として設定されます。

3 アプリで作成したデータの活用

csvファイル(XYZ座標ファイル)を使って、グリッド内ローカル座標から北斜面貝層全体の座標に変換したり、観測値を標高値に変換したりの作業を別途行います。

その後、グリッド別データを集成して、集成データからQGIS(GRASSプラグインv.surf.rstツール)を使って地山地形3Dモデルを作成します。

手作業によるXYZ座標付点群データ作成の大幅な効率化が見込まれます。

4 メモ

この作業を効率的に行う方法を最初にChatGPTに聞いたところ、次の5つの方法提案と手順説明、メリット・デメリット説明があり、方法3の推奨がありました。

1. 専用CADソフトまたは点群処理ソフトを使用する方法

必要なツール: AutoCAD, Rhino, QGIS などのソフトウェア。

2. グラフィックツール+スプレッドシートを利用する方法

必要なツール: GIMP, Photoshop, Excel, Google Sheets。

3. カスタムクリック入力用のPythonアプリを作成

必要なツール: Python, matplotlib(点のクリック取得用)。

4. GISソフトと手動入力の併用

必要なツール: QGIS, ArcGIS。

5. タブレットとスタイラスを活用したデジタル手書き

必要なツール: タブレットデバイス(iPad+GoodNotesやNotabilityなど)。

これらの方法を比較して、自身の目的やスキルに最も合った方法を選択してください。また、方法3(Pythonスクリプト)はカスタマイズ性が高く、効率化が見込めるためおすすめです。必要であればスクリプト作成のお手伝いも可能です!

検討の結果、ChatGPT推奨が自分の特性(所持ツールや能力等)に一番ふさわしいと感じ、作業仕様をChatGPTに指示してPythonスクリプトを作成しました。

ChatGPT指示は次の通りです。

●ChatGPT指示

四角の枠とその中に多数点とその標高が書かれた手書き画像があります。四角の左上座標aは(0,0)、右下座標bは(1,1)です。この画像をパソコンに表示し、aとbをクリックして座標を認知し、その後点をクリックしてXY座標を取得し、同時にクリックした場所に赤丸を表示します。コンソールでその点のZ座標を手入力して、点のXYZ座標を取得します。多数点のXYZ座標データはcsvファイルで出力するPythonスクリプトを教えてください。

不具合修正と使い勝手向上を5回繰り返し、満足できるPythonスクリプトに到達しました。


0 件のコメント:

コメントを投稿