公開している C ABI は 57 本である。C# の P/Invoke 宣言は 59 本ある。
差の 2 本は C ABI を増やさない。 既にある C の entry point へ 別の引数の形で入る C# 側の入口で、C 側に対応する宣言が無い。 下の表ではその行の C ABI の列が空欄になる。
ocvu_mat_copy_from_buffer_ptr→ocvu_mat_copy_from_bufferocvu_mat_copy_to_buffer_ptr→ocvu_mat_copy_to_buffer
「OpenCV 全対応」とは書かない。 何が在って何が無いかは、この表が示す。 ここに無い関数はまだ無いのであって、隠れているのではない。 範囲を決めているのは C ABI の所有権と versioning、 使い方は API リファレンス にある。
| module | C ABI | C# の宣言 | 到達性 | 内容 |
|---|---|---|---|---|
calib |
ocvu_calibrate_camera |
ocvu_calibrate_camera |
呼ぶ | 複数の view から撮った既知の立体パターン(通常はチェスボード)の対応点から、カメラの内部パラメータと歪み係数、および各 view の姿勢を求める。object_points は 1 点 3 float(x, y, z)、image_points は 1 点 2 float(x, y)で、どちらも view-major に並べる(1 枚目の全点、続いて 2 枚目の全点、…)。object_points_length と image_points_length はその配列のバイト数である(要素数でも点数でもない —— この ABI の length はすべてバイト数で統一してある)。呼ぶ側を信用せず、長さが必要量に満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。 view_count は 2 以上、points_per_view は 4 以上でなければならず、その積が OCVU_CALIB_MAX_POINTS を超える場合も OCVU_STATUS_INVALID_ARGUMENT を返す(int32 の乗算オーバーフローを避けるための歯止めであり、実用上の校正がこれを超えることは無い)。image_width と image_height はどちらも 1 以上でなければならない。出力の capacity は 3 つとも配列の要素数である(バイト数ではない)—— out_camera_matrix は 9 以上(3x3 を行優先で書く)、out_view_poses は view_count * 6 以上(1 view につき 6 個で、回転ベクトル 3 個のあとに並進ベクトル 3 個が続く)、out_dist_coeffs は OpenCV が返す係数の個数以上が要る。どれか 1 つでも足りなければ何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返す。歪み係数の個数だけは呼ぶ側が事前に知り得ない(OpenCV が入力を見て 4 / 5 / 8 / 12 / 14 のどれかを選ぶ)ので、dist_coeffs_capacity が足りなかった場合に限り out_dist_coeffs_count に必要な個数を入れる —— ocvu_find_chessboard_corners や ocvu_imencode と同じ 2 回呼びの作法である。成功したときは書いた歪み係数の個数を out_dist_coeffs_count に、再投影誤差(RMS、画素)を out_rms に入れる。それ以外のすべての失敗経路では out_dist_coeffs_count に 0 を書く。 OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、その理由は last-error のメッセージに入る(点が退化している、view ごとの対応が取れていない、などが該当する)。 out_camera_matrix / out_dist_coeffs / out_view_poses / out_rms の所有権は最初から最後まで呼ぶ側にある。 |
core |
ocvu_mat_create |
ocvu_mat_create |
呼ぶ | rows x cols、指定 type の Mat を確保し、handle を out_handle に書く。rows / cols が 1 未満、または type が未知なら OCVU_STATUS_INVALID_ARGUMENT を返し out_handle は変更しない。out_handle が NULL なら OCVU_STATUS_NULL_POINTER。 |
core |
ocvu_mat_release |
ocvu_mat_release |
呼ぶ | handle を解放する。解放済み、または未知の handle なら OCVU_STATUS_INVALID_HANDLE を返す(落とさない)。 |
core |
ocvu_mat_clone |
ocvu_mat_clone |
呼ぶ | src の内容を複製した独立の handle を作る。src と複製は別の記憶域を持つ。 |
core |
ocvu_mat_get_info |
ocvu_mat_get_info |
呼ぶ | handle の形状を out_info に書く。out_info が NULL なら OCVU_STATUS_NULL_POINTER。 |
core |
ocvu_mat_copy_from_buffer |
ocvu_mat_copy_from_buffer |
呼ぶ | 外部 buffer から Mat へコピーする。src は呼び出しの内側でだけ読む借用で、戻った後 native は一切保持しない。長さと stride は書く前にすべて検証し、1 つでも合わなければ何も書かずに返す。src_stride は Mat の step と異なってよく、行ごとにコピーする。 |
core |
ocvu_mat_copy_from_buffer_ptr |
呼ぶ | ocvu_mat_copy_from_buffer にアドレスを直接渡す C# 側の入口。NativeArray や Texture2D の生データを managed 配列へ写さずに渡すためにある。領域はこの呼び出しが戻るまで生きていなければならない。 | |
core |
ocvu_mat_copy_to_buffer |
ocvu_mat_copy_to_buffer |
呼ぶ | Mat から外部 buffer へコピーする。借用と検証の規則は ocvu_mat_copy_from_buffer と同じである。 |
core |
ocvu_mat_copy_to_buffer_ptr |
呼ぶ | ocvu_mat_copy_to_buffer にアドレスを直接渡す C# 側の入口。借用の契約は ocvu_mat_copy_from_buffer_ptr と同じである。 | |
core |
ocvu_extract_channel |
ocvu_extract_channel |
呼ぶ | src の 1 つの channel を取り出して dst に入れる。dst は結果に応じて丸ごと置き換わり、src と同じ大きさの 1 channel になる。channel_index は 0 以上かつ src の channel 数未満でなければならず、範囲外なら OCVU_STATUS_INVALID_ARGUMENT を返す。src と dst に同じ handle を渡してはならない(自分自身から channel を取り出す意味が無いので OCVU_STATUS_INVALID_ARGUMENT を返す)。handle が無効なら OCVU_STATUS_INVALID_HANDLE で、この判定は同じ handle かどうかの判定より先に行う。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。失敗したときは dst を書き換えない。 |
core |
ocvu_insert_channel |
ocvu_insert_channel |
呼ぶ | src(1 channel)を dst の 1 つの channel へ差し込む。dst は置き換わるのではなく、その channel だけが書き換わる —— これはこの ABI で dst を丸ごと置き換えない唯一の関数である。src は 1 channel で、dst と同じ大きさ・同じ要素型でなければならない(違えば OpenCV が例外を投げるので OCVU_STATUS_OPENCV_ERROR になる)。channel_index は 0 以上かつ dst の channel 数未満でなければならず、範囲外なら OCVU_STATUS_INVALID_ARGUMENT を返す。src と dst に同じ handle を渡してはならない。handle が無効なら OCVU_STATUS_INVALID_HANDLE で、この判定は同じ handle かどうかの判定より先に行う。失敗したときは dst を 1 バイトも書き換えない。 |
core |
ocvu_min_max_loc |
ocvu_min_max_loc |
呼ぶ | src の最小値・最大値と、それぞれが最初に現れる位置を返す。位置は out_min_x / out_min_y / out_max_x / out_max_y に画素座標で書く。6 つの出力はどれも NULL でよい(最大値だけ欲しいことは普通にある)が、6 つとも NULL なら OCVU_STATUS_NULL_POINTER を返す —— 何も受け取らずに計算だけさせる意味が無いためである。どの失敗経路でも、NULL でないすべての出力に 0 を書く。位置の 4 つがすべて NULL なら OpenCV にも位置を要求しないので、複数 channel の src でも値だけなら取得できる(値は全 channel を通した最小・最大である)。複数 channel で位置を 1 つでも要求すると、位置が一意に決まらないので OpenCV が拒み OCVU_STATUS_OPENCV_ERROR になる。handle が無効なら OCVU_STATUS_INVALID_HANDLE。出力の所有権は最初から最後まで呼ぶ側にある。 |
core |
ocvu_in_range |
ocvu_in_range |
呼ぶ | src の各画素が lower と upper の間(両端を含む)にあるかを調べ、入っていれば 255、外れていれば 0 を dst に書く。dst は結果に応じて丸ごと置き換わり、src と同じ大きさの 8 bit 1 channel になる。lower と upper は src の channel 数ぶんの double を並べた配列で、lower_length と upper_length はその バイト数 である(要素数でも channel 数でもない)。呼ぶ側を信用せず、src の channel 数ぶんに満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。複数 channel の場合は、すべての channel が範囲に入っている画素だけが 255 になる。src と dst に同じ handle を渡してもよい。lower か upper が NULL なら OCVU_STATUS_NULL_POINTER、handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
core |
ocvu_normalize |
ocvu_normalize |
呼ぶ | src の値域を正規化して dst に入れる。dst は結果に応じて丸ごと置き換わり、src と同じ型になる(この ABI は型変換を持ち込まないので、出力の型を選ぶ引数を出していない)。norm_type は OCVU_NORM_INF / OCVU_NORM_L1 / OCVU_NORM_L2 / OCVU_NORM_MINMAX のいずれかで、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す —— OCVU_NORM_HAMMING は記述子どうしの距離を測るためのもので、ここでは受け付けない。OCVU_NORM_MINMAX のときは値域を alpha と beta の間へ線形に写す(画像を見えるようにするのはふつうこれである)。他の 3 つのときは指定したノルムが alpha になるように割り、beta は使わない。src と dst に同じ handle を渡してもよい。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
core |
ocvu_bitwise |
ocvu_bitwise |
呼ぶ | src1 と src2 のビット演算(AND / OR / XOR)、または src1 のビット反転(NOT)を dst に入れる。dst は結果に応じて丸ごと置き換わり、src1 と同じ形状・型になる。op は OCVU_BITWISE_AND / OCVU_BITWISE_OR / OCVU_BITWISE_XOR / OCVU_BITWISE_NOT のいずれかで、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す。OCVU_BITWISE_NOT のときは src2 を一切見ない —— 無効な handle を渡しても成功する(黙って無視するのではなく、そう決めてある)。他の 3 つでは src2 の handle が無効なら OCVU_STATUS_INVALID_HANDLE を返す。src1 と src2 は同じ形状・同じ型でなければならず、違えば OCVU_STATUS_INVALID_ARGUMENT を返す —— この検査はこの ABI が自分で行う。 OpenCV に任せると、src2 が 1 要素のときにそれを scalar とみなして全画素へ黙って展開し、OCVU_STATUS_OK ともっともらしい結果を返すためである(実測)。src と dst に同じ handle を渡してもよい。失敗したときは dst を書き換えない。 |
core |
ocvu_lut |
ocvu_lut |
呼ぶ | src の各画素の値を表で引いた値に置き換えて dst に入れる。dst は結果に応じて丸ごと置き換わり、src と同じ形状・型になる。table は 8 bit の値域(0 から 255)を全部覆う 256 バイト以上でなければならず、table_length はその バイト数 である(読むのは先頭の 256 バイトだけで、それより長い分は使わない)。256 に満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。src は 8 bit でなければならず、そうでなければ OpenCV が例外を投げるので OCVU_STATUS_OPENCV_ERROR になる。複数 channel の src には同じ表がすべての channel に適用される。table が NULL なら OCVU_STATUS_NULL_POINTER、handle が無効なら OCVU_STATUS_INVALID_HANDLE。src と dst に同じ handle を渡してもよい。失敗したときは dst を書き換えない。 |
core |
ocvu_copy_make_border |
ocvu_copy_make_border |
呼ぶ | src の周囲に余白を足して dst に入れる。dst は結果に応じて丸ごと置き換わり、高さが src の高さ + top + bottom、幅が src の幅 + left + right で、src と同じ型になる。top / bottom / left / right はいずれも 0 以上でなければならず、負なら OCVU_STATUS_INVALID_ARGUMENT を返す。出来上がりの高さか幅が int32_t に収まらない場合も OCVU_STATUS_INVALID_ARGUMENT を返す(OpenCV に渡すと int の中で桁あふれする)。border_type は OCVU_BORDER_CONSTANT / OCVU_BORDER_REPLICATE / OCVU_BORDER_REFLECT / OCVU_BORDER_WRAP / OCVU_BORDER_REFLECT_101 のいずれかで、それ以外は拒否する。border_value は OCVU_BORDER_CONSTANT のときにだけ使う埋め値で、全 channel に同じ値が入る(channel ごとに違う値を入れる経路は出していない)。src と dst に同じ handle を渡してもよい。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
dnn |
ocvu_dnn_net_read_onnx |
ocvu_dnn_net_read_onnx |
呼ぶ | メモリ上の ONNX の byte 列からネットワークを読み、handle を out_handle に書く。ファイルパスは受け取らない(Windows の文字コードと Android の StreamingAssets のため)。読めなければ OCVU_STATUS_OPENCV_ERROR を返し out_handle は変更しない。data が NULL、out_handle が NULL なら OCVU_STATUS_NULL_POINTER。length が 1 未満なら OCVU_STATUS_INVALID_ARGUMENT。 |
dnn |
ocvu_dnn_net_release |
ocvu_dnn_net_release |
呼ぶ | ocvu_dnn_net_read_onnx が返した handle を解放する。native が所有する(docs/abi-ownership-and-versioning.md §1.7)ので、使い終わったら必ずこれで解放する。net が 0、解放済み、未知の handle のいずれでも OCVU_STATUS_INVALID_HANDLE を返し、落とさない(二重解放を検出する)。 |
dnn |
ocvu_dnn_blob_from_image |
ocvu_dnn_blob_from_image |
呼ぶ | src を推論の入力形式(4 次元の blob。N=1, C, height, width)に変換して dst に書く。scale は画素値に掛ける係数(例: 1/255.0)。mean_b / mean_g / mean_r は各チャンネルから引く値で、この順(B, G, R)で cv::Scalar に渡す固定契約である —— 配列ではなく 3 個の scalar にしてあるので、長さを取り違えて境界の外を読むことができない。検証の順序は決まっている: まず width / height の範囲(1 以上 OCVU_DNN_MAX_BLOB_DIM 以下。外れれば OCVU_STATUS_INVALID_ARGUMENT。cv::dnn::blobFromImage がその寸法でメモリを確保するため)、次に src の handle、最後に dst の handle(どちらも無効なら OCVU_STATUS_INVALID_HANDLE)。したがって範囲外の width と無効な handle を同時に渡すと OCVU_STATUS_INVALID_ARGUMENT が返る。swap_rb は 0 以外で R と B を入れ替え、crop は 0 以外でアスペクト比を保ったまま中央をトリミングする。dst が受け取る Mat は 4 次元のまま保持される(ocvu_mat_get_info のような 2 次元前提の関数はこの handle を OCVU_STATUS_INVALID_ARGUMENT で拒む)—— 2 次元へ潰すのは ocvu_dnn_net_forward の出力側だけである。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
dnn |
ocvu_dnn_net_forward |
ocvu_dnn_net_forward |
呼ぶ | net に input(ocvu_dnn_blob_from_image が作った blob)を渡して推論を 1 回走らせ、結果を output に書く。出力は 2 次元の Mat に潰される(rows × cols)。4 次元の blob を返すモデル(検出など)では、N と C の区別が失われる。分類モデルの 1 × N の出力を受け取ることを想定している。output は net の内部バッファから独立した新しいメモリのコピーであり、同じ net で続けて forward を呼んでも書き換わらない。handle の検証は net、input、output の順で行い、いずれかが無効なら OCVU_STATUS_INVALID_HANDLE を返す(解放済みの net も同じ status になる)。OpenCV が例外を投げた場合、または結果が空になった場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは output を書き換えない。engine / backend を選ぶ引数は無い(上流の 5.1 で enum EngineType の値が総入れ替えになったため、5.1 で意味が変わる数字を境界の外へ出さない)。 |
features |
ocvu_orb_detect |
ocvu_orb_detect |
呼ぶ | src から ORB の特徴点を検出して out_keypoints へ書き、見つかった個数を out_count に返す。呼ぶ側は必要量を事前に知り得るので 2 回呼ぶ必要は無い(上限は max_features で、capacity がそれに満たなければ何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返し out_count に max_features を入れる)。max_features は 1 以上 OCVU_ORB_MAX_FEATURES 以下でなければならない。OpenCV の ORB は指定した個数を上限として守らず、それを超える数の特徴点を返すことがある(実測)ので、この関数が max_features 個で切り詰める —— 上限は OpenCV の約束ではなく、この ABI 自身の契約である。記述子も要るなら ocvu_detect_and_compute を使うこと(こちらは記述子を計算しないので、角点だけが要る用途では記述子の計算と Mat の確保が省ける)。buffer の所有権は最初から最後まで呼ぶ側にある。 |
features |
ocvu_detect_and_compute |
ocvu_detect_and_compute |
呼ぶ | src から特徴点を検出し、同時にその記述子を計算する。特徴点は out_keypoints へ書き、記述子は out_descriptors の Mat へ入れる(Mat は結果で丸ごと置き換わり、行が特徴点 1 つ、列が記述子の次元になる —— ORB は 32 列の 8 bit 符号なし整数、SIFT は 128 列の 32 bit 浮動小数である)。記述子を平らな配列で返さないのは型も幅も検出器によって違うためで、handle のまま ocvu_match_descriptors へ渡せる。detector は OCVU_FEATURE_ORB か OCVU_FEATURE_SIFT で、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す。max_features は 1 以上 OCVU_ORB_MAX_FEATURES 以下でなければならない。max_features は OpenCV への希望であって上限ではない —— ORB も SIFT も指定より多くの特徴点を返すことがあるので(実測)、capacity を max_features と同じ値にしてはならない。capacity は out_keypoints の要素数である(バイト数ではない)—— 見つかった数に満たなければ何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返し、out_count に実際に見つかった数を入れる。溢れた場合 out_descriptors は書き換えない —— 更新されるのは out_count だけなので、返ってきた個数で確保し直してもう一度呼ぶこと。capacity が 0 で out_keypoints が NULL なら個数の問い合わせとして扱う(それでも out_descriptors には有効な handle が要る)。1 つも見つからないのは誤りではない —— OCVU_STATUS_OK を返して out_count に 0 を入れる。out_count が NULL なら他の何より先に OCVU_STATUS_NULL_POINTER を返し、通ったあとはどの失敗経路でも out_count に 0 を書く。src と out_descriptors に同じ handle を渡してはならない。検出器は呼び出しのたびに作り直される —— この ABI の粒度は 1 枚を処理することであって、検出器を保持することではない。記述子が要らないなら ocvu_orb_detect を使うこと。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。buffer の所有権は最初から最後まで呼ぶ側にある。 |
features |
ocvu_match_descriptors |
ocvu_match_descriptors |
呼ぶ | query の各記述子に対して train の中で最も近いものを 1 つ探し、その対応を out_matches へ書いて個数を out_count に返す。query と train は ocvu_detect_and_compute が作った記述子の Mat である。norm_type は OCVU_NORM_HAMMING か OCVU_NORM_L2 で、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す —— 検出器に合わせること(ORB の 2 値記述子には HAMMING、SIFT の 32 bit 浮動小数の記述子には L2)。組み合わせを誤ると OpenCV が例外を投げる —— OCVU_NORM_HAMMING を SIFT の浮動小数の記述子に当てた場合と、query と train の記述子の型が食い違う場合は、どちらも OCVU_STATUS_OPENCV_ERROR になる(実測)。cross_check は 0 以外を真として扱い、互いに最近傍である対応だけを残す(誤対応が減るが、対応の数も減る)—— 同じ画像から作った記述子どうしでも、cross_check が 0 だと query_index と train_index は一致しないことがある(繰り返す模様では記述子が重複し、同点のとき先に現れたほうが選ばれるため)。capacity は out_matches の要素数である(バイト数ではない)—— 見つかった対応の数に満たなければ何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返し、out_count に実際の対応数を入れる。capacity が 0 で out_matches が NULL なら個数の問い合わせとして扱う。1 つも見つからないのは誤りではない —— OCVU_STATUS_OK を返して out_count に 0 を入れる。out_count が NULL なら他の何より先に OCVU_STATUS_NULL_POINTER を返し、通ったあとはどの失敗経路でも out_count に 0 を書く。距離は小さいほど似ている。image_index は、この ABI が 1 対 1 の照合しか出していないので常に 0 である。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。buffer の所有権は最初から最後まで呼ぶ側にある。 |
geometry |
ocvu_find_homography |
ocvu_find_homography |
呼ぶ | 2 組の点の対応から射影変換(3x3)を求めて dst に入れる。dst は結果に応じて丸ごと置き換わり、64 bit 1 channel の 3x3 になる。src_points と dst_points はどちらも x と y が交互に並ぶ float の配列で、src_length と dst_length はその配列のバイト数である(要素数でも点数でもない —— この ABI の length はすべてバイト数で統一してある)。呼ぶ側を信用せず、長さが point_count * 2 * sizeof(float) に満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。 point_count は 4 以上でなければならない(4 点未満では射影変換が決まらない)。method は OCVU_HOMOGRAPHY_METHOD_* のいずれかで、それ以外は拒否する。ransac_threshold は RANSAC のときだけ使う画素単位のしきい値である。点が退化していて解が求まらないときは OCVU_STATUS_NOT_FOUND を返し、これは誤りではない(どの入力がそうなるかは OpenCV が決める。実測では全部同じ点と軸に平行な直線が NOT_FOUND で、斜めの直線は rank 不足の行列がそのまま返り OCVU_STATUS_OK になる —— 共線判定はしていない)。失敗したときは dst を書き換えない。 |
geometry |
ocvu_solve_pnp |
ocvu_solve_pnp |
呼ぶ | 既知の 3D 点と、その画像上の対応点、カメラの内部パラメータから 1 枚ぶんの姿勢を求める。object_points は 1 点 3 float(x, y, z)、image_points は 1 点 2 float(x, y)で、同じ順に並べる。object_points_length と image_points_length と camera_matrix_length と dist_coeffs_length はいずれもその配列のバイト数である(要素数でも点数でもない —— この ABI の length はすべてバイト数で統一してある)。呼ぶ側を信用せず、長さが必要量に満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。 point_count は 4 以上 OCVU_PNP_MAX_POINTS 以下でなければならない。camera_matrix は行優先の 3x3(double 9 個)である。dist_coeffs は長さ 0 で「歪み無し」を指定でき、そのとき NULL を渡してよい。長さが 0 でないのに NULL なら OCVU_STATUS_NULL_POINTER を返し、長さが 0 でないなら OpenCV が受ける個数(4 / 5 / 8 / 12 / 14 個の double)でなければならない。method は OCVU_SOLVEPNP_* のいずれかで、それ以外は拒否する。出力の rvec_capacity と tvec_capacity は配列の要素数で(バイト数ではない)、どちらも 3 以上が要る —— 足りなければ何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返す。out_rvec は Rodrigues の回転ベクトル(向きが回転軸、長さが回転角のラジアン)、out_tvec は並進で、単位は object_points に渡したものと同じである。camera_matrix の [0] と [4](fx と fy)はどちらも 0 であってはならず、0 なら OCVU_STATUS_INVALID_ARGUMENT を返す —— OpenCV は焦点距離が 0 のカメラ行列を検出せず、有限だが無意味な姿勢を成功として返すためである(実測)。これは一般的な特異性の検査ではなく、見ているのはその 2 要素だけである。姿勢が求まらないとき、および求まった 6 つの値のいずれかが有限でないときは OCVU_STATUS_NOT_FOUND を返し、これは誤りではない。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、その理由は last-error のメッセージに入る。どの失敗経路でも out_rvec と out_tvec は 1 バイトも書き換えない。 これらの所有権は最初から最後まで呼ぶ側にある。 |
geometry |
ocvu_rodrigues_to_matrix |
ocvu_rodrigues_to_matrix |
呼ぶ | Rodrigues の回転ベクトル(3 要素。向きが回転軸、長さが回転角のラジアン)を 3x3 の回転行列に直し、行優先で out_matrix へ書く。rotation_vector_length は入力配列のバイト数で(要素数ではない)、double 3 個ぶんに満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。matrix_capacity は出力配列の要素数で(バイト数ではない)、9 未満なら何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返す。ポインタが NULL なら OCVU_STATUS_NULL_POINTER を返す。OpenCV が例外を投げた場合、および結果が 3x3 でなかった場合は OCVU_STATUS_OPENCV_ERROR を返す。どの失敗経路でも out_matrix は 1 バイトも書き換えない。 out_matrix の所有権は最初から最後まで呼ぶ側にある。 |
geometry |
ocvu_rodrigues_to_vector |
ocvu_rodrigues_to_vector |
呼ぶ | 3x3 の回転行列(行優先の double 9 個)を Rodrigues の回転ベクトル(3 要素)に直して out_vector へ書く。rotation_matrix_length は入力配列のバイト数で(要素数ではない)、double 9 個ぶんに満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。vector_capacity は出力配列の要素数で(バイト数ではない)、3 未満なら何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返す。ポインタが NULL なら OCVU_STATUS_NULL_POINTER を返す。入力が回転行列でない場合の扱いは OpenCV に委ねており、例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。どの失敗経路でも out_vector は 1 バイトも書き換えない。 out_vector の所有権は最初から最後まで呼ぶ側にある。 |
geometry |
ocvu_project_points |
ocvu_project_points |
呼ぶ | 3D の点を、与えた姿勢とカメラの内部パラメータで画像平面へ投影する。object_points は 1 点 3 float(x, y, z)で、object_points_length と rvec_length と tvec_length と camera_matrix_length と dist_coeffs_length はいずれもその配列のバイト数である(要素数でも点数でもない)。呼ぶ側を信用せず、長さが必要量に満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。 point_count は 1 以上 OCVU_PNP_MAX_POINTS 以下でなければならない(姿勢は与えられているので 4 点は要らない)。rvec は Rodrigues の回転ベクトル(3 要素)、tvec は並進(3 要素)、camera_matrix は行優先の 3x3(9 要素)である。camera_matrix の [0] と [4](fx と fy)はどちらも 0 であってはならず、0 なら OCVU_STATUS_INVALID_ARGUMENT を返す(ocvu_solve_pnp と同じ理由である)。dist_coeffs は長さ 0 で歪み無しを指定でき、そのとき NULL を渡してよい。長さが 0 でないのに NULL なら OCVU_STATUS_NULL_POINTER を返し、長さが 0 でないなら 4 / 5 / 8 / 12 / 14 個の double でなければならない。out_capacity は出力配列の要素数で(バイト数ではない)、point_count の 2 倍未満なら何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返す。出力は x と y が交互に並ぶ float である。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。どの失敗経路でも out_image_points は 1 バイトも書き換えない。 out_image_points の所有権は最初から最後まで呼ぶ側にある。 |
geometry |
ocvu_get_perspective_transform |
ocvu_get_perspective_transform |
呼ぶ | ちょうど 4 点の対応から射影変換(3x3)を厳密に求めて dst に入れる。dst は結果に応じて丸ごと置き換わり、OCVU_MAT_TYPE_64FC1 の 3x3 になる。src_points と dst_points はどちらも x と y が交互に並ぶ float 8 個(4 点)で、src_length と dst_length はその配列のバイト数である(要素数でも点数でもない —— この ABI の length はすべてバイト数で統一してある)。呼ぶ側を信用せず、4 点ぶん(32 バイト)に満たなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。それより長い配列は通し、先頭の 4 点だけを読む。ocvu_find_homography との違いは、こちらがちょうど 4 点を厳密に通すのに対し、あちらは 4 点以上から当てはめる点である —— 外れ値がありうる対応には ocvu_find_homography を使うこと。求めた行列は ocvu_warp_perspective にそのまま渡せる。src_points か dst_points が NULL なら OCVU_STATUS_NULL_POINTER。dst の handle が無効なら OCVU_STATUS_INVALID_HANDLE。点が退化しているときに何が起きるかは OpenCV が決める —— 例外を投げた場合と空の行列を返した場合はどちらも OCVU_STATUS_OPENCV_ERROR を返すが、退化した 4 点で必ずそのどちらかになるとは約束しない(ocvu_find_homography と違い、そこは実測していない)。失敗したときは dst を書き換えない。 |
imgcodecs |
ocvu_imencode |
ocvu_imencode |
呼ぶ | Mat を画像形式に符号化し buffer へ書く。符号化後の大きさは呼ぶ側に分からないので 2 回呼ぶ(1 回目は buffer に NULL を渡して out_required_size に必要バイト数を受け取る。そのとき返る OCVU_STATUS_BUFFER_TOO_SMALL は失敗ではない)。buffer の所有権は最初から最後まで呼ぶ側にあり、足りなければ何も書かない。ext は .png のように先頭のドットを含む拡張子で、NULL と空文字列は拒否する。 |
imgcodecs |
ocvu_imdecode |
ocvu_imdecode |
呼ぶ | 符号化された画像 byte 列を復号して dst に入れる。dst の形状と型は結果に応じて上書きされる。data はこの呼び出しの内側でのみ読む借用で、native は保持しない。length は 1 以上 INT32_MAX 以下でなければならず、画像として解釈できない byte 列は OCVU_STATUS_OPENCV_ERROR になる(メモリは壊さない)。flags は OCVU_IMREAD_* である。 |
imgproc |
ocvu_cvt_color |
ocvu_cvt_color |
呼ぶ | 色空間を変換する。dst の形状と型は結果に応じて上書きされる。src と dst が同じ handle なら OCVU_STATUS_INVALID_ARGUMENT を返す(OpenCV の in-place 対応は関数ごとに異なり、曖昧さを ABI に持ち込まない)。OpenCV 由来の失敗は OCVU_STATUS_OPENCV_ERROR になる。 |
imgproc |
ocvu_resize |
ocvu_resize |
呼ぶ | width x height に拡大縮小する。width / height が 1 未満なら OCVU_STATUS_INVALID_ARGUMENT。src と dst に同じ handle を渡した場合も同様に拒否する。 |
imgproc |
ocvu_gaussian_blur |
ocvu_gaussian_blur |
呼ぶ | Gaussian ぼかしを掛ける。ksize は正の奇数でなければならず、そうでなければ OCVU_STATUS_INVALID_ARGUMENT。sigma に 0 を渡すと OpenCV が ksize から算出する。 |
imgproc |
ocvu_undistort |
ocvu_undistort |
呼ぶ | src の歪みを camera_matrix と dist_coeffs で補正して dst に入れる。dst は結果に応じて丸ごと置き換わり、src と同じ形状・型になる。camera_matrix は行優先の 3x3(double 9 個)、dist_coeffs は OpenCV が受ける長さ(4 / 5 / 8 / 12 / 14 個)でなければならない。camera_matrix_length と dist_coeffs_length はどちらもバイト数で、この ABI の length は全部そうである。呼ぶ側を信用せず、長さが合わなければ何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。失敗したときは dst を書き換えない。src と dst に同じ handle を渡してもよい(結果を求めてから入れ替えるので、cvtColor と違い in-place 呼び出しを禁じていない)。 |
imgproc |
ocvu_threshold |
ocvu_threshold |
呼ぶ | src を二値化して dst に入れる。dst は結果に応じて丸ごと置き換わり、src と同じ形状・型になる。type は OCVU_THRESH_BINARY から OCVU_THRESH_TOZERO_INV までのいずれかで、OCVU_THRESH_OTSU を or して渡すとしきい値を画像から自動で選ぶ(そのとき threshold_value は無視される)。それ以外のビットが立っていれば OCVU_STATUS_INVALID_ARGUMENT を返す —— cv::THRESH_TRIANGLE はこの ABI に出していないので、or して渡しても断る。out_computed_threshold には実際に使われたしきい値が入る。これは Otsu を指定したときに選ばれた値を知る唯一の手段である。out_computed_threshold は NULL でもよく、その場合は書かない。NULL でないならどの失敗経路でも 0 を書く。src の型には OpenCV 側の制約がある: 32 bit 符号つき整数は拒否され、OCVU_THRESH_OTSU が使えるのは 8 bit 符号なし 1 channel と 16 bit 符号なし 1 channel だけである(複数 channel の画像に or して渡すと OpenCV が例外を投げる)。src と dst に同じ handle を渡してもよい —— 結果を一時に求めてから入れるので、cvtColor と違い in-place 呼び出しを禁じていない。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
imgproc |
ocvu_canny |
ocvu_canny |
呼ぶ | src に Canny のエッジ検出を掛けて dst に入れる。dst は結果に応じて丸ごと置き換わり、src と同じ大きさの 8 bit 1 channel になる(エッジが 255、それ以外が 0)。src は 8 bit でなければならず、そうでなければ OpenCV が例外を投げる。threshold1 と threshold2 はどちらも 0 以上でなければならず、負なら OCVU_STATUS_INVALID_ARGUMENT を返す。小さいほうが弱いエッジをつなぐ下限、大きいほうが強いエッジの下限として使われる。aperture_size は Sobel の窓の大きさで、3 か 5 か 7 でなければならない。l2_gradient は 0 以外を真として扱い、勾配の大きさを L2 ノルムで測る(0 なら L1 で、速いが粗い)。src と dst に同じ handle を渡してもよい。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
imgproc |
ocvu_morphology_ex |
ocvu_morphology_ex |
呼ぶ | src に形態素演算(収縮・膨張・開・閉・勾配・トップハット・ブラックハット)を掛けて dst に入れる。dst は結果に応じて丸ごと置き換わり、src と同じ形状・型になる。op は OCVU_MORPH_* のいずれか、kernel_shape は OCVU_MORPH_SHAPE_* のいずれかで、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す。kernel_width と kernel_height は構造要素の大きさで、どちらも 1 以上でなければならない。iterations は演算を繰り返す回数で、1 以上でなければならない。構造要素の中心は OpenCV が自動で決める。src と dst に同じ handle を渡してもよい。handle が無効なら OCVU_STATUS_INVALID_HANDLE。構造要素が大きすぎて確保できない場合を含め、OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
imgproc |
ocvu_match_template |
ocvu_match_template |
呼ぶ | image の中で templ に似ている場所の応答画像を作って dst に入れる。dst は結果に応じて丸ごと置き換わり、列数は image の列数から templ の列数を引いて 1 を足したもの、行数も同じ引き算で決まり、型は OCVU_MAT_TYPE_32FC1 である。method は OCVU_TM_* のいずれかで、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す。OCVU_TM_SQDIFF と OCVU_TM_SQDIFF_NORMED は値が小さいほど似ており、他の 4 つは大きいほど似ている —— 最も似た位置を探すときに、最小と最大のどちらを取るかが逆になる。image と templ は 8 bit か 32 bit 浮動小数で、しかも同じ型でなければならない。templ の行数と列数はどちらも image のそれ以下でなければならず、そうでなければ OCVU_STATUS_INVALID_ARGUMENT を返す。この大きさの検査はこの ABI が自分で行う —— 実測(2026-09-05)では、両方向とも templ のほうが大きいとき OpenCV は例外を投げず image と templ を入れ替えて計算するので、任せると上に書いた出力の形が黙って破られる。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
imgproc |
ocvu_warp_perspective |
ocvu_warp_perspective |
呼ぶ | src を射影変換で変形して dst に入れる。dst は結果に応じて丸ごと置き換わり、height 行 width 列で src と同じ型になる。transform は 3x3 の変換行列を持つ Mat の handle である —— ocvu_get_perspective_transform や ocvu_find_homography の出力をそのまま渡せる形にしてあり、行列を C# 側へ読み出して詰め替える往復を呼ぶ側に強いない。3 行 3 列でなければ OCVU_STATUS_INVALID_ARGUMENT を返す。width と height はどちらも 1 以上でなければならない。interpolation は OCVU_INTER_* のいずれか、border_mode は OCVU_BORDER_* のいずれかで、それ以外は拒否する。border_mode は変換後に元の画像の外を参照した画素をどう埋めるかで、OCVU_BORDER_CONSTANT は 0 で埋める。src と dst に同じ handle を渡してもよい —— 結果を一時に求めてから入れるので、in-place 呼び出しを禁じていない。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返し、失敗したときは dst を書き換えない。 |
imgproc |
ocvu_hough_lines_p |
ocvu_hough_lines_p |
呼ぶ | 確率的 Hough 変換で src から線分を検出し、out_lines へ書いて本数を out_count に返す。src は 8 bit 1 channel の 2 値画像でなければならない(ocvu_canny の出力をそのまま渡せる)。src は書き換えない —— OpenCV は入力を書き換えることがあると宣言しているので、実装は写しを渡す。rho は距離の刻み(画素)で 0 より大きく、theta は角度の刻み(ラジアン)で 0 より大きく、threshold は投票数の下限で 1 以上でなければならない。min_line_length より短い線分は捨て、max_line_gap 以下の切れ目はつなぐ。capacity は out_lines の要素数である(バイト数でも本数でもない)—— 線分 1 本につき x1, y1, x2, y2 の 4 要素を使うので、n 本を受けるには capacity が n の 4 倍以上でなければならない。足りないときは out_lines に 1 バイトも書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返し、out_count に実際に見つかった本数を入れる(呼ぶ側はそれを 4 倍して確保し直し、呼び直せる)。out_count に入るのは常に本数であって要素数ではない。capacity が 0 のときだけ out_lines は NULL でよく、それが必要な本数だけを問い合わせる呼び方である。capacity が 1 以上なのに out_lines が NULL なら OCVU_STATUS_NULL_POINTER。1 本も見つからないのは誤りではない —— OCVU_STATUS_OK を返して out_count に 0 を入れる。out_count が NULL なら他の何より先に OCVU_STATUS_NULL_POINTER を返し、通ったあとはどの失敗経路でも out_count に 0 を書く。handle が無効なら OCVU_STATUS_INVALID_HANDLE。src の型が合わないなど OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。buffer の所有権は最初から最後まで呼ぶ側にある。 |
imgproc |
ocvu_corner_sub_pix |
ocvu_corner_sub_pix |
呼ぶ | 既に見つけてある角点の位置を副画素精度へ精緻化する。points は入出力兼用である —— 渡した位置を読み、精緻化した位置でその場を上書きする。この ABI で唯一この形をしていて、他の buffer 引数は入力か出力のどちらかである。x と y が交互に並ぶ 32 bit 浮動小数の配列で、points_length はそのバイト数である(要素数でも点数でもない)。point_count は 1 以上 OCVU_CORNER_MAX_POINTS 以下でなければならず、points_length が point_count の 2 倍の浮動小数を収めるバイト数に満たなければ、何も読まずに OCVU_STATUS_INVALID_ARGUMENT を返す。win_size は探索窓の半径(画素)で 1 以上 OCVU_CORNER_MAX_WINDOW 以下、zero_zone は窓の中央で無視する領域の半径で -1 なら無視しない、max_iterations は 1 以上、epsilon は移動量がこれを下回ったら打ち切る値である。src は 1 channel でなければならない —— cv::cornerSubPix 自身が縛るのは channel の数だけだが、実測では 8 bit と 32 bit 浮動小数だけが通り、16 bit は OpenCV の内部でさらに拒否される。断った場合は points を 1 バイトも書き換えない。呼ぶ側の buffer を直接 OpenCV へ渡さず写してから戻すので、OpenCV が例外を投げたときも points は書きかけで残らない。points が NULL なら OCVU_STATUS_NULL_POINTER。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。buffer の所有権は最初から最後まで呼ぶ側にある。 win_size と zero_zone には上限がある —— cv::cornerSubPix はこの 2 つを int のまま 2 倍して窓の寸法にするので、大きな値は符号あり整数のオーバーフローになる。実測では zero_zone に 2 の 30 乗を渡すとプロセスがアクセス違反で即死し、win_size に INT32_MAX を渡すと無意味な窓で OCVU_STATUS_OK が返った。zero_zone は -1(無視しない)または 0 以上 OCVU_CORNER_MAX_WINDOW 以下でなければならず、範囲外は OCVU_STATUS_INVALID_ARGUMENT を返す。 |
imgproc |
ocvu_find_contours |
ocvu_find_contours |
呼ぶ | src から輪郭を検出し、全輪郭の点を out_points へ、輪郭ごとの点数を out_counts へ書く。入れ子の可変長を、平らな 2 本の配列で表している —— 呼ぶ側は out_counts を前から足していけば、out_points の中で各輪郭がどこからどこまでかが決まる。src は 8 bit 1 channel の 2 値画像でなければならない(0 でない画素を 1 と見なす)。mode は OCVU_RETR_EXTERNAL から OCVU_RETR_TREE までのいずれかで、cv::RETR_FLOODFILL に当たる定数は出していない(32 bit のラベル画像を要求するので、この関数が受ける 8 bit の 2 値画像では使えない)。method は OCVU_CHAIN_APPROX_NONE か OCVU_CHAIN_APPROX_SIMPLE のどちらかで、Teh-Chin 系は出していない。どちらも一覧の外なら OCVU_STATUS_INVALID_ARGUMENT を返す。points_capacity と counts_capacity はどちらも配列の要素数である(バイト数でも点数でもない)—— 点 1 つにつき x と y の 2 要素を使う。どちらかが足りないときは、どちらの配列にも 1 バイトも書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返し、out_contour_count に必要な輪郭の本数を、out_total_points に必要な点の総数を入れる(呼ぶ側はそれで確保し直して呼び直せる)。容量が 0 のときだけ対応する配列は NULL でよく、両方を 0 と NULL にした呼び出しが必要な大きさの問い合わせになる。容量が 1 以上なのに配列が NULL なら OCVU_STATUS_NULL_POINTER。1 本も見つからないのは誤りではない —— OCVU_STATUS_OK を返して両方に 0 を入れる。out_contour_count か out_total_points が NULL なら他の何より先に OCVU_STATUS_NULL_POINTER を返す。NULL でないほうにはその時点で 0 を書き、両方が通ったあとはどの失敗経路でも両方に 0 を書く。階層(どの輪郭がどの輪郭の内側にあるか)は返さない。handle が無効なら OCVU_STATUS_INVALID_HANDLE。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。buffer の所有権は最初から最後まで呼ぶ側にある。 |
infra |
ocvu_get_abi_version |
ocvu_get_abi_version |
呼ぶ | 現在の C ABI バージョンを返す。失敗しない。 |
infra |
ocvu_get_last_error_status |
ocvu_get_last_error_status |
呼ぶ | 直近のエラー status を返す。呼び出しスレッドごとに独立している。 |
infra |
ocvu_get_last_error_message |
ocvu_get_last_error_message |
呼ぶ | 直近のエラーメッセージを UTF-8・NUL 終端で buffer に書く。buffer に NULL を渡して必要サイズだけを聞くのが正規の 1 回目で、そのとき返る OCVU_STATUS_BUFFER_TOO_SMALL は失敗ではない。out_required_size が NULL なら OCVU_STATUS_NULL_POINTER。この関数自身は last-error を変更しない。 |
infra |
ocvu_get_status_count |
ocvu_get_status_count |
呼ぶ | ネイティブ側が定義している status code の個数を返す。失敗しない。C# の CvStatus との同期を L3 で検証するために公開している。 |
infra |
ocvu_get_status_value |
ocvu_get_status_value |
呼ぶ | index 番目の status code の数値を out_value に書く。並び順は OCVU_STATUS_LIST の記述順。範囲外の index は OCVU_STATUS_INVALID_ARGUMENT、out_value が NULL なら OCVU_STATUS_NULL_POINTER。 |
infra |
ocvu_get_opencv_version |
ocvu_get_opencv_version |
呼ぶ | リンクされている OpenCV のバージョン文字列(例 5.0.0)を UTF-8 で書く。バッファ規約は ocvu_get_last_error_message と同一である。 |
infra |
ocvu_get_build_information |
ocvu_get_build_information |
呼ぶ | cv::getBuildInformation() の内容を UTF-8 で書く。どの依存が有効なリンクになっているかを実行時に確認するために使う。バッファ規約は ocvu_get_opencv_version と同一である。 |
infra |
ocvu_debug_throw |
ocvu_debug_throw |
呼ぶ | conformance test 用に、内部で意図的に例外を投げる。kind は 0 が std::runtime_error、1 が std::bad_alloc、2 が非標準例外、3 が投げない。例外が ABI 境界を越えないことの検証に使う。 |
infra |
ocvu_debug_crash |
ocvu_debug_crash |
呼ばない | conformance test 用に、意図的にプロセスを壊す。kind は 0 が不正アクセスで即死、1 が戻ってこない(無限ループ)。managed 側からネイティブが死んだときに L3 が有限時間で赤くなるかを確かめるためだけに存在し、通常の経路からは決して呼ばれない。 |
objdetect |
ocvu_qr_encode |
ocvu_qr_encode |
呼ぶ | text を QR コードの画像に符号化して dst に入れる。dst の形状と型は結果に応じて上書きされ、8 bit 1 channel の正方形になる。text は NUL 終端の UTF-8 byte 列で、NULL と空文字列は拒否する。符号化できない長さの text は OCVU_STATUS_OPENCV_ERROR になる。失敗したときは dst を書き換えない。 |
objdetect |
ocvu_qr_decode |
ocvu_qr_decode |
呼ぶ | src に写っている QR コードを 1 つ検出して復号し、NUL 終端の UTF-8 byte 列として buffer へ書く。検出の前に白い余白(quiet zone)を必ず足し、短いほうの辺が 200 px 未満の画像はさらに最近傍補間で拡大してから検出する。復号後の長さは呼ぶ側に分からないので 2 回呼ぶ(1 回目は buffer に NULL を渡して out_required_size に NUL を含む必要バイト数を受け取る。そのとき返る OCVU_STATUS_BUFFER_TOO_SMALL は失敗ではない)。buffer の所有権は最初から最後まで呼ぶ側にあり、足りなければ何も書かない。QR が写っていなければ OCVU_STATUS_NOT_FOUND を返し、これは誤りではない。 |
objdetect |
ocvu_find_chessboard_corners |
ocvu_find_chessboard_corners |
呼ぶ | src に写っているチェスボードの内側の格子点を見つけて out_corners へ x と y が交互に並ぶ形で書き、書いた float の個数を out_count に返す。capacity は out_corners の float の個数であり、点の個数ではない(x と y の 2 つで 1 点なので、必要な float 数は pattern_cols * pattern_rows * 2 である)。呼ぶ側は必要量を事前に知り得るので 2 回呼ぶ必要は無い(capacity がそれに満たなければ何も書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返し out_count に必要な float 数を入れる)。pattern_cols と pattern_rows はどちらも 2 以上でなければならず、その積が OCVU_CHESSBOARD_MAX_CORNERS を超える場合も OCVU_STATUS_INVALID_ARGUMENT を返す(int32 の乗算オーバーフローを避けるための歯止めであり、実用上のチェスボードパターンがこれを超えることは無い)。out_count が NULL なら OCVU_STATUS_NULL_POINTER を返す。capacity が正で out_corners が NULL なら OCVU_STATUS_NULL_POINTER、capacity が負なら OCVU_STATUS_INVALID_ARGUMENT を返す。src が空なら OCVU_STATUS_INVALID_ARGUMENT を返す(現在の ABI では ocvu_mat_create が空の Mat を作れないので実際には到達しない防御である)。これらいずれの失敗経路でも out_count には常に 0 を書く(BUFFER_TOO_SMALL のときだけ必要な float 数を書く)。格子が写っていなければ OCVU_STATUS_NOT_FOUND を返し、これは誤りではない。buffer の所有権は最初から最後まで呼ぶ側にある。 |
objdetect |
ocvu_aruco_generate_marker |
ocvu_aruco_generate_marker |
呼ぶ | 辞書とマーカー ID からマーカーの画像を生成して dst に入れる。dst は結果に応じて丸ごと置き換わり、side_pixels 四方の 8 bit 1 channel になる(作ったときの形と型は残らない)。dictionary_id は OCVU_ARUCO_DICT_* のいずれかで、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す —— cv::aruco には AprilTag 系の辞書もあるが、この plugin では検証していないので出していない。marker_id は 0 以上、その辞書が持つ個数未満でなければならない(DICT_4X4_50 なら 0 から 49 まで)。side_pixels は 1 以上 OCVU_ARUCO_MAX_MARKER_PIXELS 以下で、さらに「その辞書の格子の一辺 + border_bits の 2 倍」以上でなければならない(それより小さいと格子 1 つが 1 画素に満たない。これはこの ABI が自分で決めた制限であり、OpenCV の挙動を根拠にしていない)。border_bits は 1 以上で、マーカーの内側に置く黒い枠の太さ(格子単位)である —— 検出にはこの枠のさらに外側に白い余白が要るが、それを付けるのは呼ぶ側の仕事である。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。どの失敗経路でも dst は書き換えない。 |
objdetect |
ocvu_aruco_detect_markers |
ocvu_aruco_detect_markers |
呼ぶ | src から ArUco マーカーを検出し、その ID を out_ids へ、4 隅の座標を out_corners へ書いて、見つかった個数を out_count に返す。src は 8 bit の 1 channel か 3 channel か 4 channel でなければならず、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す(3 channel と 4 channel はこの関数がグレースケールへ落としてから検出する —— Unity のテクスチャは 4 channel なので、呼ぶ側に変換を強いない)。dictionary_id は OCVU_ARUCO_DICT_* のいずれかで、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す。ids_capacity と corners_capacity はどちらも配列の要素数である(バイト数ではない)—— 1 マーカーにつき ID が 1 個、隅の座標が 8 個(x と y が交互に 4 隅ぶん)要るので、n 個を受けるには ids_capacity が n 以上、corners_capacity が n の 8 倍以上でなければならない。隅は OpenCV の detectMarkers が返す順、すなわち時計回りで、最初がマーカーの左上である。容量が足りないときはどちらの配列にも 1 バイトも書かずに OCVU_STATUS_BUFFER_TOO_SMALL を返し、out_count には実際に見つかった個数を入れる —— 容量 0 とポインタ NULL の組み合わせは「何個写っているか」を先に問い合わせる正規の呼び方で、そこで得た個数ぶん確保して呼び直せる。容量が正なのにポインタが NULL なら OCVU_STATUS_NULL_POINTER を返す。1 個も見つからないのは誤りではない —— OCVU_STATUS_OK を返して out_count に 0 を入れる。out_count が NULL なら他の何より先に OCVU_STATUS_NULL_POINTER を返し、通ったあとはどの失敗経路でも out_count に 0 を書く。OpenCV が例外を投げた場合は OCVU_STATUS_OPENCV_ERROR を返す。buffer の所有権は最初から最後まで呼ぶ側にある。 |
stereo |
ocvu_compute_disparity |
ocvu_compute_disparity |
呼ぶ | 平行に並べた左右の画像から視差の画像を作って dst に入れる。dst は結果に応じて丸ごと置き換わり、入力と同じ大きさの OCVU_MAT_TYPE_16SC1(16 bit 符号つきの 1 channel)になる —— ocvu_mat_copy_to_buffer で読み出すときは 1 画素 2 バイトとして扱うこと。値は実際の視差の 16 倍である(OpenCV が固定小数で返す。視差が求まらなかった画素には負の値が入る)。left と right はどちらも OCVU_MAT_TYPE_8UC1 でなければならず、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す。2 枚はあらかじめ平行化されていなければならない —— この package は平行化を持っていないので、守らなくても誰も止めないが結果は無意味になる。algorithm は OCVU_STEREO_BM か OCVU_STEREO_SGBM で、それ以外は OCVU_STATUS_INVALID_ARGUMENT を返す —— BM は速いが粗く、SGBM は遅いが滑らかである。num_disparities は探索する視差の幅で正の 16 の倍数、block_size は照合する窓の 1 辺で 5 以上の奇数でなければならない。この 2 つは OpenCV の要求ではなく、この ABI が自分で決めた、より厳しい契約である —— OpenCV が同じ制限を課すのは BM だけで、SGBM は block_size も num_disparities も検査しない。両方に同じ制限をかけてあるので、algorithm を変えても呼ぶ側の引数の作り方は変わらない。左右の大きさが違う場合は OpenCV が例外を投げるので OCVU_STATUS_OPENCV_ERROR を返す。handle が無効なら OCVU_STATUS_INVALID_HANDLE。失敗したときは dst を 1 バイトも書き換えない。 照合器は呼び出しのたびに作り直される —— この ABI の粒度は 1 対の画像を処理することであって、照合器を保持することではない。 |
到達性 の列は、spec から生成される到達性テスト
(tests/UnityProject/Assets/Tests/Shared/AbiReachabilityChecks.g.cs)が
その宣言を実際に呼ぶかを示す。IL2CPP の stripping は呼ばれない P/Invoke
宣言を消せるので、呼ばれない宣言は消えても誰も気づかない。
到達性テストが呼ばない関数は 1 本ある。 理由は spec の
reachableNote にある(印だけ付けて理由が無い spec は生成器が拒む)。
ocvu_debug_crash—— 呼ぶと戻ってこない(kind 0 は即死、kind 1 は無限ループ)。到達性テストは全 entry point を 1 回ずつ呼ぶので、これを含めるとテストプロセスごと死ぬ。この 1 本だけは生成された呼び出しから外す。stripping で消えても壊れるものは無い —— 通常の経路から呼ぶ側が無く、L3 の test-managed-probe が名指しで P/Invoke するのは Player ではなく素の .NET だからである。