Fullseye(作業名 imgevolve)を最短で動かすためのガイドです。インストール → 最初のパイプラインを作る → 実行する → 結果を見る の順に、詰まらない導線で進めます。より詳しい環境構築は INSTALL.md、Studio の全機能は STUDIO_GUIDE.md、コードからの実行は ENGINE.md を参照してください。
Fullseye は numpy 配列を入力・出力とする画像処理オペレータ・ライブラリであり、その上に HDevelop 風のビジュアル・パイプライン設計環境(Fullseye Studio) と 実行ランタイム(FullseyeEngine) が載っています。HALCON/HDevelop で言えば「HDevelop で手順を組み、HDevEngine で自分のアプリから呼ぶ」という 2 段構えを、そのまま Python + numpy で再現したものです。
前提: Python 3.11(Windows は py -3.11、Linux は python3.11)。
cd <path-to-fullseye>
py -3.11 -m pip install -e . # numpy + scipy のコアだけ(約 521 オペレータ)
コアは numpy と scipy だけで動きます。OpenCV / scikit-image / Pillow などの追加バックエンドは任意で、入っていなくても、そのバックエンド固有のオペレータだけが無効になるだけです(graceful degradation)。実務では最低でも画像ファイルの読み書きに OpenCV か Pillow が要るので、次のどちらかを足しておくと快適です。
py -3.11 -m pip install -e ".[opencv]" # 画像 I/O + OpenCV 由来オペレータ
py -3.11 -m pip install -e ".[all]" # 全バックエンド(opencv, skimage, pil, wavelets, gpu, extra)
py -3.11 -m pip install -e ".[gui]" # Fullseye Studio(PySide6)を使うなら
extras の一覧と意味は INSTALL.md にまとめてあります。GUI を使うなら [gui](または [all] + [gui])が必要です。
インストールせずに試すこともできます。リポジトリ直下(
<path-to-fullseye>)を作業ディレクトリにし、環境変数PYTHONPATHにそのパスを通せばimport fullseyeは動きます。ただしfullseye/fullseye-studioというコマンド(コンソールスクリプト)はpip install -e .を実行して初めて使えるようになります。
import fullseye, numpy as np
frame = np.clip(np.random.default_rng(0).random((64, 64)), 0, 1) # gray H×W in [0,1]
edges = fullseye.apply(frame, "sobel_amp") # image → image(勾配強度)
seg = fullseye.apply(frame, "otsu") # image → region(0/1 の二値)
n = fullseye.apply(seg, "count_obj") # region → feature(オブジェクト数=Python float)
print(n) # 例: 316.0
引数の順は
apply(image, name, a, b)— 第 1 引数が配列、第 2 引数が op 名です。逆に渡すと 0.1.9 からはTypeError: ... arguments look swappedで止まります(0.1.8 までは numpy の 「truth value of an array is ambiguous」という無関係なエラーになっていました)。a/bは 0..1 の有限値。文字列・None・NaN は即TypeError/ValueError、範囲外は切り詰めて台帳に記録されます。
apply(image, name, a=0.5, b=0.5) は 1 個のオペレータを適用します。name は オペレータ名(例 gaussian)でも HALCON エイリアス(例 gauss_filter)でも解決されます。a、b は各オペレータが持つ 2 つのつまみ(0.0〜1.0)。意味はオペレータごとに異なります(半径・しきい値・σ など)。image(gray)/ region(二値)/ feature(スカラ float)/ color(RGB)/ contour(XLD)/ volume(3D)。on_error="fallback" では、op が内部で失敗しても型に合った無害な値(画像なら入力のコピー等)が返り、同じ op につき 1 回だけ FullseyeFallbackWarning が出ます。何が何回フォールバックしたかは fullseye.fallbacks() / fullseye.fallback_counts() で確認できます。on_error="raise" を渡す(または環境変数 FULLSEYE_ON_ERROR=raise)と fail-closed になり、op の本当の例外・dtype の契約違反(整数/bool 画像)・GPU カーネルの失敗がそのまま送出されます。sort の不一致は部分的にしか検査されません(例: RGB (H,W,3) を 2-D op に渡すと体積として処理され、raise でも例外になりません — docs/KNOWN_ISSUES.md #32-4)。CI や検証では raise を推奨します。add_image / union2 など、list_ops() で tier == "nary")は 入力をリストで渡します: fullseye.apply([img1, img2], "add_image")。ncc_locate / shape_locate)は template= で探す画像を渡します: corr, row, col = fullseye.apply(img, "ncc_locate", template=patch)(戻り値の row/col は一致位置の中心)。テンプレート無しでは no-match の [0, 0, 0] が返ります。どんなオペレータがあるかは次で探せます。
fullseye.op_names() # 全レジストリ・オペレータ名(860 個、2026-09-03 時点)
fullseye.list_ops(search="edge") # 名前 / HALCON 名 / カテゴリを部分一致で検索
fullseye.list_ops(sort="region") # 入力 sort で絞り込み
fullseye.categories() # 47 カテゴリ
複数のオペレータを順に通すのが「パイプライン」です。配列を各段にスレッドして最終結果を返します。
# 全段で同じ a, b を使う(CLI と同じ形)
out = fullseye.run_pipeline(frame, ["gaussian", "sobel_amp", "otsu"])
# 段ごとに違うつまみを使いたいとき((name, a, b) のタプルで指定)
out = fullseye.run_pipeline(frame, [("gaussian", 0.3, 0.5), ("otsu", 0.4, 0.5)])
これは「smooth(平滑化)→ エッジ強度 → Otsu 二値化」で、画像から二値のエッジマップを作る典型例です。すぐ使える組み合わせ(レシピ)は 20 個同梱されています。
import recipes
recipes.names() # レシピ名の一覧
stages = recipes.stages("Edge — Sobel + Otsu") # [(op, a, b), ...]
out = fullseye.run_pipeline(frame, stages)
コードを書かずに、オペレータを検索して並べ、つまみをスライダーで回し、1 段ずつ実行して途中結果を目で見ながら組めます。GUI extras(pip install -e ".[gui]" = PySide6)が必要です。
py -3.11 studio.py # または、インストール済みなら: fullseye-studio
3 パネル構成です。
op (a, b) の 1 行を書き込みます(値は repr の全精度。Program に未適用の手編集があるときは行だけを挿入し、Apply で反映)。param_specs.py)があるものは実際の単位で操作できます — gaussian なら σ を px で(スライダー + 単位付きスピン)、median なら核サイズを 3/5/7/9 のコンボで、reg_erode なら反復回数を整数スピンで、aug_barrel の b は「pincushion」チェックボックスで。右端の 0..1 スピンは常に生の値(正確な入力用)。仕様は ops.py の変換式(0.3 + 2.7·a など)から手書きし、テストで実装と突き合わせています(tests/test_studio_params.py)。仕様の無い op は従来どおり 0..1 のスライダー 2 本。段の一覧も表示単位で書かれます(gaussian (blur σ=1.08 px, b=–))。Reset(Home)→ Step(Ctrl+→)→ Run all(Ctrl+Enter) で 1 段ずつ、または一気に実行。組んだパイプラインは Export(Ctrl+E) で --ops 文字列や Python コードとして書き出せ、Save pipeline(Ctrl+Shift+S) で JSON 保存できます。全機能とショートカットは STUDIO_GUIDE.md、アプリ内では F1 で一覧が出ます。
Studio で Save pipeline した JSON(あるいは --ops 文字列)を、そのままファイルに対して実行できます。これが HDevEngine 相当の「設計したものを書き直さずに実行する」経路です。
# 保存した JSON の I/O と各段を確認(画像なしで構造チェック)
py -3.11 imgevolve.py run edge.json --describe
# 画像に適用して結果を保存
py -3.11 imgevolve.py run edge.json in.png --out result.png
# 1 段ずつ結果を保存(result_00.png, result_01.png, ...)
py -3.11 imgevolve.py run edge.json in.png --stepwise --out step.png
# パイプラインを単体 Python 関数として書き出す
py -3.11 imgevolve.py run "gaussian,sobel_amp,otsu" --to-python
コードから実行する場合は FullseyeEngine を使います(詳細は ENGINE.md)。
import fullseye
eng = fullseye.FullseyeEngine.load("edge.json") # or .from_ops("gaussian,sobel_amp,otsu")
print(eng.input_sort(), "->", eng.output_sort()) # image -> region
out = eng.run(frame) # numpy in, numpy out
steps = eng.run_stepwise(frame) # 各段の途中結果(リスト)
画像ファイルを直接処理したいときは CLI が手軽です(画像 I/O に OpenCV か Pillow が必要)。
py -3.11 imgevolve.py ops --search edge # オペレータを検索
py -3.11 imgevolve.py has gauss_filter # HALCON 名が実装済みか + 呼び方
py -3.11 imgevolve.py apply gauss_filter in.png out.png --a 0.6
py -3.11 imgevolve.py pipeline in.png out.png --ops "gaussian,sobel_amp,otsu"
apply / pipeline は各段で共通の --a / --b を取ります。段ごとに違うつまみを使いたいときは、上の run_pipeline(Python)か Studio を使ってください。
| 症状 | 対処 |
|---|---|
ModuleNotFoundError: No module named 'fullseye' |
pip install -e . を実行するか、リポジトリ直下を PYTHONPATH に通す |
fullseye / fullseye-studio コマンドが無い |
コンソールスクリプトは pip install -e . で登録される。未インストールなら py -3.11 imgevolve.py ... / py -3.11 studio.py を使う |
| Studio が起動しない | GUI extras 未導入。pip install -e ".[gui]"(PySide6) |
apply / pipeline で cannot read ... |
画像 I/O 用に OpenCV([opencv])か Pillow([pil])を入れる |
| 追加バックエンドのオペレータが「unknown」 | そのバックンドが未導入。.[skimage] .[wavelets] .[extra] などを足す |
より詳しいトラブルシュートは INSTALL.md を参照してください。