2026年7月3日金曜日

BlenderアドオンBlenderChatGPTUI版の使い勝手

 Usability of the BlenderChatGPTUI Add-on


I am evaluating the usability of the BlenderChatGPTUI add-on prototype. It delivers results comparable to the web-based version of ChatGPT. Additionally, the ability to easily issue simple commands via voice input—and watch Blender react right before my eyes—makes for a very smooth and enjoyable experience.


Blenderアドオンの試作品BlenderChatGPTUI版の使い勝手を検証しています。web版ChatGPTに匹敵する成果を体験しています。また、音声入力で簡易な指示を気軽に出せて、目の前でBlenderが動くので快適です。

1 BlenderアドオンBlenderChatGPTUI版の使い勝手


BlenderアドオンBlenderChatGPTUI版の使い勝手

遺物データファイル(3D座標、42属性区分データ、55892件)をBlender3DビューポートにプロットするBlenderPythonスクリプト作成をChatGPTに指示しました。指示文は次の通りです。

「"G:/test/aaa.csv"は第1行に項目名が書いてあり、第2行以降は数値あるいは空白となっています。第1列はID、第2列~第4列はx,y,z座標、第5列以降は属性が記入されています。このファイルをBlender4.4.3の3DビューポートにID、属性を含めて点群(メッシュ)としてプロットするBlenderPythonスクリプトを作成してください。」

数秒もかからずにBlenderPythonスクリプトが生成しました。アドオンのボタンで走らせると、3Dビューポートに55892件の遺物が点群(メッシュ)でプロットされ、各点(各遺物)は多数属性情報を保持していることが確認できました。

指示文及び成果BlenderPythonスクリプトは保存して次の同様操作の参考に使えます。

2 感想

web版ChatGPTと同じように、指示文(プロンプト)を詳しく書き、あいまいさをなくすことがChatGPTのパフォーマンスを引き出すコツになります。得られる成果(BlenderPythonスクリプト)はweb版ChatGPTと遜色ありません。

3 音声入力

簡易な指示は音声入力でおこない、目の前でBlenderが動くので快適です。ある操作のショートカットを忘れた時(はじめから知らない時)などに超有効です。音声入力はWindows機能を使い、Windows+hで実現できます。

なお、このアドオン入力に限らず、パソコンで操作する全ての入力場面でこの音声入力機能は有効です。


2026年7月1日水曜日

技術メモ 遺物3D空間分析用geometry nodesの使いまわし方法

 Technical Note: Reusing Geometry Nodes for 3D Spatial Analysis of Artifacts

I have been making effective use of a Geometry Nodes setup to analyze 3D spatial data for approximately 56,000 artifacts from the shell midden on the northern slope of the Ariyoshi-Kitakaizuka Shell Mound. To enable the reuse of this setup across different Blender files, I have converted it into an asset.


有吉北貝塚北斜面貝層の遺物約56000件データを3D空間で分析するgeometry nodesを便利に使っています。このgeometry nodesを別Blenderファイルでも使えるようにアセットにして使いまわし出来るようにしました。

1 geometry nodesを使っている様子


geometry nodesを使ている様子

2 遺物3D空間分析用geometry nodesのイメージ


遺物3D空間分析用geometry nodesのイメージ

このgeometry nodesには次の機能が備わっています。

1)3D座標付遺物データの選択

このgeometry nodesでは有吉北貝塚北斜面貝層の全42属性、レコード数55892件のデータを選択してあります。

2)表示する属性の選択

属性bunruicodeを選択すれば、それは遺物台帳に紐づくデータで全遺物が1(土器)、2(石器)、…のように区分されています。

属性zinkotsuを選択すれば、それは発掘調査報告書に紐づくデータで、該当データだけ区分が1になっています。

3)表示する属性の区分の選択

属性bunruicodeの区分1は土器を、区分5は骨歯を選択します。

属性zinkotsuの区分1は発掘調査報告書掲載人骨データを選択します。

4)表現メッシュ形状の選択

vert(点[メッシュ])の他、球、立方体など好みに合わせて表現メッシュ形状を選択できます。球や立方体は大きさや色なども設定できます。

3 geometry nodesの使い勝手

geometry nodesでノード(箱)の中の区分数値を変化させるだけで、表現内容が一瞬のうちに変化しますので、とても使い勝手がよいです。

しかし、このgeometry nodesのノード(箱)を一つ一つ組み立て、ラインで結ぶのは根気のいる作業です。

4 geometry nodesの使いまわし

別のBlenderファイルでも遺物3D空間分析用geometry nodesを使いまわす方法は幾つかありますが、これまではアペンドを使ってきました。しかしアペンドは遺物3D空間分析用geometry nodesが存在するBlenderファイルから持ってくる方法なので、このgeometry nodesが存在しているBlenderファイルを探さなければなりません。意外と手間取ります。

今回geometry nodesのアセット登録してみると、とても効率的にgeometry nodesを使いまわせることを確認しました。


アセットによるgeometry nodesの使いまわし方法

アセットによるgeometry nodesの使いまし方法の概要は以下のとおりです。

1)geometry nodesのグループ化

2)グループを「アセットとしてマーク」→これでアセットが使えるようになります。(※)

3)別Blenderファイルでplane追加

4)planeに新期geometry nodes作成して、そこにアセットをドロップして、グループとグループ出力をラインで結ぶ

これで遺物3D空間分析ができるようになります。(なお、アセットをドロップすると、元遺物データとvertが自動生成します。)

※ 「アセットとしてマーク」を実行するファイルを事前に設定するアセット専用フォルダーに置いておく必要があります。

2026年6月ブログ活動のふりかえりと7月見通し

 Review of June 2026 Blog Activities and Outlook for July


I have reviewed the activities for June 2026 on the blog "Walking the Hanami River Basin" and outlined the plans for July.

At the end of May, I discovered a large-scale stratigraphic inversion within the shell midden layer on the northern slope of the Ariyoshi-Kita Shell Mound. This discovery made me realize that researching this shell midden layer is not merely an archaeological endeavor, but a geo-archaeological one that requires unraveling a complex geological phenomenon. This realization has greatly fueled my research enthusiasm and intensified my efforts to develop the fundamental 3D technologies necessary for the study.


ブログ「花見川流域を歩く」の2026年6月活動をふりかえり、7月活動を見通しました。

5月末に有吉北貝塚北斜面貝層に大規模な層位逆転現象を発見しました。これにより、北斜面貝層研究が単なる考古学研究ではなく、クセの強い地学現象の解明を伴うジオ考古学研究であることに気づかされました。研究意欲が大いに掻き立てられるとともに、研究に必要な3D基礎技術開発にも熱が入りました。

1 ブログ「花見川流域を歩く」活動と特徴

1-1 記事数

6月の記事数は35です。内訳はジオ考古学的検討記事17編、技術開発記事10編、考古学切手記事5編、その他3編です。

1-2 北斜面貝層のジオ考古学検討

層位逆転現象の発見に伴い研究意欲が刺激され、次の事柄について検討しました。

・層位的逆転現象の確認

・これまで検討してきたことの総集

・全遺物3D分布データ作成観察

・崩落層等の母材提供場所推定

・断面遺物分布ヒートマップの比較

・遺物別3D分布CT撮影動画作成観察

なお、予定していた貝層ファブリック分析は貝層断面写真が7月に入手できることになったので、それ以降に実施することとし、6月は行いませんでした。

1-3 分析技術開発

検討を深めるためには、切れ味の鋭い分析ツールが必須であることから、次の分析技術開発を行いました。

・BlenderPythonスクリプト資産の効率活用策

・自作BlenderアドオンBlenderChatGPTUI版の実装

・postgreSQL→Blender点群表示の準備

・遺物3Dデータの正本管理

・点群(メッシュ)CT撮影用BlenderPythonスクリプト作成

・pngファイルからヒートマップを作成するPythonスクリプト作成

・QGISを使った3種の疑似座標GIS解析の比較

1-4 感想

5月末に有吉北貝塚北斜面貝層に大規模な層位逆転現象を発見しました。これにより、北斜面貝層研究が単なる考古学研究ではなく、クセの強い地学現象の解明を伴うジオ考古学研究であることに気づかされました。研究意欲が大いに掻き立てられるとともに、研究に必要な3D基礎技術開発にも熱が入りました。

2 ブログ「花見川流域を歩く 自然・風景編」活動と特徴

6月の記事数は1編、早朝散歩日数は16日です。

3 2026年7月の見通し

3-1 北斜面貝層のジオ考古学検討

次の事項に取組みます。

・型式別土器情報を利用した断面間貝層対比(メイン)

・貝層ファブリック分析

・地山地形3D改良

3-2 分析技術開発

次の事項に取組みます。

・BlenderアドオンBlenderChatGPTUI版の試用と改良

・遺物3D分布データの分析技術開発改良

・postgreSQLによる正本管理システム

参考 ブログ「花見川流域を歩く」2026年6月記事 ○閲覧の多いもの


2026年6月 YouTubeに投稿した動画


2026年6月 ブログ「花見川流域を歩く」投稿記事に掲載した画像


2026年6月30日火曜日

技術メモ BlenderPythonスクリプト資産の効率活用策

 Technical Note: Strategies for Efficiently Utilizing Blender Python Script Assets


As part of an effort to efficiently utilize the library of Blender Python scripts I have built up over time, I have adopted the practice of making appropriate use of the File Browser panel within the Blender interface. This has facilitated the efficient use of existing scripts.


これまでの活動で貯めてきたBlenderPythonスクリプト資産の効率的活用策の一環としてBlender画面でファイルブラウザーパネルを適宜使うようにしました。これにより既存スクリプトの効率的活用が進んでいます。

1 Blender画面におけるファイルブラウザーパネルの設置とBlenderPythonスクリプト資産の表示


BlenderPythonスクリプト資産を表示したファイルブラウザーパネル設置Blender画面

パソコンに整理されているBlenderPythonフォルダーをブラウザパネルに表示して、BlenderPythonスクリプトを選びやすくしています。

2 Blender画面テキストエディターにおけるBlenderPythonスクリプト説明文書の表示


BlenderPythonスクリプト説明文書を表示しているBlender画面

BlenderテキストエディターはBlenderPythonスクリプトだけではなく、説明文書も表示できますから、BlenderPythonスクリプト資産活用の際にスクリプト内容についてより深く確認できます。

3 テキストエディターのBlenderPythonスクリプトを走らせた様子


テキストエディターでBlenderPythonスクリプトを走らせた画面

パソコンフォルダーに格納してあるBlenderPythonスクリプトをファイルブラウザー経由で取り出しテキストエディターで走らせることによって、エクスプローラー経由よりも効率的に作業が進みます。

4 メモ

これまでWindowsのエクスプローラーを使って既存資産を取り出し、Blenderに貼りつけていましたが、それより、ファイルブラウザーを使う方が効率的であることを実感しています。効率化実感の一因はウィンドウ数減少にあります。


自作BlenderアドオンBlenderChatGPTUI版の実装

 Implementation of "BlenderChatGPTUI": A Custom Blender Add-on


To streamline the process of generating Python scripts with ChatGPT and executing operations in Blender, I have created and begun testing a custom add-on called "BlenderChatGPTUI." My goal is to develop it into a function-calling add-on.


ChatGPTによるPythonスクリプト生成→Blender操作をより効率的に行うために、自作BlenderアドオンとしてBlenderChatGPTUI版を作成し、試用し始めました。Function Calling型アドオンを目指しています。

この記事は2026.01.22記事「ChatGPTそのものをBlenderのアドオンにする」の続きです。

1 自作BlenderアドオンBlenderChatGPTUI版

自作BlenderアドオンBlenderChatGPTUI版のパネル

2 自作BlenderアドオンBlenderChatGPTUI版の挙動


自作BlenderアドオンBlenderChatGPTUI版の挙動 1

メッセージ欄に「"G:\test\aaa.csv"を点群(メッシュ)でBlender4.4.3にインポートしてください。」を書き込みました。


自作BlenderアドオンBlenderChatGPTUI版の挙動 2

SendをクリックするとPythonスクリプトが生成されます。


自作BlenderアドオンBlenderChatGPTUI版の挙動 3

Run generated scriptをクリックすると3Dビューポートに点群(メッシュ)が生成し、アウトライナーにメッシュ名が表示されます。


自作BlenderアドオンBlenderChatGPTUI版の挙動 4

Open Chat Logをクリックするとテキストエディターにログが表示されます。

Pythonスクリプト、ログ共にテキストエディターに名称案が表示されていますので、テキストエディター機能を使って書き出すことが出来ます。

3 改善と目指す方向

ChatGPTでBlenderPythonスクリプトを作成する行為の効率化を目指してアドオンBlenderChatGPTUI版を作成しました。当面様々な実務にこのアドオンを使って、出来ること、出来ないこと、使い勝手など課題を抽出して改善します。当面はエラーが出た時や機能が実現出来なかった時の対処方法について検討、改善します。

UI版が安定したら、本命であるFunction Calling版作成に取り掛かります。最終的には考古学・実測図専用Agent型を目指します。


2026年6月28日日曜日

postgreSQL→Blender点群表示の準備とスクリプト概要

 Preparing to Display PostgreSQL Point Cloud Data in Blender: Overview of the Script


I have obtained a poster outlining the script and the preparations needed to stream data from PostgreSQL into Blender for point cloud visualization. From a technical standpoint, it looks like this could be implemented right away.


postgreSQLからデータをBlenderに流し点群表示する準備とスクリプト概要のポスターを入手しました。技術的にはすぐにでもできそうです。

1 postgreSQL→Blender点群表示の準備とスクリプト概要


postgreSQL→Blender点群表示の準備とスクリプト概要

ChatGPTに次の質問をしたところ、このポスターがかえってきました。

「postgreSQLのあるテーブルから多数レコードのID、3D座標、各種属性データをBlenderに渡して、Blender3Dビューポートに点群で表示させるとします。そのための準備と作成BlenderPythonスクリプトの概要について教えてください。その点群をgeometry nodesで絞り込みなど分析が可能となると考えてよいでしょうか。」

2 メモ

postgreSQLを単なるデータ保管場所ではなく、研究基盤として位置付け、Blenderをその基盤の上で動く3D可視化・解析フロントエンドと考えることにします。

postgreSQL操作技術の習熟を加速することにします。


遺物3Dデータの正本管理の失敗

 Failure in Managing Master 3D Artifact Data


I plotted 3D artifact data into Blender as a point cloud (or mesh) and performed a virtual CT scan using a Blender Python script. While the process worked fine with test data, it resulted in errors when using the actual production data.

I wasted about half a day investigating the cause, only to discover that the data I had treated as the "master" copy was actually an intermediate working file containing errors from before corrections were made. I realized I had failed to properly manage the master data. This experience made me keenly aware of the need for a master data management system designed to minimize the risk of such errors.


遺物3DデータをBlenderに点群(メッシュ)としてプロットして、そのCT撮影をBlenderPythonスクリプトで行いました。しかし、テストデータでは正常にできるのに、本番データではエラーになってしまいます。

半日ほどその原因追究に時間を浪費しました。結果は正本データと思って使ったデータが修正前の誤りを含む途中作業データだったのでした。正本データ管理に失敗していることに気が付きました。間違いの生まれにくい正本管理システムを作る必要性を痛感しました。

関連記事(正本データを使った記事)2026.06.26記事「Blender3D空間に分布する点群(メッシュ)のCT撮影用Pythonスクリプト

1 エラーの原因

点群(メッシュ)CT撮影用BlenderPythonスクリプトを走らせた時のエラー原因はデータ(csvファイル)の座標値に極端な異常値が含まれていたことです。


極端な異常値(Z値が桁間違いと未調整により、正常な値の約380倍になっている)


極端な異常値の可視化

1点のZ値が極端な異常値であるため、BlenderPythonスクリプトが画像枠をつくることが出来ず、エラーになりました。

2 エラー発生の重大性

このエラーそのものはデータを修正すればよいことであり、さして驚くべきことではありません。私が深刻にその重大性を感じたのは、正本データとされるもので、このようなエラーが発生したことです。1年以上前に、このデータエラーは既に気が付き、正本を訂正しているのです。それにもかかわらず正本データを使って、このエラーが発生したということは、正本管理が適切に行われていないということです。

使ったcsvファイル名称は「北斜面貝層プロット用調整」となっています。ファイル名称にいくら「調整」とか「最終」とか「正本」とか書いてもそれが本当に使えるものであるどうかはまた別問題です。

現在のデータ正本管理システムを抜本的に改善する必要を感じました。

3 データ正本管理システムの抜本的改善

現在のデータの流れは次のようになっています。

postgreSQL→csv出力→Blenderプロット用正本作成→Blender

このデータの流れを次のように変更することにします。

postgreSQL(正本)→csv出力→Blender

postgreSQLを正本とし、データ修正は全てpostgreSQLで行うことにします。出力したcsvファイルは単なるその場限りのBlender用データとします。csvファイルの格下げです。このようにすれば、正本管理が確実にできそうです。

postgreSQLが正本として完成して安定すれば、直ちにその次のシステムに移行することにします。

postgreSQL(正本)→Blender

csvファイルを経由することなく、postgreSQLから直接Blenderにデータを流すことにします。

【余談】なお、postgreSQLからQGISに直接データを流せることはQGISにpostgreSQLアイコンがあることから知っていましたので、こちらの方も同時に試してみることにします。


2026年6月27日土曜日

点群(メッシュ)CT撮影用BlenderPythonスクリプトの機能付加

 Adding Functionality to a Blender Python Script for CT-Style Imaging of Point Clouds (Meshes)


I have added a feature to a Blender Python script—designed for CT-style imaging of point clouds (meshes) distributed within the Blender 3D viewport—that allows the generated cross-sectional projections of the point cloud to be pasted directly into the Blender scene. This tool will be utilized for the 3D spatial analysis of artifacts.


Blender3Dビューポートに分布している点群(メッシュ)のCT撮影用BlenderPythonスクリプトに、生成した点群投影断面図をBlenderに貼りつける機能を追加しました。遺物3D分布分析の強力ツールとして活用します。

この記事は2026.06.26記事「Blender3D空間に分布する点群(メッシュ)のCT撮影用Pythonスクリプト」の続きです。

1 点群(メッシュ)CT撮影用BlenderPythonスクリプトの当初機能と付加機能


点群(メッシュ)CT撮影用BlenderPythonスクリプトの当初機能(点群投影断面図アウトプット)(有吉北貝塚北斜面貝層土器3D分布、2mピッチ)

点群(メッシュ)分布を指定したピッチ毎に配置された断面に投影した投影断面図を作成します。この例では2mピッチで投影断面図(pngファイル)22枚を作成して、パソコンフォルダーにアウトプットしています。


点群(メッシュ)CT撮影用BlenderPythonスクリプトの付加機能(点群投影断面図のBlender内配置)


点群(メッシュ)CT撮影用BlenderPythonスクリプトの付加機能(点群投影断面図のBlender内配置)


点群(メッシュ)CT撮影用BlenderPythonスクリプトの付加機能(点群投影断面図のBlender内配置)

作成した投影断面図をBlender3Dビューポートに配置します。これによりBlender空間の外に出て使われる投影断面図の正確な位置を知ることができるとともに、Blender空間に配置された他の情報と点群との関係理解をより一層深めることができます。

2 メモ

作成した投影断面図の位置が判るので、今回追加した機能はこのツールをより強力なものにします。

投影断面図一枚一枚に位置図を組み込むことなども可能となります。


投影断面図に位置図を組み込んだ例(イメージ)


停電によるIllustrator不調の改善策

 Fixing Illustrator Issues Caused by a Power Outage


I experienced a sudden power outage while working in Illustrator. When I resumed work after the power was restored, the screen turned completely white, making it effectively impossible to continue. After investigating the issue, I selected the "Preview on CPU" option, which resolved the problem. This was the first time I learned that there are two modes: "Preview on CPU" and "Preview on GPU."


Illustrator作業中に突然の停電がありました。停電解消後作業を再開すると画面が真っ白になる現象が生まれて事実上作業が出来ないという不調が生じました。調べて「CPUでプレビュー」をチェックしたところ不調は解消しました。「CPUでプレビュー」と「GPUでプレビュー」の2つがあることをはじめて知りました。

1 突然の停電によるIllustratorの不調

1-1 データ復元

3年ぶりくらいの珍しさだと思いますが、突然の停電がありました。Illustrator作業中でした。停電解消後パソコンを立上げ、Illustratorを開くと復元ファイルが出来ていました。作業データの保存はかなり前でしたが、それにもかかわらず作業データの欠損は感じませんでした。後で確認するとクラウドファイルの自動保存間隔が5分となっていました。自動保存されているという意識はなかったので、得をした気分になりました。

1-2 Illustrator不調

復元ファイルを操作しだすと不調に気が付きました。オブジェクトをクリック(選択)すると画面全部が真っ白になってしまいます。マウスホイールを動かすと画面真っ白は解消されますが、オブジェクト選択は出来ていません。レイヤーウィンドでレイヤを非表示にしても画面が真っ白になります。「だましだまし使う」こともできない状況です。作業が全くできません。

復元ファイルではなく、過去に作成したIllustratorファイルも同じ症状です。

パソコン再立上げやIllustratorアップデータをしても同じ症状です。

2 改善策

ChatGPTに改善策を調べてもらったところ次の策を順番に試す提案がありました。

① GPUプレビューを切る(最優先)

② Illustratorの環境設定をリセット

③ 新規ファイルでも起きるか確認

④ セーフモードでGPUを確認

⑤ グラフィックドライバを入れ直す

⑥ Illustratorを完全初期化

⑦ Windows側の異常確認

⑧ Illustrator以外は正常か

最初の「GPUプレビューを切る」を試したところ不調は嘘のように消えました。


「CPUでプレビュー」をチェックして停電不調が改善

表示→「CPUでプレビュー」と表示されている状態は「GPUでプレビュー」されている状態です。ここをクリックしたので、「GPUでプレビュー」から「CPUでプレビュー」に切り替えたのです。それで不調が解消しました。その後「GPUでプレビュー」に直しましたが不調は生じません。

結果として停電によりGPU描画系が一時的に不調になり、「CPUでプレビュー」に切り替え操作を加えることで不調は解消したようです。

3 メモ

「GPUでプレビュー」「CPUでプレビュー」という項目がIllustratorに存在することにはじめて気が付きました。過去に類似の不調を体験したことがあり、だましだまし使っているうちにいつの間にか解消しましたが、その時の不調もおそらく「CPUでプレビュー」操作を加えれば解消したに違いないと想像しました。


2026年6月26日金曜日

Blender3D空間に分布する点群(メッシュ)のCT撮影用Pythonスクリプト

 Python Script for CT-Style Imaging of Point Clouds (Meshes) in Blender 3D Space


I have created a Python script to perform CT-style imaging on point clouds (meshes) distributed within Blender's 3D space. This allows for the generation of data analogous to medical CT scans of internal organs, but applied instead to the spatial distribution of artifacts within a shell midden. This marks the creation of a prototype for a key tool in 3D spatial analysis of artifacts. Moving forward, I plan to utilize this tool in spatial analysis while refining its usability.


Blender3D空間に分布する点群(メッシュ)のCT撮影用Pythonスクリプトを作成しました。体内臓器のCT撮影と同じようなデータを貝塚貝層内遺物分布にあてはめて生成できます。遺物3D空間分析の重要ツールの一つの祖型ができたことになります。これからこのツールを3D空間分析で活用して、その使い勝手を改善していくことにします。

1 点群(メッシュ)のCT撮影用Pythonスクリプトについて

このスクリプトは、Blender3Dビューポートに分布する点群(メッシュ)について、Y軸方向に多数のXZ断面を設定し、各XZ断面に近傍の点群を投影した投影断面図を作成するBlenderPythonスクリプトです。


点群(メッシュ)のCT撮影

断面図の間隔は0.1mとか0.5mとか1mとか自由に設定できます。また画面や点の色、点の大きさも自由に設定できます。


CT撮影結果(点群投影断面図)1枚目ct_slice_0000.png


CT撮影結果(点群投影断面図)2枚目ct_slice_0001.png


CT撮影結果(点群投影断面図)3枚目ct_slice_0002.png

2 使い方

Blender3Dビューポートで選択された点群(メッシュ)についてCT撮影を行います。点群をgeometry nodesで操作してテーマに沿って絞り込んで表現されている場合でも、その絞り込んだ点群を選択すれば、それを対象にCT撮影します。

下のBlenderPythonスクリプトの設定欄を好みに設定して、点群が配置されているBlenderファイルのテクストエディターに貼りつけ、走らせます。

Blenderファイルが存在するフォルダーにct_slices名称のサブフォルダーがつくられ、点群投影断面図がその中に生成します。生成スピートは高速です。(自分のパソコンでは84枚で10秒ほどです。)

3 点群(メッシュ)のCT撮影用Pythonスクリプト


import bpy
import os
import math

# ==========================
# ユーザー設定
# ==========================
# スライス厚み (m) : Y 方向の幅
SLICE_THICKNESS = 0.1

# 出力画像の「基準横幅」(px)
# 高さはバウンディングボックスの XZ 比率を保つように自動計算されます
IMAGE_WIDTH = 1024

# 点の色 (R, G, B, A) 0.0〜1.0
POINT_COLOR = (1.0, 1.0, 0.0, 1.0)  # kiiro
# 背景色 (R, G, B, A)
BACKGROUND_COLOR = (0.027, 0.051, 0.498, 1.0)  # ao

# 何ピクセル四方に塗るか(点の大きさ)
POINT_SIZE = 2  # 1なら1ピクセルのみ,2なら3x3ピクセル,3なら5x5ピクセル相当

# 出力先ディレクトリ(.blendファイルからの相対パス)
OUTPUT_DIR = "//ct_slices"

# 対象オブジェクトを「選択中」に限定するか
# True: 3Dビューポートで選択中のメッシュだけを対象にします
# False: シーン内の表示中メッシュを対象にします
USE_SELECTED_OBJECTS_ONLY = True

# Geometry Nodes / モディファイア適用後の「ビューポート表示結果」から頂点を取るか
# Geometry Nodesで点群を絞って表示している場合は True のまま使ってください
USE_EVALUATED_VIEWPORT_MESH = True

# 非表示オブジェクトを除外するか
EXCLUDE_HIDDEN_OBJECTS = True
# ==========================



def collect_world_vertices():
    """選択中(または表示中)メッシュの頂点をワールド座標で取得。

    USE_EVALUATED_VIEWPORT_MESH=True の場合は、Geometry Nodesやモディファイア適用後の
    ビューポート評価結果から頂点を取得する。
    """
    view_layer = bpy.context.view_layer
    depsgraph = bpy.context.evaluated_depsgraph_get()

    if USE_SELECTED_OBJECTS_ONLY:
        source_objects = list(bpy.context.selected_objects)
    else:
        source_objects = list(bpy.context.scene.objects)

    objects = []
    for obj in source_objects:
        if obj.type != 'MESH':
            continue
        if EXCLUDE_HIDDEN_OBJECTS and (obj.hide_get(view_layer=view_layer) or obj.hide_viewport):
            continue
        objects.append(obj)

    print("対象オブジェクト:", ", ".join(obj.name for obj in objects) if objects else "なし")

    points = []
    for obj in objects:
        mat = obj.matrix_world

        if USE_EVALUATED_VIEWPORT_MESH:
            obj_eval = obj.evaluated_get(depsgraph)
            mesh = None
            try:
                mesh = obj_eval.to_mesh(preserve_all_data_layers=False, depsgraph=depsgraph)
                for v in mesh.vertices:
                    co_world = mat @ v.co
                    points.append((co_world.x, co_world.y, co_world.z))
            finally:
                if mesh is not None:
                    obj_eval.to_mesh_clear()
        else:
            mesh = obj.data
            for v in mesh.vertices:
                co_world = mat @ v.co
                points.append((co_world.x, co_world.y, co_world.z))

    return points


def compute_bounds(points):
    """頂点群の XYZ の最小値・最大値を返す"""
    xs = [p[0] for p in points]
    ys = [p[1] for p in points]
    zs = [p[2] for p in points]

    min_x, max_x = min(xs), max(xs)
    min_y, max_y = min(ys), max(ys)
    min_z, max_z = min(zs), max(zs)

    return (min_x, max_x, min_y, max_y, min_z, max_z)


def bucket_points_by_slice(points, min_y, max_y, thickness):
    """Y方向のスライスごとに頂点をバケツ分けしたリストを返す"""
    if max_y - min_y == 0.0:
        num_slices = 1
    else:
        num_slices = int(math.floor((max_y - min_y) / thickness)) + 1

    slices = [[] for _ in range(num_slices)]

    for (x, y, z) in points:
        idx = int((y - min_y) / thickness)
        # 安全のためクランプ
        idx = max(0, min(num_slices - 1, idx))
        slices[idx].append((x, y, z))

    return slices, num_slices


def create_blank_image(name, width, height, bg_color):
    """背景色で塗られた空画像を作成して返す"""
    img = bpy.data.images.new(name=name, width=width, height=height, alpha=True, float_buffer=True)

    # すべて背景色で初期化
    r, g, b, a = bg_color
    num_pixels = width * height
    pixels = [0.0] * (num_pixels * 4)
    for i in range(num_pixels):
        base = i * 4
        pixels[base]     = r
        pixels[base + 1] = g
        pixels[base + 2] = b
        pixels[base + 3] = a

    img.pixels = pixels
    return img


def draw_points_to_image(img, points_3d, bounds, point_color, point_size):
    """XZ平面に投影した点群を画像に描画する"""
    min_x, max_x, _, _, min_z, max_z = bounds
    width = img.size[0]
    height = img.size[1]

    # 既存のピクセルデータを「リスト」としてコピー(ここが重要)
    px = list(img.pixels)

    # XZ範囲がゼロにならないように
    range_x = max_x - min_x
    range_z = max_z - min_z
    if range_x == 0.0:
        range_x = 1.0
    if range_z == 0.0:
        range_z = 1.0

    scale_x = (width - 1) / range_x
    scale_z = (height - 1) / range_z

    pr, pg, pb, pa = point_color

    # point_size=1 のときは1ピクセルのみ、
    # 2以上のときは +-point_size ピクセルに塗る
    radius = max(0, point_size - 1)

    for (x, y, z) in points_3d:
        u = int((x - min_x) * scale_x)
        v = int((z - min_z) * scale_z)

        # 画像内に収まるチェック
        if u < 0 or u >= width or v < 0 or v >= height:
            continue

        for du in range(-radius, radius + 1):
            for dv in range(-radius, radius + 1):
                uu = u + du
                vv = v + dv
                if 0 <= uu < width and 0 <= vv < height:
                    idx = (vv * width + uu) * 4
                    px[idx]     = pr
                    px[idx + 1] = pg
                    px[idx + 2] = pb
                    px[idx + 3] = pa

    # 修正したリストを pixels に戻す
    img.pixels = px


def main():
    # 頂点収集
    points = collect_world_vertices()
    if not points:
        print("メッシュ頂点が見つかりません。対象オブジェクトを確認してください。")
        return

    # 全体バウンディングボックス
    bounds = compute_bounds(points)
    min_x, max_x, min_y, max_y, min_z, max_z = bounds
    print("Bounds X:[{}, {}], Y:[{}, {}], Z:[{}, {}]".format(min_x, max_x, min_y, max_y, min_z, max_z))

    # XZ方向の実長
    range_x = max_x - min_x
    range_z = max_z - min_z

    # 万が一ゼロにならないように
    if range_x == 0.0:
        range_x = 1.0
    if range_z == 0.0:
        range_z = 1.0

    # 横幅を基準にしてピクセルスケールを決定 (px / m)
    pixels_per_unit = IMAGE_WIDTH / range_x

    # XZ の比率をそのままに縦高さを決める
    img_width = IMAGE_WIDTH
    img_height = max(1, int(round(range_z * pixels_per_unit)))

    print(f"Image size (W x H): {img_width} x {img_height} (px)")

    # スライスごとに頂点を振り分け
    slices, num_slices = bucket_points_by_slice(points, min_y, max_y, SLICE_THICKNESS)
    print("スライス数 :", num_slices)

    # 出力ディレクトリ準備
    out_dir = bpy.path.abspath(OUTPUT_DIR)
    os.makedirs(out_dir, exist_ok=True)
    print("出力先ディレクトリ:", out_dir)

    # スライスごとに画像生成
    for i in range(num_slices):
        slice_points = slices[i]

        # スライス名
        img_name = f"ct_slice_{i:04d}"
        print(f"生成中: {img_name} (頂点数: {len(slice_points)})")

        # 空画像作成(ここで計算した img_width, img_height を使用)
        img = create_blank_image(img_name, img_width, img_height, BACKGROUND_COLOR)

        # 頂点を描画(XZ 投影)
        if slice_points:
            draw_points_to_image(img, slice_points, bounds, POINT_COLOR, POINT_SIZE)

        # PNGで保存
        filepath = os.path.join(out_dir, img_name + ".png")
        img.filepath_raw = filepath
        img.file_format = 'PNG'
        img.save()

    print("完了しました。")


if __name__ == "__main__":
    main()

有吉北貝塚北斜面貝層の骨歯3D分布CT撮影動画

 Video of 3D Bone and Tooth Distribution in the Northern Slope Shell Midden at Ariyoshi-kita Shell Midden (CT Scan)


I created a video visualizing the 3D distribution of bones and teeth (34,050 items) within the shell midden on the northern slope of the Ariyoshi-kita Shell Midden site by generating projected cross-sectional views at 0.5-meter intervals. Using a Python script, I processed CT scan data (69 frames) to produce a video with a frame interval of 0.2 seconds. I plan to compare these results with CT scan data of pottery and stone tools in the future.


有吉北貝塚北斜面貝層の骨歯3D分布(34050件)について幅0.5mスリット毎に投影断面図を作成し、動画としました。PythonスクリプトでCT撮影(コンピュータ断層撮影、69コマ)し、0.2秒間隔の動画にしたものです。今後土器や石器のCT撮影結果と比較する予定です。

この記事は2026.06.26記事「有吉北貝塚北斜面貝層の石器3D分布CT撮影動画」の続きです。

1 有吉北貝塚北斜面貝層の骨歯3D分布(34050件)


有吉北貝塚北斜面貝層の骨歯3D分布(34050件)

バウンティングボックスの大きさ:13.7m×11.7m×34.0m

2 有吉北貝塚北斜面貝層の骨歯3D分布CT撮影動画


有吉北貝塚北斜面貝層の骨歯3D分布CT撮影動画

画像の大きさ13.7m×11.7m

延長34.0m区間を0.5m幅スリット毎に土器分布投影図を作成(69コマ)し、0.2秒間隔で表示する動画。

骨歯は34050件。

3 メモ

土器、石器、骨歯のそれぞれの3D分布CT撮影画像比較は今後行う予定です。


有吉北貝塚北斜面貝層の石器3D分布CT撮影動画

Video of 3D Stone Tool Distribution in the Northern Slope Shell Midden at Ariyoshi-kita Shell Midden (CT-style Visualization)


I created a video visualizing the 3D distribution of stone tools (2,045 items) found in the northern slope shell midden at Ariyoshi-kita Shell Midden by generating projected cross-sections at 0.5-meter intervals. Using a Python script, I simulated a CT scan (computed tomography; 80 frames) to produce a video with 0.2-second intervals between frames. I plan to compare these results with CT-style visualizations of pottery, bones, and teeth in the future.


 有吉北貝塚北斜面貝層の石器3D分布(2045件)について幅0.5mスリット毎に投影断面図を作成し、動画としました。PythonスクリプトでCT撮影(コンピュータ断層撮影、80コマ)し、0.2秒間隔の動画にしたものです。今後土器や骨歯のCT撮影結果と比較する予定です。

この記事は2026.06.25記事「有吉北貝塚北斜面貝層の土器3D分布CT撮影動画」の続きです。

1 有吉北貝塚北斜面貝層の石器3D分布(2045件)


有吉北貝塚北斜面貝層の石器3D分布(2045件)

バウンティングボックスの大きさ:13.2m×21.6m×41.9m

2 有吉北貝塚北斜面貝層の石器3D分布CT撮影動画


有吉北貝塚北斜面貝層の石器3D分布CT撮影動画

画像の大きさ13.2m×21.6m

延長41.9m区間を0.5m幅スリット毎に土器分布投影図を作成(80コマ)し、0.2秒間隔で表示する動画。

石器は20145件。

3 メモ

土器、石器、骨歯のそれぞれの3D分布CT撮影画像比較は今後行いますが、土器と石器は似ています。


2026年6月25日木曜日

有吉北貝塚北斜面貝層の土器3D分布CT撮影動画

 Video of CT-style visualization showing pottery distribution in the shell midden on the north slope of the Ariyoshi-kita Shell Midden


I created a video showing the 3D distribution of pottery (17,484 items) found in the shell midden on the north slope of the Ariyoshi-kita Shell Midden by generating projected cross-sections at 0.5-meter slit intervals. Using a Python script, I simulated a CT scan (computed tomography) consisting of 85 frames to produce a video with 0.2-second intervals between frames. I intend to utilize this CT-style imaging technique as a powerful tool for analyzing the 3D distribution of artifacts in the future.


有吉北貝塚北斜面貝層の土器3D分布(17484件)について幅0.5mスリット毎に投影断面図を作成し、動画としました。PythonスクリプトでCT撮影(コンピュータ断層撮影、85コマ)し、0.2秒間隔の動画にしたものです。今後遺物の3D分布分析の有力なツールとしてCT撮影を活用します。

1 有吉北貝塚北斜面貝層の土器3D分布(17484件)


有吉北貝塚北斜面貝層の土器3D分布(17484件)

バウンティングボックスの大きさ:12.6m×22.4m×42.5m

2 有吉北貝塚北斜面貝層の土器分布CT撮影動画


有吉北貝塚北斜面貝層の土器分布CT撮影動画

画像の大きさ12.6m×22.4m

延長42.5m区間を0.5m幅スリット毎に土器分布投影図を作成(85コマ)し、0.2秒間隔で表示する動画。

土器は17484件。

3 メモ

PythonスクリプトでCT撮影(コンピュータ断層撮影、85コマ)し、0.2秒間隔の動画にしたものです。今後遺物の3D分布分析の有力なツールとしてCT撮影を活用します。


2026年6月24日水曜日

有吉北貝塚北斜面貝層のデータ総集 その2

 Comprehensive Data Collection for the Shell Midden on the Northern Slope of the Ariyoshi-Kita Shell Mound: Part 2


I examined the 3D data of the shell midden on the northern slope of the Ariyoshi-Kita Shell Mound from an overall perspective, stepping back from the fine details. I noted observations based on the differences between the 3D distributions of pottery and those of bones and teeth. I hypothesize that during the final stage of shell midden formation (the new phase of the Kasori E-II style), a large-scale collapse and a high-concentration flow occurred in the western tributary at the head of the gully, and that the resulting secondary deposits extended all the way to the downstream end.


有吉北貝塚北斜面貝層の3Dデータを、詳細から離れて、全体として眺めてみました。土器3D分布と骨歯3D分布との違いから気が付いたことをメモしました。貝層形成最終段階(加曽利EⅡ式新段階期)にガリー谷頭西支谷で大規模な崩壊、高濃度流発生があり、その二次堆積物が最下流まで及んでいると思考しています。

この記事は2026.05.26記事「有吉北貝塚北斜面貝層データの総集」の続きです。

1 遺物データ3D分布

1-1 土器3D分布


土器3D分布

土器の件数は17484です。

画像には第2断面(左)と第3断面(右)を入れたあります。(以下同様)

1-2 石器3D分布


石器3D分布

石器の件数は2045です。

石器3D分布土器3D分布と似ています。

1-3 骨歯3D分布


骨歯3D分布

骨歯の件数は34050です。

骨歯の3D分布は貝層3D分布と近似すると考えることができます。

2 土器、石器、骨歯の相互関係

2-1 土器、石器の3D分布相互関係


土器、石器の3D分布相互関係

土器3D分布画像と石器3D分布画像をPhotoshopで「ピンライト」の関係でオーバーレイした画像です。

2-2 土器、骨歯の3D分布相互関係


土器、骨歯の3D分布相互関係

土器3D分布画像と骨歯3D分布画像をPhotoshopで「ピンライト」の関係でオーバーレイした画像です。

土器3D分布はあるが骨歯3D分布がない場所、逆に骨歯3D分布はあるが土器3D分布が虚弱な場所を見つけることができます。

2-3 石器、骨歯の3D分布相互関係


石器、骨歯の3D分布相互関係

石器3D分布画像と骨歯3D分布画像をPhotoshopで「ピンライト」の関係でオーバーレイした画像です。

3 予備思考 骨歯分布(≒貝殻分布)との関係から見た土器分布区分


予備思考 骨歯分布(≒貝殻分布)との関係から見た土器分布区分

土器、骨歯の3D分布相互関係図に予備思考結果をメモしました。骨歯3D分布を貝殻3D分布に見立てて、それと土器3D分布との関係を分析し、土器分布をa~kの11に区分しました。以下思考結果をメモします。

3-1 予備思考1

a:aの土器片分布は、点線で描いたような「台地縁から投棄された結果そのもの」では「ない」と思考します。aと台地縁の間に存在した「投棄結果貝層」が規模の大きな高濃度流で下流に一気に移動したと考え、その移動プロセス結果がaに残っていると考えます。高濃度流堆積物としての土器堆積です。

このように思考する根拠の一つは第2断面層序最下部付近から北斜面貝層最新土器型式(加曽利EⅡ式新段階土器)が出土していて、大規模な高濃度流を想定せざるを得ないことです。

b:bの土器分布は台地縁からの投棄結果であると考えます。第1断面谷頭急崖直下から加曽利EⅡ式中~新段階土器が出土しているので、その頃以降に投棄された土器がメインであると考えます。

c:cの土器分布はaから継続し、fへと連なる高濃度流堆積物分布が軸となっていると考えます。

d:dの土器分布は台地縁から投棄された土器の分布を示すと考えます。

e:土器密度がdで粗でeで密である理由の一つは斜面に投棄された土器が高濃度流で斜面下部に集中しやすいことが影響していると考えます。

f:fの土器分布はcの土器分布と連続するものですが、高濃度流の特性として粒子の大きいもの(土器>貝殻)が堆積先端に集中するので、f域は貝殻が伴っていない、つまり、高濃度堆積先端域と考えます。

g:fの土器がその後の高濃度流で二次堆積したと考えます。

h:hの方がdより土器が密集しているのは、土器投棄量がhの方がdより多かったと考えます。

i:dとeの関係のように、hよりiの方が土器は密集しています。

j:j域に台地縁から土器が投棄されたと考えます。

k:i域からk域に土器が移動していますが、その営力は高濃度流ではなく、流水による可能性があると考えます。この付近の貝層に水平ラミナが存在するからです。

3-2 予備思考2

a-c-f、a-c-e-i-k:この区域は、加曽利EⅡ式新段階期における左岸側(西側)支谷谷頭部の大規模崩壊による高濃度流堆積物をメインとすると考えます。その堆積物より下位にそれより古い時期の堆積物が断片的に存在する可能性はあると考えます。

b:この付近のガリー谷頭浸食は少なくとも阿玉台式期にはあったことが判っています。。加曽利EⅡ式中~新段階期に顕著なガリー谷頭浸食があり、その直後から土器、石器、貝殻の投棄が始まったことが判っています。

d,h:ガリー侵食後の崩落層形成時から貝殻投棄が始まっています。ガリー侵食時期は少なくとも中峠式期には遡ります。それより古い時期まで遡るかどうかは情報がないので現状では判断できません。中峠式期以降加曽利EⅡ式新段階期まで貝殻や土器の投棄は継続すると考えられますが、斜面貝層の小崩落(高濃度流発生)が多発していたと考えられ、現状ではセクション図掲載分層の断面間対比は部分的にしかできていません。


2026年6月23日火曜日

考古学切手 エヴォラ・ローマ神殿

 Archaeology Stamp: The Roman Temple of Évora


I recently revisited a stamp from a collection I started around 1956—the only one in the set featuring an archaeological site—and enjoyed it all over again after 70 years. It is a stamp from Portugal (issued in 1935) depicting the Roman Temple of Évora. It brought back memories of visiting the site during a two-week trip to Spain and Portugal in 2009.


1956年頃収集した切手に1枚だけ考古学切手が含まれていたので、70年経った今、再び楽しみました。ポルトガル(1935年発行)のエヴォラ・ローマ神殿切手です。2009年スペインポルトガル2週間旅行で訪問したことを思い出しました。

1 エヴォラ・ローマ神殿 ポルトガル発行


エヴォラ・ローマ神殿 ポルトガル発行

1935年

ChatGPT説明:通称:ディアナ神殿。紀元1世紀頃のローマ帝国ルキウス・アウグストゥス帝の時代に建てられたもので、世界遺産にも登録されている歴史的遺構。


エヴォラ・ローマ神殿(2009.05撮影)


エヴォラ・ローマ神殿(2009.05撮影)

切手から、2009年スペインポルトガル2週間旅行でエヴォラ・ローマ神殿を訪問したことを思い出しました。

2 ヴィクトリア女王即位50周年記念普通切手 イギリス発行


ヴィクトリア女王即位50周年記念普通切手 イギリス発行

1887年

ChatGPT説明:この切手は当時、新聞や絵葉書の郵送用に大量に印刷・使用されたため、現在でも消印付き(使用済み)のものは非常に多く残っています。

この切手の消印は1895年8月7日と読めます。

この切手は考古学切手ではありませんが、70年前に自分が収集した切手で最も価値の高いものだと感じ、とても丁寧に保存してきたものです。わらしべ長者になった気分でした。今般ChatGPTの情報によると、希少性はあまりないようですが、愛着のある切手です。


考古学切手 ネフェルティティ胸像 その2

 Archaeology Stamps: Bust of Nefertiti (Part 2)


I enjoyed discovering another stamp featuring the bust of Nefertiti in my archaeology stamp collection. It is one of the stamps that make up a souvenir sheet titled "Egypt Under the Pharaohs," issued by Mozambique.


考古学切手マイコレクションから新たにネフェルティティ胸像切手を見つけて楽しみました。モザンビーク発行「ファラオの下のエジプト」小型シートの一枚を構成する切手です。

この記事は2026.06.10記事「考古学切手 ネフェルティティ胸像」の続きです。

1 ネフェルティティ胸像 モザンビーク発行


ネフェルティティ胸像 モザンビーク発行

2014年

ポルトガル語の説明文: 「O busto de Nefertiti foi a grande esposa real, e data para cerca de 1370 aC - 1330 aC(ネフェルティティの胸像は偉大なる王の正妃であり、紀元前1370年頃〜紀元前1330年頃のものです)」

2 「ファラオの下のエジプト」小型シート モザンビーク発行


「ファラオの下のエジプト」小型シート モザンビーク発行

2014年

ネフェルティティ胸像切手の隣の切手のChatGPT説明:太陽神アテン(天体としての太陽)の光を浴びる、ファラオ・アクエンアテン(アメンホテプ4世)と王妃ネフェルティティ、そして子供たちの姿が彫られたレリーフ。 

3 メモ

2026.06.10記事を書くときになぜこの切手を見落としたのか、自分でも不思議です。エジプト切手が4000枚(1/3が考古学切手)未整理で存在していて、それを丹念に確認することに気がとられていたようです。


第1断面谷頭部の遺物分布ヒートマップ

 Heat Map of Artifact Distribution at the Head of the Valley (Section 1)


I created a heat map showing the distribution of pottery, stone tools, and bone/tooth artifacts at the head of the valley in Section 1 of the shell midden located on the northern slope of the Ariyoshi-Kita Shell Midden. The map reveals a concentration of artifacts near the area of ​​the shell layer situated in the middle section of the stratigraphy. This distribution map provides valuable information suggesting that shells, pottery, stone tools, and bone/tooth artifacts were all discarded from the edge of the plateau down to the same location at the base of the cliff.


有吉北貝塚北斜面貝層の第1断面谷頭部の土器、石器、骨歯の分布ヒートマップを作成しました。層序中段の貝層分布域付近に遺物分布が集中しているように観察できます。この分布図は、貝殻と土器・石器・骨歯が台地面縁から崖下の同じ場所に投げ込まれたと推測できる貴重な情報です。

1 第1断面谷頭部の遺物分布ヒートマップ


第1断面谷頭部土器分布ヒートマップ


第1断面谷頭部石器分布ヒートマップ


第1断面谷頭部骨歯分布ヒートマップ


第1断面谷頭部土器石器骨歯分布ヒートマップ


参考 第1断面谷頭部貝層区分(区分は発掘調査報告書による)

2 メモ

2-1 層序中段の混土貝層付近に遺物が集中

層序中段の混土貝層分布域付近に遺物分布が集中しているように観察できます。これらの分布図は、貝殻と土器・石器・骨歯が台地面縁から崖下の同じ場所に投げ込まれたと推測できる貴重な情報です。

2-2 基底混土貝層付近に遺物がない

基底混土貝層付近に遺物がほとんど分布しません。谷頭部ができた直後は貝殻の投棄はしたけれども土器、石器、骨歯の投棄はほとんどなかったことになります。なぜそうなのか、その理由に興味が深まります。

2026年6月22日月曜日

技術メモ pngファイルからヒートマップを作成するPythonスクリプトの改良

 Technical Notes: Improvements to a Python Script for Creating Heatmaps from PNG Files


I've been using a very convenient Python script to create heatmaps from dot distribution images (transparent background PNG files). However, I encountered some issues, so I've improved it. The resulting Python script is now more robust.


ドット分布画像(背景透明pngファイル)からヒートマップを作成するPythonスクリプトをとても便利に使っています。しかし、不都合が生じたので改良しました。より堅牢なPythonスクリプトとなりました。

この記事は2026.06.03記事「技術メモ pngファイルから直接ヒートマップを作成するPythonスクリプト」の続きになります。

1 遭遇した不都合


遭遇した不都合

これまで順調にpngファイルからPythonスクリプトで直接ヒートマップを作成してきました。しかし、上記のような不都合に遭遇しました。

調べたところ、画像の透明部分にRGBの色が残っている部分が存在しているために生じた現象であることがわかりました。Pythonスクリプトは透明か否かではなく、色がある部分=点群データとして扱っているので生じた不都合です。

2 不都合の解決策

この不都合の解決策として、次の2を執りました。

1 画像透明部から色を完全に除去する新たなPythonスクリプト作成。

2 色のある透明部を間違って拾わないヒートマップ作成Pythonスクリプトの作成。

それぞれのPythonスクリプトを作成しましたが、2の新たな改良ヒートマップ作成Pythonスクリプトを使う方が作業の手間がはぶけます。ヒートマップ作成Pythonスクリプトがより堅牢となりました。

3 改良Pythonスクリプト (透明部に色が残っていても正常に作動する改良版)


from pathlib import Path

import cv2
import numpy as np
from PIL import Image
from matplotlib import cm

# =========================
# 設定
# =========================

input_path = r"G:/test/aaa.png"
output_path = r"G:/test/aaa_heatmap.png"

# 使用する単色グラデーション
# 例: "Blues", "Reds", "Greens", "Purples", "Oranges", "Greys"
color_map_name = "Reds"

# グラデーションの区分数
# 例: 5, 8, 10, 16, 32
gradient_steps = 10

# 密度計算のぼかし半径
# 大きいほど広くなめらかな密集度になる
blur_radius = 20

# 背景を透明にするか
transparent_background = False

# 点群抽出に使うアルファ閾値
# alpha > alpha_threshold のピクセルだけを点として扱う
# 0: わずかでも不透明なら点
# 10〜30: ほぼ透明なノイズを除外
alpha_threshold = 20

# ヒートマップの透明出力時、薄い密度部分を透明にする閾値
# 通常は 0.0 のままでOK
heat_alpha_threshold = 0.0

# =========================
# 処理
# =========================

input_file = Path(input_path)
if not input_file.exists():
    raise FileNotFoundError(f"画像が読み込めません: {input_path}")

# RGBAで読み込み、RGB値には依存しない
img = Image.open(input_file).convert("RGBA")
arr = np.array(img)

# アルファチャンネルだけで点群を抽出
alpha = arr[:, :, 3]
dot_mask = alpha > alpha_threshold

point_pixels = int(np.count_nonzero(dot_mask))
if point_pixels == 0:
    raise ValueError(
        "アルファ値から点を検出できませんでした。"
        f" alpha_threshold={alpha_threshold} を下げてください。"
    )

print(f"画像サイズ: {img.size[0]} x {img.size[1]}")
print(f"alpha min/max: {int(alpha.min())} / {int(alpha.max())}")
print(f"点として使うピクセル数: {point_pixels}")

# 密度画像を作成
density = dot_mask.astype(np.float32)

# ガウシアンぼかしで密集度を計算
density = cv2.GaussianBlur(
    density,
    ksize=(0, 0),
    sigmaX=blur_radius,
    sigmaY=blur_radius,
)

# 0〜1に正規化
max_density = float(density.max())
if max_density > 0:
    density = density / max_density

# グラデーションを段階化
density_step = np.floor(density * gradient_steps) / gradient_steps
density_step = np.clip(density_step, 0, 1)

# カラーマップ適用
cmap = cm.get_cmap(color_map_name)
heat_rgba = cmap(density_step)

# 0〜255へ変換
heat_img = (heat_rgba[:, :, :3] * 255).astype(np.uint8)

# 密度ゼロ部分の処理
if transparent_background:
    out_alpha = (density > heat_alpha_threshold).astype(np.uint8) * 255
    output = np.dstack([heat_img, out_alpha])
    Image.fromarray(output, mode="RGBA").save(output_path)
else:
    # 背景は白
    heat_img[density <= heat_alpha_threshold] = [255, 255, 255]
    Image.fromarray(heat_img, mode="RGB").save(output_path)

print(f"ヒートマップを書き出しました: {output_path}")

2026年6月20日土曜日

考古学切手 兵馬俑 その1

 Archaeological Stamps: Terracotta Army, Part 1


I enjoy collecting archaeological stamps featuring the Terracotta Army from my personal collection. These are four older stamps issued in 1983. They were out of stock at stamp dealers, so I acquired them through Mercari.


兵馬俑をテーマとした考古学切手をマイコレクションの中から集めて楽しんでいます。最初に1983年発行の古い切手4種です。切手商には在庫がなく、メルカリで入手しました。

1 兵馬俑 T.88.(4-1) 中国発行


兵馬俑 T.88.(4-1) 中国発行

1983年

特種切手「秦始皇帝兵馬俑(カタログ番号:T88)」の4種セットのうちの1枚

2 兵馬俑 T.88.(4-2) 中国発行


兵馬俑 T.88.(4-2) 中国発行

1983年

特種切手「秦始皇帝兵馬俑(カタログ番号:T88)」の4種セットのうちの1枚

3 兵馬俑 T.88.(4-3) 中国発行


兵馬俑 T.88.(4-3) 中国発行

1983年

特種切手「秦始皇帝兵馬俑(カタログ番号:T88)」の4種セットのうちの1枚

4 兵馬俑 T.88.(4-4) 中国発行


兵馬俑 T.88.(4-4) 中国発行

1983年

特種切手「秦始皇帝兵馬俑(カタログ番号:T88)」の4種セットのうちの1枚

5 メモ

よく見かける兵馬俑の切手であり、直ぐにでも入手できると楽観していました。しかし、どの切手商にも在庫がなく、入手をあきらめかけていました。あるとき、フト、メルカリの存在に気が付き検索したところ、格安で即入手できました。それ以来切手入手方法としてメルカリを多用するようになりました。

メルカリ販売者(過去のお土産品などの不要物処分)←→私(考古学切手として入手したい価値ある小品)という対照が面白いです。

話しは脱線しますが、古い考古学図書の入手にヤフオクを利用したことあります。縄文土器大観全4巻を、うまく立ち回り、格安で入手できた体験があります。しかし、ヤフオクを使ってみて、無意味に他の人と競うという心を磨り減らす側面があり、それ以来止めました。それに対して、メルカリは心の負担なしに価値交換できるので、よりよい仕組みです。