diff --git a/CMakeLists.txt b/CMakeLists.txt index bc0ba4f..65e8981 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ cmake_minimum_required(VERSION 3.5) -project(tensorrt_yolox) +project(ailia_yolox) if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 17) @@ -15,57 +15,31 @@ ament_auto_find_build_dependencies() find_package(OpenCV REQUIRED) ament_auto_add_library(${PROJECT_NAME} SHARED - src/tensorrt_yolox.cpp + src/ailia_yolox.cpp ) - -ament_target_dependencies(${PROJECT_NAME} - OpenCV -) - -target_compile_definitions(${PROJECT_NAME} PRIVATE - TENSORRT_VERSION_MAJOR=${TENSORRT_VERSION_MAJOR} +target_link_libraries(${PROJECT_NAME} + ${CMAKE_SOURCE_DIR}/lib/libailia.so + ${CMAKE_SOURCE_DIR}/lib/libailia_cuda-8.so ) - -ament_auto_add_library(yolox_single_image_inferece_node SHARED - src/yolox_single_image_inference_node.cpp +target_include_directories(${PROJECT_NAME} + PUBLIC include/ailia ) - -ament_target_dependencies(yolox_single_image_inferece_node +ament_target_dependencies(${PROJECT_NAME} OpenCV ) -target_link_libraries(yolox_single_image_inferece_node - ${PROJECT_NAME} - stdc++fs -) - -target_compile_definitions(yolox_single_image_inferece_node PRIVATE - TENSORRT_VERSION_MAJOR=${TENSORRT_VERSION_MAJOR} -) - -rclcpp_components_register_node(yolox_single_image_inferece_node - PLUGIN "tensorrt_yolox::YoloXSingleImageInferenceNode" - EXECUTABLE yolox_single_image_inferece -) - ament_auto_add_library(${PROJECT_NAME}_node SHARED - src/tensorrt_yolox_node.cpp + src/ailia_yolox_node.cpp ) - ament_target_dependencies(${PROJECT_NAME}_node OpenCV ) - target_link_libraries(${PROJECT_NAME}_node ${PROJECT_NAME} ) -target_compile_definitions(${PROJECT_NAME}_node PRIVATE - TENSORRT_VERSION_MAJOR=${TENSORRT_VERSION_MAJOR} -) - rclcpp_components_register_node(${PROJECT_NAME}_node - PLUGIN "tensorrt_yolox::TrtYoloXNode" + PLUGIN "ailia_yolox::AiliaYoloXNode" EXECUTABLE ${PROJECT_NAME}_node_exe ) diff --git a/include/ailia/ailia.h b/include/ailia/ailia.h new file mode 100644 index 0000000..4431df5 --- /dev/null +++ b/include/ailia/ailia.h @@ -0,0 +1,1566 @@ +/** + * \~japanese + * @file ailia.h + * @brief 推論ライブラリ + * @copyright AXELL CORPORATION, ax Inc. + * @date 2021/11/22 + * + * \~english + * @file ailia.h + * @brief inference library + * @copyright AXELL CORPORATION, ax Inc. + * @date Novemver 22, 2021 + */ + +#ifndef INCLUDED_AILIA +#define INCLUDED_AILIA + +/* 呼び出し規約 */ + +#if defined(_M_JS) + #include + #define AILIA_API EMSCRIPTEN_KEEPALIVE +#elif defined(_WIN64) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__APPLE__) || defined(__ANDROID__) || defined(ANDROID) || defined(__linux__) || defined(NN_NINTENDO_SDK) + #define AILIA_API +#else + #define AILIA_API __stdcall +#endif + +#include "ailia_call.h" + +#ifdef __cplusplus +extern "C" { +#endif + /**************************************************************** + * ライブラリ状態定義 + **/ + + /** + * \~japanese + * @def AILIA_STATUS_SUCCESS + * @brief 成功 + * + * \~english + * @def AILIA_STATUS_SUCCESS + * @brief Successful + */ + #define AILIA_STATUS_SUCCESS ( 0) + /** + * \~japanese + * @def AILIA_STATUS_INVALID_ARGUMENT + * @brief 引数が不正 + * @remark API呼び出し時の引数を確認してください。 + * + * \~english + * @def AILIA_STATUS_INVALID_ARGUMENT + * @brief Incorrect argument + * @remark Please check argument of called API. + */ + #define AILIA_STATUS_INVALID_ARGUMENT ( -1) + /** + * \~japanese + * @def AILIA_STATUS_ERROR_FILE_API + * @brief ファイルアクセスに失敗した + * @remark 指定したパスのファイルが存在するか、権限を確認してください。 + * + * \~english + * @def AILIA_STATUS_ERROR_FILE_API + * @brief File access failed. + * @remark Please check file is exist or not, and check access permission. + */ + #define AILIA_STATUS_ERROR_FILE_API ( -2) + /** + * \~japanese + * @def AILIA_STATUS_INVALID_VERSION + * @brief 構造体バージョンが不正 + * @remark API呼び出し時に指定した構造体バージョンを確認し、正しい構造体バージョンを指定してください。 + * + * \~english + * @def AILIA_STATUS_INVALID_VERSION + * @brief Incorrect struct version + * @remark Please check struct version that passed with API and please pass correct struct version. + */ + #define AILIA_STATUS_INVALID_VERSION ( -3) + /** + * \~japanese + * @def AILIA_STATUS_BROKEN + * @brief 壊れたファイルが渡された + * @remark モデルファイルが破損していないかを確認し、正常なモデルを渡してください。 + * + * \~english + * @def AILIA_STATUS_BROKEN + * @brief A corrupt file was passed. + * @remark Please check model file are correct or not, and please pass correct model. + */ + #define AILIA_STATUS_BROKEN ( -4) + /** + * \~japanese + * @def AILIA_STATUS_MEMORY_INSUFFICIENT + * @brief メモリが不足している + * @remark メインメモリやVRAMの空き容量を確保してからAPIを呼び出してください。 + * + * \~english + * @def AILIA_STATUS_MEMORY_INSUFFICIENT + * @brief Insufficient memory + * @remark Please check usage of main memory and VRAM. And please call API after free memory. + */ + #define AILIA_STATUS_MEMORY_INSUFFICIENT ( -5) + /** + * \~japanese + * @def AILIA_STATUS_THREAD_ERROR + * @brief スレッドの作成に失敗した + * @remark スレッド数などシステムリソースを確認し、リソースを開放してからAPIを呼び出してください。 + * + * \~english + * @def AILIA_STATUS_THREAD_ERROR + * @brief Thread creation failed. + * @remark Please check usage of system resource (e.g. thread). And please call API after release system resources. + */ + #define AILIA_STATUS_THREAD_ERROR ( -6) + /** + * \~japanese + * @def AILIA_STATUS_INVALID_STATE + * @brief ailia の内部状態が不正 + * @remark APIドキュメントを確認し、呼び出し手順が正しいかどうかを確認してください。 + * + * \~english + * @def AILIA_STATUS_INVALID_STATE + * @brief The internal status of the ailia is incorrect. + * @remark Please check API document and API call steps. + */ + #define AILIA_STATUS_INVALID_STATE ( -7) + /** + * \~japanese + * @def AILIA_STATUS_UNSUPPORT_NET + * @brief 非対応のネットワーク + * @remark Detectorなどのラッパー関数に非対応のモデルファイルが渡されました。ドキュメント記載のサポートモデルかどうかを確認してください。 + * + * \~english + * @def AILIA_STATUS_UNSUPPORT_NET + * @brief Unsupported network + * @remark Non supported model file was passed to wrapper functions (e.g. Detector). Please check document whether presented models are supported or not. + */ + #define AILIA_STATUS_UNSUPPORT_NET ( -9) + /** + * \~japanese + * @def AILIA_STATUS_INVALID_LAYER + * @brief レイヤーの重みやパラメータ、入出力形状が不正 + * @remark モデル中のレイヤーのパラメーターなどが不正でした。ailiaGetErrorDetail() で詳細なエラーメッセージを確認し、モデルファイルが正しいかを確認してください。 + * + * \~english + * @def AILIA_STATUS_INVALID_LAYER + * @brief Incorrect layer weight, parameter, or input or output shape + * @remark The layer of model had incorrect parameter or so on. Please call ailiaGetErrorDetail() and check detail message. And, please check model. + */ + #define AILIA_STATUS_INVALID_LAYER ( -10) + /** + * \~japanese + * @def AILIA_STATUS_INVALID_PARAMINFO + * @brief パラメータファイルの内容が不正 + * @remark 指定したパラメーターファイルが破損していないかどうかを確認してください。 + * + * \~english + * @def AILIA_STATUS_INVALID_PARAMINFO + * @brief The content of the parameter file is invalid. + * @remark Please check parameter file are correct or not. + */ + #define AILIA_STATUS_INVALID_PARAMINFO ( -11) + /** + * \~japanese + * @def AILIA_STATUS_NOT_FOUND + * @brief 指定した要素が見つからなかった + * @remark 指定した名前やindexの要素が見つかりませんでした。指定した要素がモデルに含まれているかを確認してください。 + * + * \~english + * @def AILIA_STATUS_NOT_FOUND + * @brief The specified element was not found. + * @remark The specified element of passed name/index was not found. Please check the element are exisit on model or not. + */ + #define AILIA_STATUS_NOT_FOUND ( -12) + /** + * \~japanese + * @def AILIA_STATUS_GPU_UNSUPPORT_LAYER + * @brief GPUで未対応のレイヤーパラメータが与えられた + * @remark GPUで実行できないレイヤーやパラメーターが与えられました。モデルファイルが正しいかどうかを確認した上で、ドキュメント記載のサポート窓口までお問い合わせください。 + * + * \~english + * @def AILIA_STATUS_GPU_UNSUPPORT_LAYER + * @brief A layer parameter not supported by the GPU was given. + * @remark The layer or parameter that not supported by the GPU was given. Please check model file are correct or not and contact support desk that described on document. + */ + #define AILIA_STATUS_GPU_UNSUPPORT_LAYER ( -13) + /** + * \~japanese + * @def AILIA_STATUS_GPU_ERROR + * @brief GPU上での処理中にエラー + * @remark 最新のGPUドライバーを利用しているか、VRAMが不足していないかなどを確認してください。 + * + * \~english + * @def AILIA_STATUS_GPU_ERROR + * @brief Error during processing on the GPU + * @remark Please check the GPU driver are latest and VRAM are sufficient or not. + */ + #define AILIA_STATUS_GPU_ERROR ( -14) + /** + * \~japanese + * @def AILIA_STATUS_UNIMPLEMENTED + * @brief 未実装 + * @remark 指定した環境では未実装な機能が呼び出されました。エラー内容をドキュメント記載のサポート窓口までお問い合わせください。 + * + * \~english + * @def AILIA_STATUS_UNIMPLEMENTED + * @brief Unimplemented error + * @remark The called API are not available on current environment. Please contact support desk that described on document. + */ + #define AILIA_STATUS_UNIMPLEMENTED ( -15) + /** + * \~japanese + * @def AILIA_STATUS_PERMISSION_DENIED + * @brief 許可されていない操作 + * @remark 暗号化モデルなどで許可されていないAPIが呼び出されました。モデルファイルを確認し、APIの呼び出しを変更してください。 + * + * \~english + * @def AILIA_STATUS_PERMISSION_DENIED + * @brief Operation not allowed + * @remark The called API are not allowed on this model (e.g. encrypted model are used.). Please check model file and change API call flow. + */ + #define AILIA_STATUS_PERMISSION_DENIED ( -16) + /** + * \~japanese + * @def AILIA_STATUS_EXPIRED + * @brief モデルの有効期限切れ + * @remark モデルファイルの有効期限が切れています。ailia_obfuscate_cを利用してモデルを再生成してください。 + * + * \~english + * @def AILIA_STATUS_EXPIRED + * @brief Model Expired + * @remark The model file are expired. Please re generate model with ailia_obfuscate_c. + */ + #define AILIA_STATUS_EXPIRED ( -17) + /** + * \~japanese + * @def AILIA_STATUS_UNSETTLED_SHAPE + * @brief 形状が未確定 + * @remark 出力形状などが不定形です。出力形状取得時に発生した場合は入力形状を指定した上で推論を行い、その後形状取得APIを呼び出してください。 + * + * \~english + * @def AILIA_STATUS_UNSETTLED_SHAPE + * @brief The shape is not yet determined + * @remark The shape (e.g. output shape) are not determined. When called API that to get output shape, please set input shape and execute inference, then call API that to get output shape. + */ + #define AILIA_STATUS_UNSETTLED_SHAPE ( -18) + /** + * \~japanese + * @def AILIA_STATUS_DATA_HIDDEN + * @brief アプリケーションからは取得できない情報だった + * @remark 最適化などで指定した要素が削除されています。情報を取得する場合、最適化を無効にしてから呼び出してください。 + * + * \~english + * @def AILIA_STATUS_DATA_HIDDEN + * @brief The information was not available from the application + * @remark The specified information was removed due to optimization. If you need the information, please disable optimization and call API. + */ + #define AILIA_STATUS_DATA_HIDDEN ( -19) + #define AILIA_STATUS_DATA_REMOVED AILIA_STATUS_DATA_HIDDEN + /** + * \~japanese + * @def AILIA_STATUS_LICENSE_NOT_FOUND + * @brief 有効なライセンスが見つからない + * @remark トライアル版を利用する場合はライセンスファイルが必要です。ライセンスファイルに関しましては、ドキュメント記載のサポート窓口までお問い合わせください。 + * + * \~english + * @def AILIA_STATUS_LICENSE_NOT_FOUND + * @brief No valid license found + * @remark The license file are required for trial version. Please contact support desk that described on document. + */ + #define AILIA_STATUS_LICENSE_NOT_FOUND ( -20) + /** + * \~japanese + * @def AILIA_STATUS_LICENSE_BROKEN + * @brief ライセンスが壊れている + * @remark トライアル版を利用する際に必要なライセンスファイルが破損しています。ライセンスファイルに関しましては、ドキュメント記載のサポート窓口までお問い合わせください。 + * + * \~english + * @def AILIA_STATUS_LICENSE_BROKEN + * @brief License is broken + * @remark The license file that are required for trial version are broken. Please contact support desk that described on document. + */ + #define AILIA_STATUS_LICENSE_BROKEN ( -21) + /** + * \~japanese + * @def AILIA_STATUS_LICENSE_EXPIRED + * @brief ライセンスの有効期限切れ + * @remark トライアル版を利用するのに必要なライセンスファイルの有効期限が切れています。ライセンスファイルに関しましては、ドキュメント記載のサポート窓口までお問い合わせください。 + * + * \~english + * @def AILIA_STATUS_LICENSE_EXPIRED + * @brief License expired + * @remark The license file that are required for trial version are expired. Please contact support desk that described on document. + * + */ + #define AILIA_STATUS_LICENSE_EXPIRED ( -22) + /** + * \~japanese + * @def AILIA_STATUS_NDIMENSION_SHAPE + * @brief 形状が5次元以上であることを示す + * @remark 4次元までしか扱えない旧APIが呼び出されました。APIドキュメントを参照し、5次元以上が扱えるAPIを利用してください。 + * + * \~english + * @def AILIA_STATUS_NDIMENSION_SHAPE + * @brief Dimension of shape is 5 or more. + * @remark The called API are supported up to 4 dimension. Please replace API that described on API document. + */ + #define AILIA_STATUS_NDIMENSION_SHAPE ( -23) + /** + * \~japanese + * @def AILIA_STATUS_OTHER_ERROR + * @brief 不明なエラー + * @remark その他のエラーが発生しました。ailiaGetErrorDetail() で詳細なエラーメッセージを確認し、エラー内容をドキュメント記載のサポート窓口までお問い合わせください。 + * + * \~english + * @def AILIA_STATUS_OTHER_ERROR + * @brief Unknown error + * @remark The misc error has been occured. Please call ailiaGetErrorDetail() and check detail message. And, please contact support desk that described on document. + */ + #define AILIA_STATUS_OTHER_ERROR (-128) + + /**************************************************************** + * ネットワークオブジェクトのインスタンス + **/ + + struct AILIANetwork; + + /**************************************************************** + * 形状情報 + **/ + + #define AILIA_SHAPE_VERSION (1) + + typedef struct _AILIAShape { + /** + * \~japanese + * X軸のサイズ + * + * \~english + * Size along the X axis + */ + unsigned int x; + /** + * \~japanese + * Y軸のサイズ + * + * \~english + * Size along the Y axis + */ + unsigned int y; + /** + * \~japanese + * Z軸のサイズ + * + * \~english + * Size along the Z axis + */ + unsigned int z; + /** + * \~japanese + * W軸のサイズ + * + * \~english + * Size along the W axis + */ + unsigned int w; + /** + * \~japanese + * 次元情報 + * + * \~english + * Dimension information + */ + unsigned int dim; + }AILIAShape; + + /**************************************************************** + * スレッド数 + **/ + + #define AILIA_MULTITHREAD_AUTO (0) + + /**************************************************************** + * 推論実行環境自動設定 + **/ + + #define AILIA_ENVIRONMENT_ID_AUTO (-1) + + /**************************************************************** + * 推論API + **/ + + /** + * \~japanese + * @brief ネットワークオブジェクトを作成します。 + * @param net ネットワークオブジェクトポインタへのポインタ + * @param env_id 計算に利用する推論実行環境のID( ailiaGetEnvironment() で取得) \ref AILIA_ENVIRONMENT_ID_AUTO にした場合は自動で選択する + * @param num_thread スレッド数の上限( \ref AILIA_MULTITHREAD_AUTO にした場合は自動で設定) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ネットワークオブジェクトを作成します。 + * 推論実行環境を自動にした場合はCPUモードになり、BLASが利用できる場合はBLASを利用します。 + * なお、BLASを利用する場合num_threadは無視される場合があります。 + * + * \~english + * @brief Creates a network instance. + * @param net A pointer to the network instance pointer + * @param env_id The ID of the inference backend used for computation (obtained by ailiaGetEnvironment() ). It is selected automatically if \ref AILIA_ENVIRONMENT_ID_AUTO is specified. + * @param num_thread The upper limit on the number of threads (It is set automatically if \ref AILIA_MULTITHREAD_AUTO is specified.) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * Creates a network instance. + * If the inference backend is set to automatic, CPU mode is used, while if BLAS is available, it uses BLAS. + * Note that if BLAS is used, num_thread may be ignored. + */ + int AILIA_API ailiaCreate(struct AILIANetwork **net, int env_id, int num_thread); + + /** + * \~japanese + * @brief ネットワークオブジェクトを初期化します。(ファイルから読み込み) + * @param net ネットワークオブジェクトポインタ + * @param path prototxtファイルのパス名(MBSC or UTF16) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ファイルから読み込み、ネットワークオブジェクトを初期化します。 + * + * \~english + * @brief Initializes the network instance. (Read from file) + * @param net A network instance pointer + * @param path The path name to the prototxt file (MBSC or UTF16) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function reads the network instance from a file and initializes it. + */ + int AILIA_API ailiaOpenStreamFileA(struct AILIANetwork *net, const char *path); + int AILIA_API ailiaOpenStreamFileW(struct AILIANetwork *net, const wchar_t *path); + + /** + * \~japanese + * @brief ネットワークオブジェクトを初期化します。(ユーザ定義ファイルアクセスコールバック) + * @param net ネットワークオブジェクトポインタ + * @param fopen_args \ref AILIA_USER_API_FOPEN に通知される引数ポインタ + * @param callback ユーザ定義ファイルアクセスコールバック関数構造体 + * @param version ファイルアクセスコールバック関数構造体のバージョン( \ref AILIA_FILE_CALLBACK_VERSION ) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ファイルから読み込み、ネットワークオブジェクトを初期化します。 + * + * \~english + * @brief Initializes the network instance. (User-defined file access callback) + * @param net A network instance pointer + * @param fopen_args An argument pointer supplied by AILIA_USER_API_FOPEN + * @param callback A struct for the user-defined file access callback function + * @param version The version of the struct for the file access callback function ( \ref AILIA_FILE_CALLBACK_VERSION ) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function reads the network instance from a file and initializes it. + */ + int AILIA_API ailiaOpenStreamEx(struct AILIANetwork *net, const void *fopen_args, ailiaFileCallback callback, int version); + + /** + * \~japanese + * @brief ネットワークオブジェクトを初期化します。(メモリから読み込み) + * @param net ネットワークオブジェクトポインタ + * @param buf prototxtファイルのデータへのポインタ + * @param buf_size prototxtファイルのデータサイズ + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * メモリから読み込み、ネットワークオブジェクトを初期化します。 + * + * \~english + * @brief Initializes the network instance. (Read from memory) + * @param net A network instance pointer + * @param buf A pointer to the data in the prototxt file + * @param buf_size The data size of the prototxt file + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function reads the network instance from memory and initializes it. + */ + int AILIA_API ailiaOpenStreamMem(struct AILIANetwork *net, const void *buf, unsigned int buf_size); + + /** + * \~japanese + * @brief ネットワークオブジェクトに重み係数を読み込みます。(ファイルから読み込み) + * @param net ネットワークオブジェクトポインタ + * @param path protobuf/onnxファイルのパス名(MBSC or UTF16) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ファイルからネットワークオブジェクトに重み係数を読み込みます。 + * + * \~english + * @brief Reads weights into a network instance. (Read from file) + * @param net A network instance pointer + * @param path The path name to the protobuf/onnx file (MBSC or UTF16) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function reads weights into the network instance from a file. + */ + int AILIA_API ailiaOpenWeightFileA(struct AILIANetwork *net, const char *path); + int AILIA_API ailiaOpenWeightFileW(struct AILIANetwork *net, const wchar_t *path); + + /** + * \~japanese + * @brief ネットワークオブジェクトに重み係数を読み込みます。(ユーザ定義ファイルアクセスコールバック) + * @param net ネットワークオブジェクトポインタ + * @param fopen_args \ref AILIA_USER_API_FOPEN に通知される引数ポインタ + * @param callback ユーザ定義ファイルアクセスコールバック関数構造体 + * @param version ファイルアクセスコールバック関数構造体のバージョン( \ref AILIA_FILE_CALLBACK_VERSION ) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ファイルからネットワークオブジェクトに重み係数を読み込みます。 + * + * \~english + * @brief Reads weights into a network instance. (User-defined file access callback) + * @param net A network instance pointer + * @param fopen_args An argument pointer supplied by AILIA_USER_API_FOPEN + * @param callback A struct for the user-defined file access callback function + * @param version The version of the struct for the file access callback function ( \ref AILIA_FILE_CALLBACK_VERSION ) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function reads weights into the network instance from a file. + */ + int AILIA_API ailiaOpenWeightEx(struct AILIANetwork *net, const void *fopen_args, ailiaFileCallback callback, int version); + + /** + * \~japanese + * @brief ネットワークオブジェクトに重み係数を読み込みます。(メモリから読み込み) + * @param net ネットワークオブジェクトポインタ + * @param buf protobuf/onnxファイルのデータへのポインタ + * @param buf_size protobuf/onnxファイルのデータサイズ + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * メモリからネットワークオブジェクトに重み係数を読み込みます。 + * + * \~english + * @brief Reads weights into a network instance. (Read from memory) + * @param net A network instance pointer + * @param buf A pointer to the data in the protobuf/onnx file + * @param buf_size The data size of the protobuf/onnx file + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function reads weights into the network instance from memory. + */ + int AILIA_API ailiaOpenWeightMem(struct AILIANetwork *net, const void *buf, unsigned int buf_size); + + /** + * \~japanese + * @brief ネットワークオブジェクトを破棄します。 + * @param net ネットワークオブジェクトポインタ + * + * \~english + * @brief It destroys the network instance. + * @param net A network instance pointer + */ + void AILIA_API ailiaDestroy(struct AILIANetwork *net); + + /** + * \~japanese + * @brief 推論時の入力データの形状を変更します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 入力データの形状情報 + * @param version AILIA_SHAPE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * prototxtで定義されている入力形状を変更します。 + * prototxtに記述されているランクと同じにする必要があります。 + * なお、重み係数の形状が入力形状に依存しているなどによりエラーが返る場合があります。 + * prototxtで定義されているランクが4次元未満の場合は未使用の要素に1を設定する必要があります。 + * prototxtで定義されているランクが5次元以上の場合は ailiaSetInputShapeND() を利用してください。 + * + * \~english + * @brief Changes the shape of the input data during inference. + * @param net A network instance pointer + * @param shape Shape information for the input data + * @param version AILIA_SHAPE_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function changes the input shape defined in prototxt. + * The shape must have the same rank as the one contained in prototxt. + * Note that an error may be returned if the weights are dependent on the input shapes, among other reasons. + * The dimension of shape that defined in prototxt is less than 4, the unused element must be set to 1. + * The dimension of shape that defined in prototxt has 5 or more, please use ailiaSetInputShapeND() (). + */ + int AILIA_API ailiaSetInputShape(struct AILIANetwork *net, const AILIAShape* shape, unsigned int version); + + /** + * \~japanese + * @brief 推論時の入力データの形状を変更します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 入力データの各次元の大きさの配列(dim-1, dim-2, ... ,1, 0) + * @param dim shapeの次元 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * prototxtで定義されている入力形状を変更します。 + * prototxtに記述されているランクと同じにする必要があります。 + * なお、重み係数の形状が入力形状に依存しているなどによりエラーが返る場合があります。 + * + * \~english + * @brief Changes the shape of the input data during inference. + * @param net A network instance pointer + * @param shape An array of shape that contains size of each axis (dim-1, dim-2, ... ,1, 0) + * @param dim The size of shape. + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function changes the input shape defined in prototxt. + * The shape must have the same rank as the one contained in prototxt. + * Note that an error may be returned if the weights are dependent on the input shapes, among other reasons. + */ + int AILIA_API ailiaSetInputShapeND(struct AILIANetwork* net, const unsigned int* shape, unsigned int dim); + + /** + * \~japanese + * @brief 推論時の入力データの形状を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 入力データの形状情報 + * @param version AILIA_SHAPE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、5次元以上の場合 \ref AILIA_STATUS_NDIMENSION_SHAPE 、 + * 形状の一部が未確定の場合 \ref AILIA_STATUS_UNSETTLED_SHAPE 、それ以外のエラーの場合はエラーコードを返す。 + * @details + * 形状が5次元以上の場合は ailiaGetInputDim() 、 ailiaGetInputShapeND() を利用してください。 + * 形状の一部が未確定の場合、該当する次元の値は0となり、それ以外の次元の値は有効な値が格納されます。 + * + * \~english + * @brief Gets the shape of the input data during inference. + * @param net A network instance pointer + * @param shape Shape information for the input data + * @param version AILIA_SHAPE_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS . + * If shape has 5 or more dimension, it returns \ref AILIA_STATUS_NDIMENSION_SHAPE . + * And if shape is not seattled, it returns \ref AILIA_STATUS_UNSETTLED_SHAPE , or an error code otherwise. + * @details + * When dimension of shape is 5 or more, please use ailiaGetInputDim() and ailiaGetInputShapeND(). + * When shape is not settled, this function stores 0 at unsettled dimension and otherwise stores valid value. + */ + int AILIA_API ailiaGetInputShape(struct AILIANetwork *net, AILIAShape* shape, unsigned int version); + + /** + * \~japanese + * @brief 推論時の入力データの次元を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param dim 入力データの次元の格納先 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、それ以外のエラーの場合はエラーコードを返す。 + * + * \~english + * @brief Gets the dimension of the input data during inference. + * @param net A network instance pointer + * @param dim The storage location of the dimension + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetInputDim(struct AILIANetwork* net, unsigned int* dim); + + /** + * \~japanese + * @brief 推論時の入力データの形状を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 入力データの各次元の大きさの格納先配列(dim-1, dim-2, ... ,1, 0順で格納) + * @param dim shapeの次元 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、形状の一部が未確定の場合 \ref AILIA_STATUS_UNSETTLED_SHAPE 、 + * それ以外のエラーの場合はエラーコードを返す。 + * @details + * 形状の一部が未確定の場合、該当する次元の値は0となり、それ以外の次元の値は有効な値が格納されます。 + * + * \~english + * @brief Gets the shape of the input data during inference. + * @param net A network instance pointer + * @param shape The storage location of the shape array. (It stores dim-1, dim-2, ... ,1, 0 order.) + * @param dim The size of shape + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS . + * And if shape is not seattled, it returns \ref AILIA_STATUS_UNSETTLED_SHAPE , or an error code otherwise. + * @details + * When shape is not settled, this function stores 0 at unsettled dimension and otherwise stores valid value. + */ + int AILIA_API ailiaGetInputShapeND(struct AILIANetwork* net, unsigned int* shape, unsigned int dim); + + /** + * \~japanese + * @brief 推論時の出力データの形状を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 出力データの形状情報 + * @param version AILIA_SHAPE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、5次元以上の場合 \ref AILIA_STATUS_NDIMENSION_SHAPE 、 + * それ以外のエラーの場合エラーコードを返す。 + * 形状が5次元以上の場合は ailiaGetOutputDim() 、 ailiaGetOutputShapeND() を利用してください。 + * + * \~english + * @brief Gets the shape of the output data during inference. + * @param net A network instance pointer + * @param shape Shape information of the output data + * @param version AILIA_SHAPE_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS . + * And if shape has 5 or more dimension, it returns \ref AILIA_STATUS_NDIMENSION_SHAPE , or an error code otherwise. + * @details + * When dimension of shape is 5 or more, please use ailiaGetOutputDim() () and ailiaGetOutputShapeND() (). + */ + int AILIA_API ailiaGetOutputShape(struct AILIANetwork *net, AILIAShape* shape, unsigned int version); + + /** + * \~japanese + * @brief 推論時の出力データの次元を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param dim 出力データの次元の格納先 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、それ以外のエラーの場合はエラーコードを返す。 + * + * \~english + * @brief Gets the dimension of the output data during inference. + * @param net A network instance pointer + * @param dim The storage location of the dimension + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetOutputDim(struct AILIANetwork* net, unsigned int* dim); + + /** + * \~japanese + * @brief 推論時の出力データの形状を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 出力データの各次元の大きさの格納先配列(dim-1, dim-2, ... ,1, 0順で格納) + * @param dim shapeの次元 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、それ以外のエラーの場合はエラーコードを返す。 + * + * \~english + * @brief Gets the shape of the output data during inference. + * @param net A network instance pointer + * @param shape The storage location of the shape array. (It stores dim-1, dim-2, ... ,1, 0 order.) + * @param dim The size of shape + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetOutputShapeND(struct AILIANetwork* net, unsigned int* shape, unsigned int dim); + + + /** + * \~japanese + * @brief 推論を行い推論結果を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param dest 推論結果の書き出し先バッファにX,Y,Z,Wの順でnumeric型で格納 サイズはネットファイルのoutputSizeとなる + * @param dest_size 推論結果の書き出し先バッファのbyte数 + * @param src 推論データ X,Y,Z,Wの順でnumeric型で格納 サイズはネットファイルのinputSizeとなる + * @param src_size 推論データのbyte数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Performs the inferences and provides the inference result. + * @param net A network instance pointer + * @param dest The result is stored in the inference result destination buffer as numeric type data in the order of X, Y, Z, and W. The buffer has the same size as the network file outputSize. + * @param dest_size The number of bytes for the destination buffer for the inference result + * @param src The input is stored as numeric type data in the order of the inference data X, Y, Z, and W. The input has the same size as the network file inputSize. + * @param src_size The number of bytes of the inference data + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPredict(struct AILIANetwork *net, void * dest, unsigned int dest_size, const void *src, unsigned int src_size); + + /**************************************************************** + * 状態取得API + **/ + + /** + * \~japanese + * @brief 推論時の内部データ(Blob)の数を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param blob_count blobの数の格納先 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the amount of internal data (blob) during inference. + * @param net A network instance pointer + * @param blob_count Storage location of the number of blobs + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetBlobCount(struct AILIANetwork *net, unsigned int *blob_count); + + /** + * \~japanese + * @brief 推論時の内部データ(Blob)の形状を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param shape データの形状情報の格納先 + * @param blob_idx blobのインデックス (0~ ailiaGetBlobCount() -1) + * @param version AILIA_SHAPE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、5次元以上の場合 \ref AILIA_STATUS_NDIMENSION_SHAPE 、 + * それ以外のエラーの場合はエラーコードを返す。 + * @details + * 形状が5次元以上の場合は ailiaGetBlobDim() 、 ailiaGetBlobShapeND() を利用してください。 + * + * \~english + * @brief Gets the shape of the internal data (blob) during inference. + * @param net A network instance pointer + * @param shape Storage location of the data shape information + * @param blob_idx The index of the blob (0 to ailiaGetBlobCount() -1) + * @param version AILIA_SHAPE_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS . + * And if shape has 5 or more dimension, it returns \ref AILIA_STATUS_NDIMENSION_SHAPE , or an error code otherwise. + * @details + * When dimension of shape is 5 or more, please use ailiaGetBlobDim() and ailiaGetBlobShapeND(). + */ + int AILIA_API ailiaGetBlobShape(struct AILIANetwork *net, AILIAShape* shape, unsigned int blob_idx, unsigned int version); + + /** + * \~japanese + * @brief 推論時の内部データ(Blob)の次元を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param dim blobの次元の格納先 + * @param blob_idx blobのインデックス (0~ ailiaGetBlobCount() -1) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、それ以外のエラーの場合はエラーコードを返す。 + * + * \~english + * @brief Gets the dimension of the internal data (blob) during inference. + * @param net A network instance pointer + * @param dim The storage location of the dimension + * @param blob_idx The index of the blob (0 to ailiaGetBlobCount() -1) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetBlobDim(struct AILIANetwork* net, unsigned int* dim, unsigned int blob_idx); + + /** + * \~japanese + * @brief 推論時の内部データ(Blob)の形状を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param shape blobの各次元の大きさの格納先配列(dim-1, dim-2, ... ,1, 0順で格納) + * @param dim shapeの次元 + * @param blob_idx blobのインデックス (0~ ailiaGetBlobCount() -1) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、それ以外のエラーの場合はエラーコードを返す。 + * + * \~english + * @brief Gets the amount of internal data (blob) during inference. + * @param net A network instance pointer + * @param shape The storage location of the shape array. (It stores dim-1, dim-2, ... ,1, 0 order.) + * @param dim The size of shape + * @param blob_idx The index of the blob (0 to ailiaGetBlobCount() -1) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetBlobShapeND(struct AILIANetwork* net, unsigned int* shape, unsigned int dim, unsigned int blob_idx); + + /** + * \~japanese + * @brief 推論時の内部データ(Blob)を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param dest 推論結果の書き出し先バッファにX,Y,Z,Wの順でnumeric型で格納 + * @param dest_size 推論結果の書き出し先バッファのbyte数 + * @param blob_idx blobのインデックス (0~ ailiaGetBlobCount() -1) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ailiaPredict() または ailiaUpdate() を一度も実行していない場合は \ref AILIA_STATUS_INVALID_STATE が返ります。 + * + * \~english + * @brief Gets the internal data (blob) during inference. + * @param net A network instance pointer + * @param dest The result is stored in the inference result destination buffer as numeric type data in the order of X, Y, Z, and W. + * @param dest_size The number of bytes for the inference result destination buffer + * @param blob_idx The index of the blob (0 to ailiaGetBlobCount() -1) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * If ailiaPredict() or ailiaUpdate() is not run at all, the function returns \ref AILIA_STATUS_INVALID_STATE . + */ + int AILIA_API ailiaGetBlobData(struct AILIANetwork *net, void* dest, unsigned int dest_size, unsigned int blob_idx); + + /** + * \~japanese + * @brief 推論時の内部データ(Blob)のインデックスを名前で探し取得します。 + * @param net ネットワークオブジェクトポインタ + * @param blob_idx blobのインデックス (0~ ailiaGetBlobCount() -1) + * @param name 検索するBlob名 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Searches by name for the index of the internal data (blob) during inference and returns it. + * @param net A network instance pointer + * @param blob_idx The index of the blob (0 to ailiaGetBlobCount() -1) + * @param name The name of the blob to search for + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaFindBlobIndexByName(struct AILIANetwork *net, unsigned int* blob_idx, const char* name); + + /** + * \~japanese + * @brief 内部データ(Blob)の名前の出力に必要なバッファのサイズを取得します。 + * @param net ネットワークオブジェクトポインタ + * @param blob_idx blobのインデックス (0~ ailiaGetBlobCount() -1) + * @param buffer_size Blob名の出力に必要なバッファのサイズ(終端null文字分を含む) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the size of the buffer needed for output of the name of the internal data (blob). + * @param net A network instance pointer + * @param blob_idx The index of the blob (0 to ailiaGetBlobCount() -1) + * @param buffer_size The size of the buffer needed for output of the blob name (including the null terminator) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetBlobNameLengthByIndex(struct AILIANetwork *net, const unsigned int blob_idx, unsigned int* buffer_size); + + /** + * \~japanese + * @brief 推論時の内部データ(Blob)の名前をインデックスで探し取得します。 + * @param net ネットワークオブジェクトポインタ + * @param buffer Blob名の出力先バッファ + * @param buffer_size バッファのサイズ(終端null文字分を含む) + * @param blob_idx 検索するblobのインデックス + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Searches by index for the name of the internal data (blob) during inference and returns it. + * @param net A network instance pointer + * @param buffer The output destination buffer for the blob name + * @param buffer_size The size of the buffer (including the null terminator) + * @param blob_idx The index of the blob to search for + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaFindBlobNameByIndex(struct AILIANetwork *net, char* buffer, const unsigned int buffer_size, const unsigned int blob_idx); + + /** + * \~japanese + * @brief ネットワークSummary用に必要なバッファのサイズを取得します。 + * @param net ネットワークオブジェクトポインタ + * @param buffer_size バッファのサイズの格納先(終端null文字分を含む) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the size of the buffer needed for the network summary. + * @param net A network instance pointer + * @param buffer_size The storage location of the buffer size (including the null terminator) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetSummaryLength(struct AILIANetwork * net, unsigned int * buffer_size); + + /** + * \~japanese + * @brief 各Blobの名前と形状を表示します。 + * @param net ネットワークオブジェクトポインタ + * @param buffer Summaryの出力先 + * @param buffer_size 出力バッファのサイズ(終端null文字分を含む)。 ailiaGetSummaryLength() で取得した値を設定してください。 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Shows the name and shape of each blob. + * @param net A network instance pointer + * @param buffer The output destination of the summary + * @param buffer_size The size of the output buffer (including the null terminator). Set the value obtained by ailiaGetSummaryLength() . + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaSummary(struct AILIANetwork * net, char* const buffer, const unsigned int buffer_size); + + /**************************************************************** + * 複数入力指定・推論API + **/ + + /** + * \~japanese + * @brief 入力データ(Blob)の数を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param input_blob_count 入力blobの数の格納先 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Get the number of input data blobs. + * @param net A network instance pointer + * @param input_blob_count Storage location of the number of input blobs + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetInputBlobCount(struct AILIANetwork *net, unsigned int *input_blob_count); + + /** + * \~japanese + * @brief 入力データ(Blob)のインデックスを取得します + * @param net ネットワークオブジェクトポインタ + * @param blob_idx blobのインデックス(0~ ailiaGetBlobCount() -1) + * @param input_blob_idx 入力blob内でのインデックス(0~ ailiaGetInputBlobCount() -1) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Get the blob index of the input data. + * @param net A network instance pointer + * @param blob_idx index of the blob (between 0 and ailiaGetBlobCount() -1) + * @param input_blob_idx index among the input blobs (between 0 and ailiaGetInputBlobCount() -1) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetBlobIndexByInputIndex(struct AILIANetwork *net, unsigned int *blob_idx, unsigned int input_blob_idx); + + /** + * \~japanese + * @brief 指定したBlobに入力データを与えます。 + * @param net ネットワークオブジェクトポインタ + * @param src 推論データ X,Y,Z,Wの順でnumeric型で格納 + * @param src_size 推論データのbyte数 + * @param blob_idx 入力するblobのインデックス + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 複数入力があるネットワークなどで入力を指定する場合に用います。 + * blob_idxで入力レイヤーのblob以外のものを指定した場合、 \ref AILIA_STATUS_INVALID_ARGUMENT が返ります。 + * + * \~english + * @brief Provides the specified blob with the input data. + * @param net A network instance pointer + * @param src The inference data is stored as numeric type data in the order of X, Y, Z, and W. + * @param src_size The number of bytes of the inference data + * @param blob_idx The index of the blob for input + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function is used to specify the input on networks with multiple inputs. + * If something other than a blob in the input layer is specified for blob_idx, the function returns \ref AILIA_STATUS_INVALID_ARGUMENT . + */ + int AILIA_API ailiaSetInputBlobData(struct AILIANetwork *net, const void* src, unsigned int src_size, unsigned int blob_idx); + + /** + * \~japanese + * @brief 指定したBlobの形状を変更します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 入力データの形状情報 + * @param blob_idx 変更するblobのインデックス + * @param version AILIA_SHAPE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 複数入力があるネットワークなどで入力形状を変更する場合に用います。 + * blob_idxは入力レイヤーのblob以外のものを指定した場合 \ref AILIA_STATUS_INVALID_ARGUMENT が返ります。 + * その他の注意点は ailiaSetInputShape() の解説を参照してください。 + * 入力形状のランクが5次元以上の場合は ailiaSetInputBlobShapeND() を利用してください。 + * + * \~english + * @brief Change the shape of the blob given by its index + * @param net network object pointer + * @param shape new shape of the blob + * @param blob_idx index referencing the blob to reshape + * @param version AILIA_SHAPE_VERSION + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and otherwise the coresponding error code. + * @details + * This is useful to change the network input shape in a context where there are several input blobs. + * If blob_idx does not correspond to an input layer, \ref AILIA_STATUS_INVALID_ARGUMENT is returned. + * For other related remarks, see the documentation of ailiaSetInputShape(). + * If dimension of shape has 5 or more, please use ailiaSetInputBlobShapeND(). + */ + int AILIA_API ailiaSetInputBlobShape(struct AILIANetwork *net, const AILIAShape* shape, unsigned int blob_idx, unsigned int version); + + + /** + * \~japanese + * @brief 指定したBlobの形状を変更します。 + * @param net ネットワークオブジェクトポインタ + * @param shape 入力データの各次元の大きさの配列(dim-1, dim-2, ... ,1, 0) + * @param dim shapeの次元 + * @param blob_idx 変更するblobのインデックス + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 複数入力があるネットワークなどで入力形状を変更する場合に用います。 + * blob_idxは入力レイヤーのblob以外のものを指定した場合 \ref AILIA_STATUS_INVALID_ARGUMENT が返ります。 + * その他の注意点は ailiaSetInputShapeND() の解説を参照してください。 + * + * \~english + * @brief Change the shape of the blob given by its index + * @param net network object pointer + * @param shape An array of shape that contains size of each axis (dim-1, dim-2, ... ,1, 0) + * @param dim The size of shape. + * @param blob_idx index referencing the blob to reshape + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and otherwise the coresponding error code. + * @details + * This is useful to change the network input shape in a context where there are several input blobs. + * If blob_idx does not correspond to an input layer, \ref AILIA_STATUS_INVALID_ARGUMENT is returned. + * For other related remarks, see the documentation of ailiaSetInputShapeND(). + */ + int AILIA_API ailiaSetInputBlobShapeND(struct AILIANetwork* net, const unsigned* shape, const unsigned dim, unsigned int blob_idx); + + /** + * \~japanese + * @brief 事前に指定した入力データで推論を行います。 + * @param net ネットワークオブジェクトポインタ + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ailiaSetInputBlobData() を用いて入力を与えた場合などに用います。 + * 推論結果は ailiaGetBlobData() で取得してください。 + * + * \~english + * @brief Makes inferences with the input data specified in advance. + * @param net A network instance pointer + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function is used when, for example, the input is provided with ailiaSetInputBlobData() . + * Get the inference result with ailiaGetBlobData() . + */ + int AILIA_API ailiaUpdate(struct AILIANetwork *net); + + /** + * \~japanese + * @brief 出力データ(Blob)の数を取得します。 + * @param net ネットワークオブジェクトポインタ + * @param output_blob_count 出力blobの数の格納先 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Get the number of output data blobs. + * @param net A network instance pointer + * @param output_blob_count Storage location for the number of output blobs. + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetOutputBlobCount(struct AILIANetwork *net, unsigned int *output_blob_count); + + /** + * \~japanese + * @brief 出力データ(Blob)のインデックスを取得します + * @param net ネットワークオブジェクトポインタ + * @param blob_idx blobのインデックス(0~ ailiaGetBlobCount() -1) + * @param output_blob_idx 出力blob内でのインデックス(0~ ailiaGetOutputBlobCount() -1) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Get the blob index of the input data blob. + * @param net A network instance pointer + * @param blob_idx blob index (between 0 and ailiaGetBlobCount() -1) + * @param output_blob_idx index among output blobs (between 0 and ailiaGetOutputBlobCount() -1) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetBlobIndexByOutputIndex(struct AILIANetwork *net, unsigned int *blob_idx, unsigned int output_blob_idx); + + /**************************************************************** + * 推論実行環境取得・指定API + **/ + + #define AILIA_ENVIRONMENT_VERSION (2) + + #define AILIA_ENVIRONMENT_TYPE_CPU (0) + #define AILIA_ENVIRONMENT_TYPE_BLAS (1) + #define AILIA_ENVIRONMENT_TYPE_GPU (2) + #define AILIA_ENVIRONMENT_TYPE_REMOTE (3) + + #define AILIA_ENVIRONMENT_BACKEND_NONE (0) + #define AILIA_ENVIRONMENT_BACKEND_AMP (1) + #define AILIA_ENVIRONMENT_BACKEND_CUDA (2) + #define AILIA_ENVIRONMENT_BACKEND_MPS (3) + #define AILIA_ENVIRONMENT_BACKEND_VULKAN (6) + + #define AILIA_ENVIRONMENT_PROPERTY_NORMAL (0) + /** + * \~japanese + * 省電力なGPU(内蔵GPUなど)を用いることを示す(MPS用) + * + * \~english + * Indicates that a low-power GPU (e.g. integrated GPU) will be preferentially used. (for MPS) + */ + #define AILIA_ENVIRONMENT_PROPERTY_LOWPOWER (1) + /** + * \~japanese + * FP16で動作することを示す + * + * \~english + * Indicates that a FP16 mode + */ + #define AILIA_ENVIRONMENT_PROPERTY_FP16 (2) + + typedef struct _AILIAEnvironment { + /** + * \~japanese + * 環境を識別するID( ailiaCreate() の引数に与える) + * + * \~english + * The ID to identify the inference backend (passed to ailiaCreate() as an argument) + */ + int id; + /** + * \~japanese + * 環境の種別( \ref AILIA_ENVIRONMENT_TYPE_CPU or BLAS or GPU) + * + * \~english + * The type of the inference backend ( \ref AILIA_ENVIRONMENT_TYPE_CPU , BLAS, or GPU) + */ + int type; + /** + * \~japanese + * デバイス名(シングルトンで保持されており開放不要)(ASCII) + * + * \~english + * The device name. It is valid until the AILIANetwork instance is destroyed. + */ + const char* name; + /** + * \~japanese + * 環境のバックエンド (AILIA_ENVIRONMENT_BACKEND_*) + * + * \~english + * Computational (hardware) backend enabled by this environment (AILIA_ENVIRONMENT_BACKEND_*) + */ + int backend; + /** + * \~japanese + * 環境の特性などを示す(AILIA_ENVIRONMENT_PROPERTY_* の論理和) + * + * \~english + * Additional property (low-power etc) of the environment (Logical-OR of AILIA_ENVIRONMENT_PROPERTY_*) + */ + int props; + }AILIAEnvironment; + + /** + * \~japanese + * @brief 一時キャッシュディレクトリを指定します + * @param cache_dir 一時キャッシュディレクトリ + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 指定したキャッシュディレクトリは推論実行環境毎に最適化したマシンコードを生成して保存するためにシステムが利用します。 + * ailia の実行開始時に一度だけ呼び出してください。二回目以降の呼び出しに対しては無視して成功を返します。 + * 複数スレッドから呼び出された場合も内部で排他制御しているので特に問題は発生しません。 + * Vulkan のシェーダーキャッシュ機能など、この API を呼ぶまで利用できないものがあります。 + * cache_dirにはContext.getCacheDir()で取得したファイルパスを指定してください。 + * + * \~english + * @brief Specifies a temporary cache directory. + * @param cache_dir Temporary cache directory + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This system uses the specified cache directory to generate and store machine code optimized for each inference backend. + * Call only once at the start of execution of ailia. It ignores any second and subsequent calls, and automatically returns success. + * There is no particular problem if it is called from multiple threads, as it provides exclusive control internally. + * Some functions, such as Vulkan shader cache, cannot be used until this API function is called. + * Specify the file path obtained by Context.getCacheDir() for cache_dir. + */ + int AILIA_API ailiaSetTemporaryCachePathA(const char * cache_dir); + int AILIA_API ailiaSetTemporaryCachePathW(const wchar_t * cache_dir); + + /** + * \~japanese + * @brief 利用可能な計算環境(CPU, GPU)の数を取得します + * @param env_count 計算環境情報の数の格納先 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the number of available computational environments (CPU, GPU). + * @param env_count The storage location of the number of computational environment information + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetEnvironmentCount(unsigned int * env_count); + + /** + * \~japanese + * @brief 計算環境の一覧を取得します + * @param env 計算環境情報の格納先(AILIANetworkインスタンスを破棄するまで有効) + * @param env_idx 計算環境情報のインデックス(0~ ailiaGetEnvironmentCount() -1) + * @param version AILIA_ENVIRONMENT_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the list of computational environments. + * @param env The storage location of the computational environment information (valid until the AILIANetwork instance is destroyed) + * @param env_idx The index of the computational environment information (0 to ailiaGetEnvironmentCount() -1) + * @param version AILIA_ENVIRONMENT_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetEnvironment(AILIAEnvironment** env, unsigned int env_idx, unsigned int version); + + /** + * \~japanese + * @brief 選択された計算環境を取得します + * @param net ネットワークオブジェクトポインタ + * @param env 計算環境情報の格納先(AILIANetworkインスタンスを破棄するまで有効) + * @param version AILIA_ENVIRONMENT_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the selected computational environment. + * @param net A network instance pointer + * @param env The storage location of the computational environment information (valid until the AILIANetwork instance is destroyed) + * @param version AILIA_ENVIRONMENT_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaGetSelectedEnvironment(struct AILIANetwork *net, AILIAEnvironment** env, unsigned int version); + + /**************************************************************** + * メモリモードAPI + **/ + + /** + * \~japanese + * 中間バッファーの開放は行わない + * + * \~english + * Do not release the intermediate buffer + */ + #define AILIA_MEMORY_NO_OPTIMIZATION (0) + /** + * \~japanese + * 重みなどの定数となる中間バッファーを開放する + * + * \~english + * Releases the intermediate buffer that is a constant such as weight + */ + #define AILIA_MEMORY_REDUCE_CONSTANT (1) + /** + * \~japanese + * 入力指定のinitializerを変更不可にし、重みなどの定数となる中間バッファーを開放する + * + * \~english + * Disable the input specified initializer and release the intermediate buffer that becomes a constant such as weight. + */ + #define AILIA_MEMORY_REDUCE_CONSTANT_WITH_INPUT_INITIALIZER (2) + /** + * \~japanese + * 推論時の中間バッファーを開放する + * + * \~english + * Release intermediate buffer during inference + */ + #define AILIA_MEMORY_REDUCE_INTERSTAGE (4) + /** + * \~japanese + * 中間バッファーを共有して推論する。 \ref AILIA_MEMORY_REDUCE_INTERSTAGE と併用した場合、共有可能な中間バッファーは開放しない。 + * + * \~english + * Infer by sharing the intermediate buffer. When used with \ref AILIA_MEMORY_REDUCE_INTERSTAGE , the sharable intermediate buffer is not opened. + */ + #define AILIA_MEMORY_REUSE_INTERSTAGE (8) + + #define AILIA_MEMORY_OPTIMAIZE_DEFAULT (AILIA_MEMORY_REDUCE_CONSTANT) + + /** + * \~japanese + * @brief 推論時のメモリの使用方針を設定します + * @param net ネットワークオブジェクトポインタ + * @param mode メモリモード(論理和で複数指定可) AILIA_MEMORY_XXX (デフォルト: \ref AILIA_MEMORY_REDUCE_CONSTANT ) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * メモリの使用方針を変更します。 \ref AILIA_MEMORY_NO_OPTIMIZATION 以外を指定した場合は、 + * 推論時に確保する中間バッファーを開放するため、推論時のメモリ使用量を削減することができます。 + * ailiaCreate() の直後に指定する必要があります。ailiaOpenを呼び出した後は変更することができません。 + * なお、中間バッファーを開放するように指定した場合、該当するBlobに対し、 ailiaGetBlobData() を呼び出すと + * \ref AILIA_STATUS_DATA_HIDDEN エラーが返ります。 + * + * \~english + * @brief Set the memory usage policy for inference + * @param net A network instance pointer + * @param mode Memory mode (Multiple specifications possible with logical sum) AILIA_MEMORY_XXX (Default : \ref AILIA_MEMORY_REDUCE_CONSTANT ) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * Change the memory usage policy. + * If a value other than \ref AILIA_MEMORY_NO_OPTIMIZATION is specified, + * the intermediate buffer secured during inference will be released, so the memory usage during inference can be reduced. + * Must be specified immediately after ailiaCreate() . It cannot be changed after calling ailiaOpen. + * If you specify to release the intermediate buffer, calling ailiaGetBlobData() for the corresponding blob will return an \ref AILIA_STATUS_DATA_HIDDEN error. + */ + int AILIA_API ailiaSetMemoryMode(struct AILIANetwork* net, unsigned int mode); + + /**************************************************************** + * 最適化制御API + **/ + + /** + * \~japanese + * @brief 推論時のレイヤー統合を無効化します + * @param net ネットワークオブジェクトポインタ + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * レイヤー統合により取得できなくなるBlobを取得する必要がある場合などに用います。 + * ailiaCreate() の直後に指定する必要があります。ailiaOpenを呼び出した後は変更することができません。 + * なお、レイヤー統合を無効化すると推論速度が低下する場合があります。 + * + * \~english + * @brief Disalbe layer fusion optimaization for inference + * @param net A network instance pointer + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This api use to get blob that remove by layer fusion optimization. + * Must be specified immediately after ailiaCreate() . It cannot be changed after calling ailiaOpen. + * Note: When disable layer fusion optimization, inference speed may be down. + */ + int AILIA_API ailiaDisableLayerFusion(struct AILIANetwork* net); + + /**************************************************************** + * プロファイルモードAPI + **/ + + /** + * \~japanese + * プロファイルモードを無効にします(デフォルト) + * + * \~english + * Disable profile mode (Default) + */ + #define AILIA_PROFILE_DISABLE (0x00) + /** + * \~japanese + * レイヤー別の処理時間を計測します。複数回推論した場合は平均値が保存されます。 + * + * \~english + * Measure the processing time for each layer. + * If you infer multiple times, the average value excluding the first execution is saved. + */ + #define AILIA_PROFILE_AVERAGE (0x01) + + /** + * \~japanese + * @brief プロファイルモードをセットします + * @param net ネットワークオブジェクトポインタ + * @param mode プロファイルモード + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * プロファイルモードを指定します。デフォルトは無効です。 + * ailiaOpenStreamXXXを呼び出したあとに呼び出してください。 + * プロファイルモードを有効にした場合、 ailiaSummary() の出力にプロファイル結果が追加されます。 + * + * \~english + * @brief Set the profile mode. + * @param net The network instance pointer + * @param mode Profile mode AILIA_PROFILE_XXX (Default : \ref AILIA_PROFILE_DISABLE ) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * Set the profile mode. The default is profile disabled. + * Call it after calling ailiaOpenStreamXXX. + * When profile mode is enabled, you can get profile result via ailiaSummary() . + */ + int AILIA_API ailiaSetProfileMode(struct AILIANetwork * net, unsigned int mode); + + /**************************************************************** + * 情報取得API + **/ + + /** + * \~japanese + * @brief ステータスコードに対応する文字列を返します。 + * @return + * ステータスコードに対応する文字列。 + * @details + * 返値は解放する必要はありません。 + * 返された文字列は ailia のライブラリ(ailia.dll, libailia.so 等)をアンロードするまで有効です。 + * AILIANetwork のインスタンスがある場合は ailiaGetErrorDetail() でエラーの詳細を取得できます。 + * + * \~english + * @brief Returns the string describing given status code. + * @return + * String describing given status code. + * Retuned string is valid until the library of ailia (ailia.dll, libailia.so, etc) is unloaded. + * @details + * The return value does not have to be released. + * If an instance of AILIANetwork is exist, ailiaGetErrorDetail() can be used to get the detail of the error. + */ + const char * AILIA_API ailiaGetStatusString(int status_code); + + /** + * \~japanese + * @brief エラーの詳細を返します + * @return + * エラー詳細 + * @details + * 返値は解放する必要はありません。 + * 文字列の有効期間は次にailiaのAPIを呼ぶまでです。 + * モデルが暗号化されている場合は空文字を返します。 + * + * \~english + * @brief Returns the details of errors. + * @return + * Error details + * @details + * The return value does not have to be released. + * The string is valid until the next ailia API function is called. + * If model is encrypted, this function returns empty string. + */ + const char * AILIA_API ailiaGetErrorDetail(struct AILIANetwork *net); + + /** + * \~japanese + * @brief ライブラリバージョンを取得します + * @return + * バージョン番号 + * @details + * 返値は解放する必要はありません。 + * + * \~english + * @brief Get the version of the library. + * @return + * Version number + * @details + * The return value does not have to be released. + */ + const char* AILIA_API ailiaGetVersion(void); + + #ifdef UNICODE + #define ailiaOpenStreamFile ailiaOpenStreamFileW + #define ailiaOpenWeightFile ailiaOpenWeightFileW + #define ailiaSetTemporaryCachePath ailiaSetTemporaryCachePathW + #else + #define ailiaOpenStreamFile ailiaOpenStreamFileA + #define ailiaOpenWeightFile ailiaOpenWeightFileA + #define ailiaSetTemporaryCachePath ailiaSetTemporaryCachePathA + #endif + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA) */ diff --git a/include/ailia/ailia_audio.h b/include/ailia/ailia_audio.h new file mode 100644 index 0000000..62f7374 --- /dev/null +++ b/include/ailia/ailia_audio.h @@ -0,0 +1,969 @@ +/** + * \~japanese + * @file ailia_audio.h + * @brief 音響信号処理用ライブラリ + * @copyright AXELL CORPORATION, ax Inc. + * @date 2021/07/28 + * + * \~english + * @file ailia_audio.h + * @brief audio processing library + * @copyright AXELL CORPORATION, ax Inc. + * @date 2021/07/28 + */ + +#if !defined(INCLUDED_AILIA_AUDIO) +#define INCLUDED_AILIA_AUDIO + +#if !defined(AILIA_API) + #if defined(_MSC_VER) && !defined(_WIN64) + #define AILIA_API __stdcall + #else + #define AILIA_API + #endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * \~japanese + * @def AILIA_AUDIO_WIN_TYPE_HANN + * @brief 窓関数に hann 窓を使う + * + * \~english + * @def AILIA_AUDIO_WIN_TYPE_HANN + * @brief use a Hann window function + */ + #define AILIA_AUDIO_WIN_TYPE_HANN (1) + /** + * \~japanese + * @def AILIA_AUDIO_WIN_TYPE_HAMMING + * @brief 窓関数に hamming 窓を使う + * + * \~english + * @def AILIA_AUDIO_WIN_TYPE_HAMMING + * @brief use a Hamming window function + */ + #define AILIA_AUDIO_WIN_TYPE_HAMMING (2) + + /** + * \~japanese + * @def AILIA_AUDIO_STFT_CENTER_NONE + * @brief STFT の際、前後に padding を入れない + * + * \~english + * @def AILIA_AUDIO_STFT_CENTER_NONE + * @brief for the STFT, do not insert padding before and after + */ + #define AILIA_AUDIO_STFT_CENTER_NONE (0) + /** + * \~japanese + * @def AILIA_AUDIO_STFT_CENTER_ENABLE + * @brief STFT の際、sample_n の前後に fft_n/2 の padding(reflect) を入れる + * + * \~english + * @def AILIA_AUDIO_STFT_CENTER_ENABLE + * @brief for the STFT, insert a padding (reflect) of fft_n/2 before and after the sample_n samples + */ + #define AILIA_AUDIO_STFT_CENTER_ENABLE (1) + /** + * \~japanese + * @def AILIA_AUDIO_STFT_CENTER_SCIPY_DEFAULT + * @brief STFT の際、sample_n の前後に fft_n/2 の padding(zero) を入れ、さらにhop_n処理単位になるように後方padding(zero)で合わせる + * + * \~english + * @def AILIA_AUDIO_STFT_CENTER_SCIPY_DEFAULT + * @brief for the STFT, insert a padding (zeros) of fft_n/2 before and after the sample_n samples, and also pad at the end with zeros to process in units of hop_n + */ + #define AILIA_AUDIO_STFT_CENTER_SCIPY_DEFAULT (2) + + /** + * \~japanese + * @def AILIA_AUDIO_FFT_NORMALIZE_NONE + * @brief FFT の出力を正規化しない + * + * \~english + * @def AILIA_AUDIO_FFT_NORMALIZE_NONE + * @brief Do not normalize the FFT output + */ + #define AILIA_AUDIO_FFT_NORMALIZE_NONE (0) + /** + * \~japanese + * @def AILIA_AUDIO_FFT_NORMALIZE_LIBROSA_COMPAT + * @brief FFT の出力を librosa 互換で正規化する + * + * \~english + * @def AILIA_AUDIO_FFT_NORMALIZE_LIBROSA_COMPAT + * @brief Normalize the FFT output in a way compatible with librosa + */ + #define AILIA_AUDIO_FFT_NORMALIZE_LIBROSA_COMPAT (1) + /** + * \~japanese + * @def AILIA_AUDIO_FFT_NORMALIZE_PYTORCH_COMPAT + * @brief FFT の出力を PyTorch 互換で正規化する + * + * \~english + * @def AILIA_AUDIO_FFT_NORMALIZE_PYTORCH_COMPAT + * @brief Normalize the FFT output in a way compatible with PyTorch + */ + #define AILIA_AUDIO_FFT_NORMALIZE_PYTORCH_COMPAT (1) + /** + * \~japanese + * @def AILIA_AUDIO_FFT_NORMALIZE_SCIPY_COMPAT + * @brief FFT の出力を SciPy 互換で正規化する + * + * \~english + * @def AILIA_AUDIO_FFT_NORMALIZE_SCIPY_COMPAT + * @brief Normalize the FFT output in a way compatible with SciPy + */ + #define AILIA_AUDIO_FFT_NORMALIZE_SCIPY_COMPAT (2) + + /** + * \~japanese + * @def AILIA_AUDIO_MEL_NORMALIZE_NONE + * @brief MEL スペクトログラムの出力を正規化しない + * + * \~english + * @def AILIA_AUDIO_MEL_NORMALIZE_NONE + * @brief Do not normalize the output of the mel spectrogram + */ + #define AILIA_AUDIO_MEL_NORMALIZE_NONE (0) + /** + * \~japanese + * @def AILIA_AUDIO_MEL_NORMALIZE_ENABLE + * @brief MEL スペクトログラムの出力を正規化する + * + * \~english + * @def AILIA_AUDIO_MEL_NORMALIZE_ENABLE + * @brief Normalize the output of the mel spectrogram + */ + #define AILIA_AUDIO_MEL_NORMALIZE_ENABLE (1) + + /** + * \~japanese + * @def AILIA_AUDIO_MEL_SCALE_FORMULA_HTK + * @brief MEL 尺度を HTK formula で求める (PyTorch 互換) + * + * \~english + * @def AILIA_AUDIO_MEL_SCALE_FORMULA_HTK + * @brief Get the mel scale from the HTK formula (PyTorch compatible) + */ + #define AILIA_AUDIO_MEL_SCALE_FORMULA_HTK (1) + /** + * \~japanese + * @def AILIA_AUDIO_MEL_SCALE_FORMULA_SLANYE + * @brief MEL 尺度を Slanye's formula で求める (librosa デフォルト互換) + * + * \~english + * @def AILIA_AUDIO_MEL_SCALE_FORMULA_SLANYE + * @brief Get the mel scale from the Slanye's formula (compatible with the default of librosa) + */ + #define AILIA_AUDIO_MEL_SCALE_FORMULA_SLANYE (0) + + /** + * \~japanese + * @def AILIA_AUDIO_PHASE_FORM_COMPLEX + * @brief 位相を複素数形式で出力する (librosa デフォルト互換) + * + * \~english + * @def AILIA_AUDIO_PHASE_FORM_COMPLEX + * @brief Output the phase in complex format (compatible with the default of librosa) + */ + #define AILIA_AUDIO_PHASE_FORM_COMPLEX (1) + /** + * \~japanese + * @def AILIA_AUDIO_PHASE_FORM_REAL + * @brief 位相を実数形式で出力する (PyTorch デフォルト互換) + * + * \~english + * @def AILIA_AUDIO_PHASE_FORM_REAL + * @brief Output the phase in complex format (compatible with the default of PyTorch) + */ + #define AILIA_AUDIO_PHASE_FORM_REAL (0) + + /** + * \~japanese + * @def AILIA_AUDIO_FILTFILT_PAD_NONE + * @brief ゼロ位相フィルタ処理の際、padding をしない + * + * \~english + * @def AILIA_AUDIO_FILTFILT_PAD_NONE + * @brief During zero-phase filtering, do not pad + */ + #define AILIA_AUDIO_FILTFILT_PAD_NONE (0) + /** + * \~japanese + * @def AILIA_AUDIO_FILTFILT_PAD_ODD + * @brief ゼロ位相フィルタ処理の際、padding はodd + * + * \~english + * @def AILIA_AUDIO_FILTFILT_PAD_ODD + * @brief During zero-phase filtering, pad with an odd reflection (substract the reflected values from two times the edge value) + */ + #define AILIA_AUDIO_FILTFILT_PAD_ODD (1) + /** + * \~japanese + * @def AILIA_AUDIO_FILTFILT_PAD_EVEN + * @brief ゼロ位相フィルタ処理の際、padding はeven(reflect) + * + * \~english + * @def AILIA_AUDIO_FILTFILT_PAD_EVEN + * @brief During zero-phase filtering, pad with an even reflection (normal reflection) + */ + #define AILIA_AUDIO_FILTFILT_PAD_EVEN (2) + /** + * \~japanese + * @def AILIA_AUDIO_FILTFILT_PAD_CONSTANT + * @brief ゼロ位相フィルタ処理の際、padding は端値 + * + * \~english + * @def AILIA_AUDIO_FILTFILT_PAD_CONSTANT + * @brief During zero-phase filtering, pad using the edge value + */ + #define AILIA_AUDIO_FILTFILT_PAD_CONSTANT (3) + + /** + * \~japanese + * @brief 入力値を対数スケールに変換します。 + * @param dst 出力データポインタ、float 型、長さ src_n + * @param src 入力データポインタ、float 型、長さ src_n + * @param src_n 計算対象の要素数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * dst = log_e(1.0 + src) を計算します。 + * + * \~english + * @brief Convert the input values to a logarithmic scale. + * @param dst pointer to the output data, of float format, and of length src_n + * @param src pointer to the input data, of float format, and of length src_n + * @param src_n number of elements to be calculated + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * dst = log_e(1.0 + src) + */ + int AILIA_API ailiaAudioLog1p(void* dst, const void* src, int src_n); + + + /** + * \~japanese + * @brief 非負の入力値をデシベルスケールに変換します。 + * @param dst 出力データポインタ、float 型、長さ src_n + * @param src 入力データポインタ、float 型、要素数 src_n + * @param src_n 計算対象の要素数 + * @param top_db 出力の最大値から出力下限の閾値までを定める値 (>= 0.0)、負数の場合は処理は閾値を設定しない + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * librosa.power_to_dbと互換性があります。 + * + * \~english + * @brief Convert non-negative input values to decibel scale. + * @param dst pointer to the output data, of float format, and of length src_n + * @param src pointer to the input data, of float format, and of length src_n + * @param src_n number of elements to be calculated + * @param top_db float >= 0.0 + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * Output compatible with librosa.power_to_db. + * dst = trimlow( 10 * log10(src / ref) ) + * where ref is the max of 1e-10 and of positive values of src, + * and trimlow(), if top_db > 0, trims all values inferior to (- top_db) and replaces them by (- top_db)), + * else, trimlow() does nothing. + */ + int AILIA_API ailiaAudioConvertPowerToDB(void* dst, const void* src, int src_n, float top_db); + + + /** + * \~japanese + * @brief STFTで生成される時間フレーム長を取得します。 + * @param frame_n フレーム長出力先ポインタ + * @param sample_n STFTを適用するサンプル数 + * @param fft_n FFT点数 + * @param hop_n 窓のシフト数 + * @param center AILIA_AUDIO_STFT_CENTER_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * STFT実行前のバッファサイズの決定に使用します。 + * \ref AILIA_AUDIO_STFT_CENTER_NONE の場合 hop_n ずつ区切り、sample_n の前後に padding を行いません。 + * \ref AILIA_AUDIO_STFT_CENTER_ENABLE の場合 sample_n の前後に fft_n/2 の padding(reflect) を行います。 + * \ref AILIA_AUDIO_STFT_CENTER_SCIPY_DEFAULT の場合、sample_n の前後に fft_n/2 の padding(zero) を行い、hop_nの倍数になるようにpadding(zero)を行います + * + * \~english + * @brief Get the number of frames generated by the STFT. + * @param frame_n pointer to the destination where to write the output (the number of frames) + * @param sample_n count of samples on which the STFT is performed + * @param fft_n size of the FFT at each frame (i.e. number of frequency bins at each frame) + * @param hop_n stride of each window shift (in number of samples). This is the quantum of time for the time axis of the STFT output. + * @param center any of the AILIA_AUDIO_STFT_CENTER_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * Before executing the STFT, use this function to determine the space required for the output buffer. + * If \ref AILIA_AUDIO_STFT_CENTER_NONE is used, the sample_n samples are cut in packets of size hop_n, and no padding occurs before the first sample nor after the last sample. + * If \ref AILIA_AUDIO_STFT_CENTER_ENABLE is used, a reflection padding of length fft_n/n is performed before the first sample and after the last sample. + * If \ref AILIA_AUDIO_STFT_CENTER_ENABLE is used, a zero padding of length fft_n/n is performed before the first sample and after the last sample, and moreover an additional zero padding is performed to ensure that the total length is a multiple of hop_n. + */ + int AILIA_API ailiaAudioGetFrameLen(int* frame_n, int sample_n, int fft_n, int hop_n, int center); + + + /** + * \~japanese + * @brief ISTFTで生成されるサンプル数を取得します。 + * @param sample_n サンプル数出力先ポインタ + * @param frame_n STFTデータの時間フレーム長 + * @param fft_n FFT点数 + * @param hop_n 窓のシフト数 + * @param center AILIA_AUDIO_STFT_CENTER_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ISTFT実行前のバッファサイズの決定に使用します。 + * \ref AILIA_AUDIO_STFT_CENTER_NONE の場合 前後の切り捨てを行いません。 + * \ref AILIA_AUDIO_STFT_CENTER_NONE 以外の場合 前後の切り捨てを行います。 + * + * \~english + * @brief Get the number of samples generated by the ISTFT. + * @param sample_n pointer to the destination where to write the output (the number of samples) + * @param frame_n length of the STFT data, expressed in number of frames + * @param fft_n size of the FFT at each frame (i.e. number of frequency bins at each frame) + * @param hop_n stride of each window shift (in number of samples). This is the quantum of time for the time axis of the STFT output. + * @param center any of the AILIA_AUDIO_STFT_CENTER_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * Before executing the ISTFT, use this function to determine the space required for the output buffer. + * If \ref AILIA_AUDIO_STFT_CENTER_NONE is used, no truncation is performed at the beginning nor at the end. + * If \ref AILIA_AUDIO_STFT_CENTER_NONE is not used, a truncation is performed at the beginning and at the end. + */ + int AILIA_API ailiaAudioGetSampleLen(int* sample_n, int frame_n, int freq_n, int hop_n, int center); + + + /** + * \~japanese + * @brief 窓関数の係数を取得します。 + * @param dst 出力データのポインタ、float 型、要素数 window_n + * @param window_n 窓の長さ(サンプル数) + * @param win_type 窓関数の種類、AILIA_AUDIO_WIN_TYPE_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 窓関数はhann窓とhamming窓のみ対応しています。 + * + * \~english + * @brief Get the window function. + * @param dst pointer to the output data, of float format, and of length window_n + * @param window_n length of the window (in number of samples) + * @param win_type type of the window function: any of the AILIA_AUDIO_WIN_TYPE_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * Only the Hann and the Hamming window functions are supported. + */ + int AILIA_API ailiaAudioGetWindow(void* dst, int window_n, int win_type); + + + /** + * \~japanese + * @brief FFTを実行します。 + * @param dst 出力データのポインタ、float 型、外側から fft_n, 2(実部、虚部) 順のメモリレイアウト + * @param src 入力データのポインタ、float 型、要素数 fft_n + * @param fft_n FFT点数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * FFT点数が2の累乗の場合、高速アルゴリズムで動作します。 + * 出力データは実部と虚部の交互信号であり、長さは fft_n*2 です。 + * + * \~english + * @brief Execute the FFT. + * @param dst pointer to the output data, of float format, of length 2*fft_n, and which memory layout is a sequence of fft_n pairs [real part, imaginary part]. Memory layout, using the row-major convention: (fft_n, 2). + * @param src pointer to the input data, of float format, and of length fft_n + * @param fft_n count of FFT values (i.e. of frequency bins) + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * If fft_n is a power of 2, this function uses a faster algorithm. + * As the output data alternates real and imaginary parts, its length is 2*fft_n. + */ + int AILIA_API ailiaAudioFFT(void* dst, const void* src, int fft_n); + + + /** + * \~japanese + * @brief IFFTを実行します。 + * @param dst 出力データのポインタ、float 型、外側から fft_n, 2(実部、虚部) 順のメモリレイアウト + * @param src 入力データのポインタ、float 型、外側から fft_n, 2(実部、虚部) 順のメモリレイアウト + * @param fft_n FFT点数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * FFT点数が2の累乗の場合、高速アルゴリズムで動作します。 + * 出力データは実部と虚部の交互信号であり、長さは fft_n*2 です。 + * + * \~english + * @brief Execute the IFFT. + * @param dst pointer to the output data, of float format, of length 2*fft_n, and which memory layout is a sequence of fft_n pairs [real part, imaginary part]. Memory layout, using the row-major convention: (fft_n, 2). + * @param src pointer to the input data, of float format, of length 2*fft_n, and which memory layout is a sequence of fft_n pairs [real part, imaginary part]. Memory layout, using the row-major convention: (fft_n, 2). + * @param fft_n count of FFT values (i.e. of frequency bins) + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * If fft_n is a power of 2, this function uses a faster algorithm. + * As the output data alternates real and imaginary parts, its length is 2*fft_n. + */ + int AILIA_API ailiaAudioIFFT(void* dst, const void* src, int fft_n); + + + /** + * \~japanese + * @brief 音響信号からスペクトログラムを生成します。 + * @param dst 出力データのポインタ、float 型、外側から freq_n, frame_n, 2(複素数: 実部, 虚部) 順のメモリレイアウト + * @param src 入力データのポインタ、float 型、要素数 sample_n + * @param sample_n 入力データのサンプル数 + * @param fft_n FFT点数 + * @param hop_n フレームのシフト数 + * @param win_n 窓関数の長さ + * @param win_type 窓関数の種類、AILIA_AUDIO_WIN_TYPE_* のいずれか + * @param max_frame_n 出力データの時間フレーム数の最大値 + * @param center 入力データの前後へのパディングの有無、AILIA_AUDIO_STFT_CENTER_* のいずれか + * @param power スペクトログラムの乗数(>= 0.0) 0.0: 複素スペクトログラム、1.0: 振幅スペクトログラム、2.0: パワースペクトログラム、その他: 任意の累乗値の出力に相当 + * @param norm_type FFT後の正規化処理、AILIA_AUDIO_FFT_NORMALIZE_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 時間フレームごとにFFT→正規化処理→累乗(振幅・パワーに変換)の順で処理を実行します。 + * 出力データは実部と虚部の交互信号であり、長さは(fft_n/2+1)*時間フレーム長*2です。 + * powerが0.0以外の場合は虚部の値を全て0.0として出力します。 + * + * \~english + * @brief Generate the spectrogram from the audio signal. + * @param dst pointer to the output data, of float format, of length (2 * freq_n * frame_n), and which memory layout is a sequence of pairs [real part, imaginary part]. (where freq_n = fft_n/2+1). Memory layout, using the row-major convention: (freq_n, frame_n, 2). + * @param src pointer to the input data, of float format, and of length sample_n + * @param sample_n count of samples in the input data + * @param fft_n size of the FFT at each frame (i.e. number of frequency bins at each frame) + * @param hop_n stride of each window shift (in number of samples). This is the size of the time increment for the spectrogram. + * @param win_n size of the window function + * @param win_type type of the window function: any of the AILIA_AUDIO_WIN_TYPE_* constants + * @param max_frame_n maximum value of the time frame index in the outputted data + * @param center whether to pad or not (and the type of padding) before and after the input data: any of the AILIA_AUDIO_STFT_CENTER_* constants + * @param power exponent to apply to the spectrogram (> = 0.0). A special case is for 0.0: complex spectrogram. For other cases the amplitude is just exponentiated accordingly: 1.0: amplitude spectrogram, 2.0: power spectrogram, etc, any other positive exponent value is allowed. + * @param norm_type normalization after the FFT: any of the AILIA_AUDIO_FFT_NORMALIZE_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * For each time frame, the operations are processed in this order: FFT -> normalization -> power exponentiation. + * As the output data alternates real and imaginary parts, its length is 2*(fft_n/2+1)*frame_n. (where frame_n is the number of time frames outputted) + * When the power argument is a non-zero value, all the complex parts are set to 0 in the output. + */ + int AILIA_API ailiaAudioGetSpectrogram(void* dst, const void* src, int sample_n, int fft_n, int hop_n, int win_n, int win_type, int max_frame_n, int center, float power, int norm_type); + + + /** + * \~japanese + * @brief 複素スペクトログラムから音響信号を生成します。 + * @param dst 出力データのポインタ、float 型、要素数 sample_n + * @param src 入力データのポインタ、float 型、外側から freq_n, frame_n, 2(複素数: 実部, 虚部) 順のメモリレイアウト + * @param frame_n 入力データの時間フレーム数 + * @param freq_n 周波数(fft_n/2+1) + * @param hop_n フレームのシフト数 + * @param win_n 窓関数の長さ + * @param win_type 窓関数の種類、AILIA_AUDIO_WIN_TYPE_* のいずれか + * @param max_sample_n 出力データのサンプル数の最大値 + * @param center 入力データ生成時の前後へのパディングの有無、AILIA_AUDIO_STFT_CENTER_* のいずれか + * @param norm_type 入力データ生成時の正規化処理、AILIA_AUDIO_FFT_NORMALIZE_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 時間フレームごとにIFFTを行い、最後に正規化処理を実行します。 + * 複素スペクトログラムのみに対応しています。 + * + * \~english + * @brief Generate an audio signal from a complex spectrogram. + * @param dst pointer to the output data, of float format, and of length sample_n + * @param src pointer to the input data, of float format, of length (2 * freq_n * frame_n), and which memory layout is a sequence of pairs [real part, imaginary part]. Memory layout, using the row-major convention: (freq_n, frame_n, 2). + * @param frame_n number of time frames in the input data + * @param freq_n number of frequencies bins for each time frame (freq_n = fft_n/2+1) + * @param hop_n step size of the time frame increment (expressed in number of samples) for the inputted spectrogram. + * @param win_n size of the window function + * @param win_type type of the window function: any of the AILIA_AUDIO_WIN_TYPE_* constants + * @param max_sample_n maximum value of the sample index in the outputted data + * @param center whether padding (before and after) was used or not (and its type) during the generation of the input data: any of the AILIA_AUDIO_STFT_CENTER_* constants + * @param norm_type normalization type that was used during the generation of the input data: any of the AILIA_AUDIO_FFT_NORMALIZE_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * For each time frame the normalization is executed at the end of the IFFT. + * Only accepts a complex spectrogram in input. + */ + int AILIA_API ailiaAudioGetInverseSpectrogram(void* dst, const void* src, int frame_n, int freq_n, int hop_n, int win_n, int win_type, int max_sample_n, int center, int norm_type); + + + /** + * \~japanese + * @brief メルフィルタバンクの係数を計算します。 + * @param dst 出力データのポインタ、float 型、外側から mel_n, freq_n 順のメモリレイアウト + * @param freq_n 周波数のインデックス数 + * @param f_min 周波数の最小値 + * @param f_max 周波数の最大値 + * @param mel_n メル周波数のインデックス数( < freq_n) + * @param sample_rate サンプリング周波数 + * @param mel_norm 出力される係数の正規化の有無、AILIA_AUDIO_MEL_NORMALIZE_* のいずれか + * @param mel_formula MEL尺度の形式、AILIA_AUDIO_MEL_SCALE_FORMULA_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Create a mel filter-bank. + * @param dst pointer to the output data, of float format, and of length (mel_n * freq_n). (memory layout, using the row-major convention: (mel_n, freq_n)) + * @param freq_n number of frequency indices for the FFT (1+fft_n/2) + * @param f_min lowest frequency + * @param f_max highest frequency + * @param mel_n number of mel frequency bins in the output (< freq_n) + * @param sample_rate sampling rate for the signal that will be inputted to this filter + * @param mel_norm whether to normalize the output (and the type of the normalization): any of the AILIA_AUDIO_MEL_NORMALIZE_* constants + * @param mel_formula mel scale format: any of the AILIA_AUDIO_MEL_SCALE_FORMULA_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + */ + int AILIA_API ailiaAudioGetFBMatrix(void* dst, const int freq_n, float f_min, float f_max, int mel_n, int sample_rate, int mel_norm, int mel_formula); + + + /** + * \~japanese + * @brief 音響信号からメルスペクトログラムを生成します。 + * @param dst 出力データのポインタ、float 型、外側から mel_n, frame_n 順のメモリレイアウト + * @param src 入力データのポインタ、float 型、モノラル PCM データ + * @param sample_n 入力データのサンプル数 + * @param sample_rate サンプリング周波数 + * @param fft_n FFT点数 + * @param hop_n フレームのシフト数 + * @param win_n 1フレームに含むサンプル数 + * @param win_type 窓関数の種類、AILIA_AUDIO_WIN_TYPE_* のいずれか + * @param max_frame_n 出力データの時間フレーム数の最大値 + * @param center 入力データの前後へのパディングの有無、AILIA_AUDIO_STFT_CENTER_* のいずれか + * @param power スペクトログラムの乗数( > 0.0)1.0: 振幅スペクトログラム、2.0: パワースペクトログラム、その他: 任意の累乗値の出力に相当 + * @param fft_norm_type FFT後の正規化処理、AILIA_AUDIO_FFT_NORMALIZE_* のいずれか + * @param f_min 周波数の最小値 + * @param f_max 周波数の最大値 + * @param mel_n メル周波数のインデックス数( < freq_n) + * @param mel_norm_type MELスペクトログラムの正規化の有無、AILIA_AUDIO_MEL_NORMALIZE_* のいずれか + * @param mel_formula MEL尺度の形式、AILIA_AUDIO_MEL_SCALE_FORMULA_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 時間フレームごとにFFT(STFT)→正規化処理→累乗(振幅・パワーに変換→メルフィルタバンクの係数取得→メル尺度への変換 の順で処理を実行します。 + * 出力データは実数の信号であり、長さはmel_n*時間フレーム長です。 + * + * \~english + * @brief Generate the mel spectrogram from the audio signal. + * @param dst pointer to the output data, of float format, and of length (mel_n * frame_n) (with frame_n the number of time frames outputted). (memory layout, using the row-major convention: (mel_n, frame_n)) + * @param src pointer to the input data, of float format, monoral PCM audio data. + * @param sample_n count of samples in the input data + * @param sample_rate sampling rate of the input signal + * @param fft_n number of FFT components + * @param hop_n stride of each window shift (in number of samples). This is the size of the time increment for the spectrogram. + * @param win_n size of the window function (in number of samples) + * @param win_type type of the window function: any of the AILIA_AUDIO_WIN_TYPE_* constants + * @param max_frame_n maximum value of the time frame index in the outputted data + * @param center whether to pad or not (and the type of padding) before and after the input data: any of the AILIA_AUDIO_STFT_CENTER_* constants + * @param power exponent to apply to the spectrogram (> 0.0). 1.0: amplitude spectrogram, 2.0: power spectrogram, etc, any other positive exponent value is allowed. + * @param fft_norm_type normalization after the FFT: any of the AILIA_AUDIO_FFT_NORMALIZE_* constants + * @param f_min lowest frequency + * @param f_max highest frequency + * @param mel_n number of mel frequency bins in the output (< freq_n) + * @param mel_norm whether to normalize the mel spectrogram (and the type of the normalization): any of the AILIA_AUDIO_MEL_NORMALIZE_* constants + * @param mel_formula mel scale format: any of the AILIA_AUDIO_MEL_SCALE_FORMULA_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * For each time frame, the operations are processed in this order: + * FFT(STFT) -> normalization -> power exponentiation -> get the mel filter-bank coefficients -> convert to the mel scale. + * The output is real values, and its length is mel_n*frame_n (with frame_n the number of time frames outputted). + */ + int AILIA_API ailiaAudioGetMelSpectrogram(void* dst, const void* src, int sample_n, int sample_rate, int fft_n, int hop_n, int win_n, int win_type, int max_frame_n, int center, float power, int fft_norm_type, float f_min, float f_max, int mel_n, int mel_norm_type, int mel_formula); + + + /** + * \~japanese + * @brief スペクトログラムから振幅と位相を計算します。 + * @param dst_mag 振幅の出力先ポインタ、外側から freq_n, frame_n 順のメモリレイアウト + * @param dst_phase 位相の出力先ポインタ、外側から freq_n, frame_n, 2(実部、虚部) 順のメモリレイアウト + * @param src 入力データのポインタ、frame_n, freq_n, 2(実部、虚部) 順のメモリレイアウト + * @param freq_n 周波数のインデックス数 + * @param frame_n 時間フレームの数 + * @param power 振幅スペクトルの乗数 ( > 0.0)、1.0: 振幅スペクトログラム、2.0: パワースペクトログラムに相当 + * @param phase_form 位相の出力形式、AILIA_AUDIO_PHASE_FORM_* のいずれか + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * librosaのデフォルト値と互換の条件: phase_form = \ref AILIA_AUDIO_PHASE_FORM_COMPLEX , power = 1.0 + * PyTorchのデフォルト値と互換の条件: phase_form = \ref AILIA_AUDIO_PHASE_FORM_REAL , power = 1.0 + * phase_formによってdst_phaseの出力が変わります。 + * - \ref AILIA_AUDIO_PHASE_FORM_COMPLEX : 実部と虚部の交互信号、サイズは freq_n * frame_n * 2 + * - \ref AILIA_AUDIO_PHASE_FORM_REAL : 実部のみの信号、サイズは freq_n * frame_n + * + * \~english + * @brief Get the amplitude and the phase from the spectrogram. + * @param dst_mag pointer to the outputted amplitudes, an array of length (freq_n * frame_n). (memory layout, using the row-major convention: (freq_n, frame_n)) + * @param dst_phase pointer to the outputted phases, an array of length (2 * freq_n * frame_n) (sequence of complex pairs [real part, imaginary part]). (memory layout, using the row-major convention: (freq_n, frame_n, 2)) + * @param src pointer to the input data, of length (2 * frame_n * freq_n) (a sequence of complex pairs [real, imaginary]). (memory layout, using the row-major convention: (frame_n, freq_n, 2)) + * @param freq_n number of frequency indices + * @param frame_n number of time frames + * @param power exponent to apply to the spectrogram (> 0.0). 1.0: amplitude spectrogram, 2.0: power spectrogram, etc, any other positive exponent value is allowed. + * @param phase_form format of the outputted phase: any of the AILIA_AUDIO_PHASE_FORM_* constants + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * To be compatible with librosa, use: phase_form = \ref AILIA_AUDIO_PHASE_FORM_COMPLEX , power = 1.0 + * To be compatible with PyTorch, use: phase_form = \ref AILIA_AUDIO_PHASE_FORM_REAL , power = 1.0 + * The dst_phase output depends on phase_form: + * - \ref AILIA_AUDIO_PHASE_FORM_COMPLEX : signal with real and imaginary parts, of size (freq_n * frame_n * 2) + * - \ref AILIA_AUDIO_PHASE_FORM_REAL : real signal, of size (freq_n * frame_n) + */ + int AILIA_API ailiaAudioMagPhase(void* dst_mag, void* dst_phase, const void* src, int freq_n, int frame_n, float power, int phase_form); + + + /** + * \~japanese + * @brief 実数の信号に対して標準化を実行します。 + * @param dst 出力データのポインタ、float 型、要素数 src_n + * @param src 入力データのポインタ、float 型、要素数 src_n + * @param src_n 入力データの要素数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 入力データの平均0、分散1になるよう標準化を行う。 + * dst = (src - mean(src)) / std(src) + * + * \~english + * @brief Standardize a real signal. + * @param dst pointer to the output data, of float format, and of length src_n + * @param src pointer to the input data, of float format, and of length src_n + * @param src_n length of the input data + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * Standardize the input data so that its average value becomes 0 and its variance 1. + * dst = (src - mean(src)) / std(src) + */ + int AILIA_API ailiaAudioStandardize(void* dst, const void* src, const int src_n); + + + /** + * \~japanese + * @brief 複素数のノルムを算出します + * @param dst 出力データのポインタ、float 型、要素数 src_n + * @param src 入力データのポインタ、float 型、外側から src_n, 2(実部、虚部) 順のメモリレイアウト + * @param src_n 入力データの要素数 + * @param power 累乗値( > 0.0 )、1.0で複素数絶対値に相当 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 入力データのノルムを算出します + * src_cmp = src[0] + src[1] i において + * tmp_dst = pow(src[0],2.0) + pow(src[1],2.0) + * dst[0] = pow(tmp_dst,0.5*power); + * + * \~english + * @brief Get the norm of the complex signal. + * @param dst pointer to the output data, of float format, and of length src_n + * @param src pointer to the input data, of float format, an array of length (2 * src_n) (sequence of complex pairs [real part, imaginary part]). (memory layout, using the row-major convention: (src_n, 2)) + * @param src_n length of the input data + * @param power exponent to apply to the spectrogram (> 0.0). 1.0: amplitude spectrogram + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * Compute the norm of the input data. + * For each src_cmp = src[0] + i * src[1], + * tmp_dst = pow(src[0],2.0) + pow(src[1],2.0) + * dst[0] = pow(tmp_dst,0.5*power); + */ + int AILIA_API ailiaAudioComplexNorm(void* dst, const void* src, const int src_n, float power); + + + /** + * \~japanese + * @brief 実数STFT結果をメル尺度に変換する + * @param dst 出力データのポインタ、float 型、外側から mel_n, frame_n 順のメモリレイアウト + * @param src 入力データのポインタ、float 型、外側から freq_n, frame_n 順のメモリレイアウト + * @param fb_mtrx メルフィルタバンク、float 型、外側から mel_n, freq_n 順のメモリレイアウト + * @param freq_n 周波数のインデックス数 + * @param frame_n 入力データの時間フレームの数 + * @param mel_n メル周波数のインデックス数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 入力された実数スペクトログラムをメル尺度に変換します + * fb_mtrxには ailiaAudioGetFBMatrix() で取得した係数を与える事が出来ます + * + * \~english + * @brief Convert the real output of the STFT to the mel scale. + * @param dst pointer to the output data, of float format, of length (mel_n * frame_n), and of memory layout (in row-major convention) (mel_n, frame_n). + * @param src pointer to the input data, of float format, of length (freq_n * frame_n), and of memory layout (in row-major convention) (freq_n, frame_n). + * @param fb_mtrx the mel filter-bank, of float format, of length (mel_n * freq_n), and of memory layout (in row-major convention) (mel_n, freq_n). + * @param freq_n number of frequency indices + * @param frame_n number of time frames in the input data + * @param mel_n number of mel frequency indices + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * Converts the real spectrogram given in input to the mel scale. + * The argument fb_mtrx can take the coefficients outputted by ailiaAudioGetFBMatrix() . + */ + int AILIA_API ailiaAudioConvertToMel(void* dst, const void* src, const void* fb_mtrx, int freq_n, int frame_n, int mel_n); + + + /** + * \~japanese + * @brief 実数スペクトログラム/メルスペクトログラムの時間フレーム数を調整します。 + * @param dst 出力データのポインタ、freq_n, dst_frame_n 順のメモリレイアウト + * @param src 入力データのポインタ、freq_n, src_frame_n 順のメモリレイアウト + * @param freq_n 周波数のインデックス数 + * @param dst_frame_n 出力データの時間フレームの数 + * @param src_frame_n 入力データの時間フレームの数 + * @param pad_data パディング(dst_frame_n > src_frame_n の場合に使用) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * dst_frame_n > src_frame_n : 不足する時間フレームのデータを pad_data のデータで埋める。 + * dst_frame_n <= src_frame_n : 先頭から dst_frame_n のデータのみを切り出す。 + * + * \~english + * @brief Fix the number of time frames of a real-valued spectrogram/mel-spectrogram. + * @param dst pointer to the output data, of length (freq_n * dst_frame_n), and of memory layout (in row-major convention) (freq_n, dst_frame_n). + * @param src pointer to the input data, of length (freq_n * src_frame_n), and of memory layout (in row-major convention) (freq_n, src_frame_n). + * @param freq_n number of frequency indices + * @param dst_frame_n number of time frames in the output data + * @param src_frame_n number of time frames in the input data + * @param pad_data value inserted for padding (used when dst_frame_n > src_frame_n) + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * dst_frame_n > src_frame_n : missing time frames are added and filled with the value pad_data. + * dst_frame_n <= src_frame_n : only keeps the first dst_frame_n data. + */ + int AILIA_API ailiaAudioFixFrameLen(void* dst, const void* src, int freq_n, int dst_frame_n, int src_frame_n, float pad_data); + + + /** + * \~japanese + * @brief 信号をリサンプルします + * @param dst 出力データのポインタ、float 型、要素数 dst_n + * @param src 入力データのポインタ、float 型、要素数 src_n + * @param dst_sample_rate 変換後のサンプリングレート + * @param dst_n データ出力先の確保要素数(dst_n >= max_resample_n) + * @param src_sample_rate 入力データのサンプリングレート + * @param src_n 入力データの要素数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 最大出力数max_resample_nは ailiaAudioGetResampleLen() で取得できます。 + * dst_n < max_resample_n : 先頭からdst_nに入る部分のみ出力 + * dst_n >= max_resample_n : 出力要素数はmax_resample_n + * + * \~english + * @brief Resample the signal. + * @param dst pointer to the output data, of float format, and of length dst_n + * @param src pointer to the input data, of float format, and of length src_n + * @param dst_sample_rate sampling rate after the resampling + * @param dst_n length (in number of samples) reserved in the output buffer(dst_n >= max_resample_n) + * @param src_sample_rate sampling rate of the input signal + * @param src_n number of samples in the input signal + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * The max number of samples in the output, max_resample_n, can be obtained from ailiaAudioGetResampleLen() . + * dst_n < max_resample_n : only the first dst_n samples are outputted + * dst_n >= max_resample_n : max_resample_n samples are outputted + */ + int AILIA_API ailiaAudioResample(void* dst, const void* src, int dst_sample_rate, int dst_n, int src_sample_rate, int src_n); + + + /** + * \~japanese + * @brief リサンプル後のサンプル数を計算します + * @param dst_sample_n リサンプル後サンプル数出力先ポインタ + * @param dst_sample_rate 変換後のサンプリングレート + * @param src_sample_n 入力データのサンプル数 + * @param src_sample_rate 入力データのサンプリングレート + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Get the number of samples after the resampling. + * @param dst_sample_n pointer to the destination where to write the output (the number of samples after resampling) + * @param dst_sample_rate sampling rate after the resampling + * @param src_sample_n number of samples in the input signal + * @param src_sample_rate sampling rate of the input signal + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + */ + int AILIA_API ailiaAudioGetResampleLen(int* dst_sample_n, int dst_sample_rate, int src_sample_n, int src_sample_rate); + + + /** + * \~japanese + * @brief 信号にフィルタ処理を適用します + * @param dst 出力データのポインタ、float 型、要素数 dst_n + * @param src 入力データのポインタ、float 型、要素数 src_n + * @param n_coef フィルタ分子係数のポインタ、float 型、要素数 n_coef_n + * @param d_coef フィルタ分母係数のポインタ、float 型、要素数 d_coef_n + * @param zi 遅延状態のポインタ、float 型、要素数 zi_n (zi_n = max(n_coef_n,d_coef_n)-1)、nullptrを許容 + * @param dst_n データ出力先の確保要素数(dst_n >= src_n) + * @param src_n 入力データの要素数 + * @param n_coef_n フィルタ分子係数の要素数 + * @param d_coef_n フィルタ分母係数の要素数 + * @param zi_n 遅延状態の要素数 (zi_n >= max(n_coef_n,d_coef_n)-1) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * dstへの出力数はmin(dst_m,src_n)となります。 + * ziへは初期遅延状態を渡します。処理後には最終遅延状態に上書きされます。 + * zi_nはmax(n_coef_n,d_coef_n)-1が必要となります。不足の場合、不足分は0でパディングし、最終遅延状態は返しません。 + * ziにnullptrを与えた場合は、初期遅延状態を0とします。最終遅延状態も返しません。zi_nは無視されます。 + * n_coef_nとd_coef_nは大きいほうを基準とし、不足分は0でパディングします。 + * + * \~english + * @brief Apply a filter to the signal. + * @param dst pointer to the output data, of float format, and of length dst_n + * @param src pointer to the input data, of float format, and of length src_n + * @param n_coef pointer to the numerator coefficients of the filter, of float format, and length n_coef_n + * @param d_coef pointer to the denominator coefficients of the filter, of float format, and length d_coef_n + * @param zi pointer to the initial delayed values to be used, of float format, and of length zi_n (zi_n = max(n_coef_n,d_coef_n)-1). nullptr is allowed. + * @param dst_n size, in number of samples, reserved in the output buffer (dst_n >= src_n) + * @param src_n number of samples in the input signal + * @param n_coef_n number of numerator coefficients of the filter + * @param d_coef_n number of denominator coefficients of the filter + * @param zi_n number of initial delayed values provided (zi_n >= max(n_coef_n,d_coef_n)-1) + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * The number of samples outputted to dst is min(dst_m,src_n). + * Use zi to provide the initial delayed values. During processing, this array is overriden with the new delayed values. + * Out of the zi_n, the number of delayed values used is max(n_coef_n,d_coef_n)-1. If there are less than that, the remaining is assumed to be zeros, and the array zi is not updated with the new values. + * When zi is nullptr, zi_n is ignored, all the delayed values are assumed to be zero, and the new delayed values are not returned. + * The largest of n_coef_n and d_coef_n is taken as reference and zeros are added for padding where necessary. + */ + int AILIA_API ailiaAudioLinerFilter(void* dst, const void* src, const void* n_coef, const void* d_coef, void* zi, int dst_n, int src_n, int n_coef_n, int d_coef_n, int zi_n); + + + /** + * \~japanese + * @brief フィルタ処理用の初期遅延係数を算出します + * @param dst_zi 出力する初期遅延状態のポインタ、float 型、要素数 dst_n (dst_n >= max(n_coef_n,d_coef_n)-1) + * @param n_coef フィルタ分子係数のポインタ、float 型、要素数 n_coef_n + * @param d_coef フィルタ分母係数のポインタ、float 型、要素数 d_coef_n + * @param dst_n 出力先の確保要素数 (dst_n >= max(n_coef_n,d_coef_n)-1) + * @param n_coef_n フィルタ分子係数の要素数 + * @param d_coef_n フィルタ分母係数の要素数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 一般に、得られた係数に入力信号の先頭を乗じたものを、初期遅延状態として ailiaAudioLinerFilter() に与えます。 + * dst_nはmax(n_coef_n,d_coef_n)-1が必要となります。 + * 不足の場合は、確保分だけ出力します。 + * 超える部分は、0で埋めます。 + * n_coef_nとd_coef_nは大きいほうを基準とし、不足分は0でパディングします。 + * + * \~english + * @brief Calculate the initial delay coefficients for filtering + * @param dst_zi pointer to the output (initial delay coefficients), of float format, and of length dst_n (dst_n >= max(n_coef_n,d_coef_n)-1) + * @param n_coef pointer to the numerator coefficients of the filter, of float format, and length n_coef_n + * @param d_coef pointer to the denominator coefficients of the filter, of float format, and length d_coef_n + * @param dst_n size, in number of samples, reserved in the output buffer (dst_n >= max(n_coef_n,d_coef_n)-1) + * @param n_coef_n number of numerator coefficients of the filter + * @param d_coef_n number of denominator coefficients of the filter + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * These initial delay coefficients dst_zi, once multiplied with the early values of the signal, can be passed as initial delayed values, the zi argument, to ailiaAudioLinerFilter() . + * Of the dst_n reserved length of the output buffer, the length used is max(n_coef_n,d_coef_n)-1. + * If dst_n is less than that, only the corresponding first values are output. + * If dst_n is larger, the remaining is filled with 0. + * The largest of n_coef_n and d_coef_n is taken as reference and zeros are added for padding where necessary. + */ + int AILIA_API ailiaAudioGetLinerFilterZiCoef(void* dst_zi, const void* n_coef, const void* d_coef, int dst_n, int n_coef_n, int d_coef_n); + + + /** + * \~japanese + * @brief 信号にゼロ位相フィルタ処理を適用します + * @param dst 出力データのポインタ、float 型、要素数 dst_n + * @param src 入力データのポインタ、float 型、要素数 src_n + * @param n_coef フィルタ分子係数のポインタ、float 型、要素数 n_coef_n + * @param d_coef フィルタ分母係数のポインタ、float 型、要素数 d_coef_n + * @param dst_n データ出力先の確保要素数(dst_n >= src_n) + * @param src_n 入力データの要素数 + * @param n_coef_n フィルタ分子係数の要素数 + * @param d_coef_n フィルタ分母係数の要素数 + * @param pad_type 入力信号に対する両端パディング処理方法、 AILIA_AUDIO_FILTFILT_PAD_* のいずれか + * @param pad_len 入力信号に対する両端パディング数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * dstへの出力数はmin(dst_m,src_n)となります。 + * n_coef_nとd_coef_nは大きいほうを基準とし、不足分は0でパディングします。 + * + * \~english + * @brief Apply a zero-phase filter to the signal. + * @param dst pointer to the output data, of float format, and of length dst_n + * @param src pointer to the input data, of float format, and of length src_n + * @param n_coef pointer to the numerator coefficients of the filter, of float format, and length n_coef_n + * @param d_coef pointer to the denominator coefficients of the filter, of float format, and length d_coef_n + * @param dst_n length (in number of samples) reserved in the output buffer (dst_n >= src_n) + * @param src_n number of samples in the input signal + * @param n_coef_n number of numerator coefficients of the filter + * @param d_coef_n number of denominator coefficients of the filter + * @param pad_type type of padding to apply at the start and at the end of the input signal: any of the AILIA_AUDIO_FILTFILT_PAD_* constants + * @param pad_len length of the padding applied to the start and to the end of the input signal + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * The number of values written to the output dst is min(dst_m,src_n). + * The largest of n_coef_n and d_coef_n is taken as reference and zeros are added for padding where necessary. + */ + int AILIA_API ailiaAudioFilterFilter(void* dst, const void* src, const void* n_coef, const void* d_coef, int dst_n, int src_n, int n_coef_n, int d_coef_n, int pad_type, int pad_len); + + + /** + * \~japanese + * @brief 信号の入力前後の無音域を除いた領域を検出します + * @param dst_start_pos 有音域の先頭サンプル位置出力先ポインタ、int 型 + * @param dst_length 有音域の長さ出力先ポインタ、int 型 + * @param src 入力データのポインタ、float 型、要素数 sample_n + * @param sample_n 入力データのサンプル数 + * @param win_n 1フレームに含むサンプル数 + * @param hop_n フレームのシフト数 + * @param thr_db 有音を判断するdB (thr_db > 0) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 全域が無音の場合、*dst_start_pos = -1,*dst_length = 0となります。 + * + * \~english + * @brief Find the region of the signal between the first and the last non-silence samples. Detects the area excluding the silent range before and after the signal input + * @param dst_start_pos pointer to the destination where to write the outputted start position of the non-silence area, of int format + * @param dst_length pointer to the destination where to write the outputted length of the non-silence area, of int format + * @param src pointer to the input data, of float format, and of length sample_n + * @param sample_n count of samples in the input data + * @param win_n size of the window function + * @param hop_n stride of each window shift (in number of samples) + * @param thr_db threshold (in dB) above which the signal is considered non-silence (thr_db > 0) + * @return + * In case of success, \ref AILIA_STATUS_SUCCESS , and else an error code is returned. + * @details + * In case the whole signal is considered silence, the following happens: *dst_start_pos = -1, *dst_length = 0 + */ + int AILIA_API ailiaAudioGetNonSilentPos(int* dst_start_pos, int* dst_length, const void* src, int sample_n, int win_n, int hop_n, float thr_db); + + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA_AUDIO) */ diff --git a/include/ailia/ailia_call.h b/include/ailia/ailia_call.h new file mode 100644 index 0000000..04fc066 --- /dev/null +++ b/include/ailia/ailia_call.h @@ -0,0 +1,218 @@ +/** + * \~japanese + * @file ailia_call.h + * @brief ユーザ定義コールバック + * @copyright AXELL CORPORATION, ax Inc. + * @date 2021/07/28 + * @details + * ファイルアクセスコールバック関数は、1ネットワークオブジェクトにつき、 + * 1スレッドから呼び出されます。 + * 複数のオブジェクトに対して、共通のコールバック関数を与える場合は、 + * コールバック関数はスレッドセーフである必要があります。 + * また、コールバック関数からは例外を投げずに、 + * AILIA_USER_API_FAILEDでエラーを通知してください。 + * + * \~english + * @file ailia_call.h + * @brief user-defined callback + * @copyright AXELL CORPORATION, ax Inc. + * @date 2021/07/28 + * @details + * The file access callback function is called by a single thread + * per network instance. + * If a common callback function is given to multiple instances, + * the callback function must be thread-safe. + * Also, do not throw an exception from the callback function, + * instead use AILIA_USER_API_FAILED to make error notifications. + */ + +#if !defined(INCLUDED_AILIA_CALL) +#define INCLUDED_AILIA_CALL + +/* 呼び出し規約 */ + +#if defined(_WIN32) && !defined(_WIN64) + #define AILIA_USER_API __stdcall +#else + #define AILIA_USER_API +#endif + +#ifdef __EMSCRIPTEN__ + #define AILIA_FSIZE_RETURN_TYPE int +#else + #define AILIA_FSIZE_RETURN_TYPE long long +#endif + +/* ユーザ定義コールバックの返値 */ +/** +* \~japanese +* @def AILIA_USER_API_SUCCESS +* @brief 成功 +* +* \~english +* @def AILIA_USER_API_SUCCESS +* @brief Successful +*/ +#define AILIA_USER_API_SUCCESS ( 0) +/** +* \~japanese +* @def AILIA_USER_API_FAILED +* @brief 失敗 +* +* \~english +* @def AILIA_USER_API_FAILED +* @brief Failed +*/ +#define AILIA_USER_API_FAILED (-1) + +/* +* ファイルアクセスコールバック関数は、1ネットワークオブジェクトにつき、 +* 1スレッドから呼び出されます。 +* 複数のオブジェクトに対して、共通のコールバック関数を与える場合は、 +* コールバック関数はスレッドセーフである必要があります。 +* また、コールバック関数からは例外を投げずに、 +* AILIA_USER_API_FAILEDでエラーを通知してください。 +*/ + + +#ifdef __cplusplus +extern "C" { +#endif + + /** + * \~japanese + * @brief ファイルを開きます + * @param const void * ailiaOpenStreamEx() もしくは ailiaOpenWeightEx() に与えたfopen_args + * @return + * 成功した場合、ユーザ定義ファイルポインタを返す。 + * 失敗した場合、NULLを返す。 + * + * \~english + * @brief Opens a file. + * @param const void * fopen_args given to ailiaOpenStreamEx() or ailiaOpenWeightEx + * @return + * This function returns a user-defined file pointer if successful. + * It returns NULL if it fails. + */ + typedef void* (AILIA_USER_API *AILIA_USER_API_FOPEN) (const void *); + + /** + * \~japanese + * @brief ファイルをシークします + * @param void * ユーザ定義ファイルポインタ + * @param \ref AILIA_FSIZE_RETURN_TYPE ファイル先頭からのオフセットバイト + * @return + * 成功した場合、 \ref AILIA_USER_API_SUCCESS を返す。 + * 失敗した場合、 \ref AILIA_USER_API_FAILED を返す。 + * + * \~english + * @brief It seeks the file specified. + * @param void * A user-defined file pointer + * @param \ref AILIA_FSIZE_RETURN_TYPE Offset in bytes from the beginning of the file + * @return + * This function returns \ref AILIA_USER_API_SUCCESS if successful. + * It returns \ref AILIA_USER_API_FAILED if it fails. + */ + typedef int (AILIA_USER_API *AILIA_USER_API_FSEEK) (void*, AILIA_FSIZE_RETURN_TYPE); + + /** + * \~japanese + * @brief ファイルの現在位置を取得します + * @param void * ユーザ定義ファイルポインタ + * @return + * 成功した場合、ファイルポインタの位置をバイト単位で返す。 + * 失敗した場合、-1を返す。 + * + * \~english + * @brief Gets the current position in the file. + * @param void * A user-defined file pointer + * @return + * This function returns the position, in bytes, the file pointer points to if successful. + * It returns -1 if it fails. + */ + typedef AILIA_FSIZE_RETURN_TYPE (AILIA_USER_API *AILIA_USER_API_FTELL) (void*); + + /** + * \~japanese + * @brief ファイルのサイズを取得します + * @param void * ユーザ定義ファイルポインタ + * @return + * 成功した場合、ファイルのサイズをバイト単位で返す。 + * 失敗した場合、-1を返す。 + * + * \~english + * @brief Gets the size of the file. + * @param void * A user-defined file pointer + * @return + * This function returns the size of the file in bytes if successful. + * It returns -1 if it fails. + */ + typedef AILIA_FSIZE_RETURN_TYPE (AILIA_USER_API *AILIA_USER_API_FSIZE) (void*); + + /** + * \~japanese + * @brief ファイルからデータを読み込みます + * @param void * 読み込みデータ格納先のポインタ + * @param \ref AILIA_FSIZE_RETURN_TYPE 読み込みデータのバイト長さ + * @param void * ユーザ定義ファイルポインタ + * @return + * 成功した場合、 \ref AILIA_USER_API_SUCCESS を返す。 + * 失敗した場合、 \ref AILIA_USER_API_FAILED を返す。 + * 標準APIとは異なり、返値はAILIA_USER_API_*になりますのでご注意ください。 + * + * \~english + * @brief Reads data from the file. + * @param void * A pointer to the storage location of the data to be read + * @param \ref AILIA_FSIZE_RETURN_TYPE The length in bytes of the data to be read + * @param void * A user-defined file pointer + * @return + * This function returns \ref AILIA_USER_API_SUCCESS if successful. + * It returns \ref AILIA_USER_API_FAILED if it fails. + * Note that unlike the standard API, the return value will be AILIA_USER_API_*. + */ + typedef int (AILIA_USER_API *AILIA_USER_API_FREAD) (void *, AILIA_FSIZE_RETURN_TYPE, void*); + + /** + * \~japanese + * @brief ファイルを閉じます + * @param void * ユーザ定義ファイルポインタ + * @return + * 成功した場合、 \ref AILIA_USER_API_SUCCESS を返す。 + * 失敗した場合、 \ref AILIA_USER_API_FAILED を返す。 + * + * \~english + * @brief Closes the file. + * @param void * A user-defined file pointer + * @return + * This function returns \ref AILIA_USER_API_SUCCESS if successful. + * It returns \ref AILIA_USER_API_FAILED if it fails. + */ + typedef int (AILIA_USER_API *AILIA_USER_API_FCLOSE) (void*); + + /** + * \~japanese + * @def AILIA_FILE_CALLBACK_VERSION + * @brief 構造体バージョン + * + * \~english + * @def AILIA_FILE_CALLBACK_VERSION + * @brief Struct version + */ + #define AILIA_FILE_CALLBACK_VERSION (1) + + /* ファイルアクセスコールバック関数構造体 */ + typedef struct _ailiaFileCallback { + AILIA_USER_API_FOPEN fopen; /* ユーザ定義fopen関数 */ + AILIA_USER_API_FSEEK fseek; /* ユーザ定義fseek関数 */ + AILIA_USER_API_FTELL ftell; /* ユーザ定義ftell関数 */ + AILIA_USER_API_FREAD fread; /* ユーザ定義fread関数 */ + AILIA_USER_API_FSIZE fsize; /* ユーザ定義fsize関数 */ + AILIA_USER_API_FCLOSE fclose; /* ユーザ定義fclose関数 */ + } ailiaFileCallback; + + + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA_CALL) */ diff --git a/include/ailia/ailia_classifier.h b/include/ailia/ailia_classifier.h new file mode 100644 index 0000000..fc445ee --- /dev/null +++ b/include/ailia/ailia_classifier.h @@ -0,0 +1,168 @@ +/** + * \~japanese + * @file ailia_classifier.h + * @brief 物体識別ライブラリ + * @copyright AXELL CORPORATION, ax Inc. + * @date 2021/07/28 + * + * \~english + * @file ailia_classifier.h + * @brief object classification library + * @copyright AXELL CORPORATION, ax Inc. + * @date 2021/07/28 + */ + +#if !defined(INCLUDED_AILIA_CLASSIFIER) +#define INCLUDED_AILIA_CLASSIFIER + +/* コアライブラリ */ + +#include "ailia.h" +#include "ailia_format.h" + +/* 呼び出し規約 */ + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************** + * 識別オブジェクトのインスタンス + **/ + + struct AILIAClassifier; + + /**************************************************************** + * 識別情報 + **/ + + #define AILIA_CLASSIFIER_CLASS_VERSION (1) + + typedef struct _AILIAClassifierClass { + /** + * \~japanese + * 識別カテゴリ番号 + * + * \~english + * Classification category number + */ + int category; + /** + * \~japanese + * 推定確率(0~1) + * + * \~english + * Estimated probability (0 to 1) + */ + float prob; + }AILIAClassifierClass; + + /** + * \~japanese + * @brief 識別オブジェクトを作成します。 + * @param classifier 識別オブジェクトポインタへのポインタ + * @param net ネットワークオブジェクトポインタ + * @param format ネットワークの画像フォーマット (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param channel ネットワークの画像チャンネル (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param range ネットワークの画像レンジ (AILIA_NETWORK_IMAGE_RANGE_*) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Creates a classifier instance. + * @param classifier A pointer to a classifier instance pointer + * @param net A network instance pointer + * @param format The network image format (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param channel The network image channel (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param range The network image range (AILIA_NETWORK_IMAGE_RANGE_*) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaCreateClassifier(struct AILIAClassifier **classifier, struct AILIANetwork *net, unsigned int format, unsigned int channel, unsigned int range); + + /** + * \~japanese + * @brief 識別オブジェクトを破棄します。 + * @param classifier 識別オブジェクトポインタ + * + * \~english + * @brief Destroys the classifier instance. + * @param classifier A classifier instance pointer + */ + void AILIA_API ailiaDestroyClassifier(struct AILIAClassifier *classifier); + + /** + * \~japanese + * @brief 物体識別を行います。 + * @param classifier 識別オブジェクトポインタ + * @param src 画像データ(32bpp) + * @param src_stride 1ラインのバイト数 + * @param src_width 画像幅 + * @param src_height 画像高さ + * @param src_format 画像のフォーマット (AILIA_IMAGE_FORMAT_*) + * @param max_class_count 識別結果の数の最大 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Performs object classification. + * @param classifier A classifier instance pointer + * @param src Image data (32 bpp) + * @param src_stride The number of bytes in 1 line + * @param src_width Image width + * @param src_height Image height + * @param src_format Image format (AILIA_IMAGE_FORMAT_*) + * @param max_class_count The maximum number of classification results + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaClassifierCompute(struct AILIAClassifier *classifier,const void *src, unsigned int src_stride, unsigned int src_width, unsigned int src_height, unsigned int src_format, unsigned int max_class_count); + + /** + * \~japanese + * @brief 識別結果の数を取得します。 + * @param classifier 識別オブジェクトポインタ + * @param cls_count クラス数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the number of classification results. + * @param classifier A classifier instance pointer + * @param cls_count The number of classes + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaClassifierGetClassCount(struct AILIAClassifier *classifier, unsigned int *cls_count); + + /** + * \~japanese + * @brief 識別結果を取得します。 + * @param classifier 識別オブジェクトポインタ + * @param cls クラス情報 + * @param cls_idx クラスインデックス + * @param version \ref AILIA_CLASSIFIER_CLASS_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ailiaClassifierCompute() を一度も実行していない場合は \ref AILIA_STATUS_INVALID_STATE が返ります。 + * 識別結果は推定確率順でソートされます。 + * + * \~english + * @brief Gets the classification results. + * @param classifier A classifier instance pointer + * @param cls Class information + * @param cls_idx Class index + * @param version \ref AILIA_CLASSIFIER_CLASS_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * If ailiaClassifierCompute() is not run at all, the function returns \ref AILIA_STATUS_INVALID_STATE . + * The classification results are sorted in the order of estimated probability. + */ + int AILIA_API ailiaClassifierGetClass(struct AILIAClassifier *classifier, AILIAClassifierClass* obj, unsigned int cls_idx, unsigned int version); + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA_CLASSIFIER) */ diff --git a/include/ailia/ailia_detector.h b/include/ailia/ailia_detector.h new file mode 100644 index 0000000..da4a35d --- /dev/null +++ b/include/ailia/ailia_detector.h @@ -0,0 +1,279 @@ +/** +* \~japanese +* @file +* @brief AILIA 物体検出ライブラリ +* @copyright AXELL CORPORATION, ax Inc. +* @date 2021/07/28 +* +* \~english +* @file +* @brief AILIA object detection library +* @copyright AXELL CORPORATION, ax Inc. +* @date July 28, 2021 +*/ +#if !defined(INCLUDED_AILIA_DETECTOR) +#define INCLUDED_AILIA_DETECTOR + +/* コアライブラリ */ + +#include "ailia.h" +#include "ailia_format.h" + +/* 呼び出し規約 */ + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************** + * 検出オブジェクトのインスタンス + **/ + + struct AILIADetector; + + /**************************************************************** + * 物体情報 + **/ + #define AILIA_DETECTOR_OBJECT_VERSION (1) + + typedef struct _AILIADetectorObject { + /** + * \~japanese + * オブジェクトカテゴリ番号(0~category_count-1) + * + * \~english + * Object category number (0 to category_count-1) + */ + unsigned int category; + /** + * \~japanese + * 推定確率(0~1) + * + * \~english + * Estimated probability (0 to 1) + */ + float prob; + /** + * \~japanese + * 左上X位置(1で画像幅) + * + * \~english + * X position at the top left (1 for the image width) + */ + float x; + /** + * \~japanese + * 左上Y位置(1で画像高さ) + * + * \~english + * Y position at the top left (1 for the image height) + */ + float y; + /** + * \~japanese + * 幅(1で画像横幅、負数は取らない) + * + * \~english + * Width (1 for the width of the image, negative numbers not allowed) + */ + float w; + /** + * \~japanese + * 高さ(1で画像高さ、負数は取らない) + * + * \~english + * Height (1 for the height of the image, negative numbers not allowed) + */ + float h; + }AILIADetectorObject; + + #define AILIA_DETECTOR_ALGORITHM_YOLOV1 (0) //YOLOV1 + #define AILIA_DETECTOR_ALGORITHM_YOLOV2 (1) //YOLOV2 + #define AILIA_DETECTOR_ALGORITHM_YOLOV3 (2) //YOLOV3 + #define AILIA_DETECTOR_ALGORITHM_YOLOV4 (3) //YOLOV4 + #define AILIA_DETECTOR_ALGORITHM_YOLOX (4) //YOLOX + #define AILIA_DETECTOR_ALGORITHM_SSD (8) //SSD(Single Shot multibox Detector) + + #define AILIA_DETECTOR_FLAG_NORMAL (0) //オプションなし + + /**************************************************************** + * 物体検出API + **/ + + /** + * \~japanese + * @brief 検出オブジェクトを作成します。 + * @param detector 検出オブジェクトポインタ + * @param net ネットワークオブジェクトポインタ + * @param format ネットワークの画像フォーマット (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param channel ネットワークの画像チャンネル (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param range ネットワークの画像レンジ (AILIA_NETWORK_IMAGE_RANGE_*) + * @param algorithm 検出アルゴリズム(AILIA_DETECTOR_ALGORITHM_*) + * @param category_count 検出カテゴリ数(VOCの場合は20、COCOの場合は80、などを指定) + * @param flags 追加オプションフラグ(AILIA_DETECTOR_FLAG_*) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Creates a detector instance. + * @param detector A detector instance pointer + * @param net The network instance pointer + * @param format The network image format (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param channel The network image channel (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param range The network image range (AILIA_NETWORK_IMAGE_RANGE_*) + * @param algorithm Detection algorithm(AILIA_DETECTOR_ALGORITHM_*) + * @param category_count The number of detection categories (specify 20 for VOC or 80 for COCO, etc.) + * @param flags Additional option(AILIA_DETECTOR_FLAG_*) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaCreateDetector(struct AILIADetector **detector,struct AILIANetwork *net, unsigned int format, unsigned int channel, unsigned int range, unsigned int algorithm, unsigned int category_count, unsigned int flags); + + /** + * \~japanese + * @brief 検出オブジェクトを破棄します。 + * @param detector 検出オブジェクトポインタ + * + * \~english + * @brief Destroys the detector instance. + * @param detector A detector instance pointer + */ + void AILIA_API ailiaDestroyDetector(struct AILIADetector *detector); + + /** + * \~japanese + * @brief 物体検出を行います。 + * @param detector 検出オブジェクトポインタ + * @param src 画像データ(32bpp) + * @param src_stride 1ラインのバイト数 + * @param src_width 画像幅 + * @param src_height 画像高さ + * @param src_format 画像フォーマット (AILIA_IMAGE_FORMAT_*) + * @param threshold 検出しきい値(0.1f等)(小さいほど検出されやすくなり、検出数増加) + * @param iou 重複除外しきい値(0.45f等)(小さいほど重複を許容せず検出数減少) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Performs object detection. + * @param detector A detector instance pointer + * @param src Image data (32 bpp) + * @param src_stride The number of bytes in 1 line + * @param src_width Image width + * @param src_height Image height + * @param src_format Image format (AILIA_IMAGE_FORMAT_*) + * @param threshold The detection threshold (for example, 0.1f) (The smaller it is, the easier the detection will be and the more detected objects found.) + * @param iou Iou threshold (for example, 0.45f) (The smaller it is, the fewer detected objects found, as duplication is not allowed.) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaDetectorCompute(struct AILIADetector *detector, const void *src, unsigned int src_stride, unsigned int src_width, unsigned int src_height, unsigned int src_format, float threshold, float iou); + + /** + * \~japanese + * @brief 検出結果の数を取得します。 + * @param detector 検出オブジェクトポインタ + * @param obj_count オブジェクト数 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the number of detection results. + * @param detector A detector instance pointer + * @param obj_count The number of objects + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaDetectorGetObjectCount(struct AILIADetector *detector, unsigned int *obj_count); + + /** + * \~japanese + * @brief 検出結果を取得します。 + * @param detector 検出オブジェクトポインタ + * @param obj オブジェクト情報 + * @param obj_idx オブジェクトインデックス + * @param version AILIA_DETECTOR_OBJECT_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * ailiaDetectorCompute() を一度も実行していない場合は \ref AILIA_STATUS_INVALID_STATE が返ります。 + * 検出結果は推定確率順でソートされます。 + * + * \~english + * @brief Gets the detection results. + * @param detector A detector instance pointer + * @param obj Object information + * @param obj_idx Object index + * @param version AILIA_DETECTOR_OBJECT_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * If ailiaDetectorCompute() is not run at all, the function returns \ref AILIA_STATUS_INVALID_STATE . + * The detection results are sorted in the order of estimated probability. + */ + int AILIA_API ailiaDetectorGetObject(struct AILIADetector *detector, AILIADetectorObject* obj, unsigned int obj_idx, unsigned int version); + + /** + * \~japanese + * @brief YoloV2などのためにアンカーズ (anchorsまたはbiases) の情報を設定します。 + * @param detector 検出オブジェクトポインタ + * @param anchors アンカーズの寸法 (検出ボックスの形状、高さと幅) + * @param anchors_count アンカーズの数 (anchorsの配列サイズの半分) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * YoloV2などは学習時に決定された複数の検出ボックスを使用して物体検出を行います。このAPIで学習時に決定された検出ボックスの形状を設定することで、正しい推論を行います。 + * anchorsには{x,y,x,y...}の形式で格納します。 + * anchors_countが5の場合、anchorsは10次元の配列になります。 + * + * \~english + * @brief Sets the anchor information (anchors or biases) for YoloV2 or other systems. + * @param detector A detector instance pointer + * @param anchors The anchor dimensions (the shape, height and width of the detection box) + * @param anchors_count The number of anchors (half of the anchors array size) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * YoloV2 and other systems perform object detection with multiple detection boxes determined during training. By using this API function to set the shape of the detection box determined during training, correct inferences can be made. + * The {x, y, x, y ...} format is used for anchor storage. + * If anchors_count has a value of 5, then anchors is a 10-dimensional array. + */ + int AILIA_API ailiaDetectorSetAnchors(struct AILIADetector *detector, float *anchors, unsigned int anchors_count); + + /** + * \~japanese + * @brief YoloV3またはYoloXでのモデルへの入力画像サイズを指定します。 + * @param detector 検出オブジェクトポインタ + * @param input_width モデルの入力画像幅 + * @param input_height モデルの入力画像高さ + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * YoloV3では単一のモデルが任意の入力解像度に対応します。(32 の倍数制限あり) + * YoloXでは単一のモデルが任意の入力解像度に対応します。 + * 計算量の削減等でモデルへの入力画像サイズを指定する場合この API を実行してください。 + * ailiaCreateDetector() () と ailiaDetectorCompute() () の間に実行する必要があります。 + * この API を実行しない場合、デフォルトの 416x416 を利用します。 + * YOLOv3またはYOLOX 以外で実行した場合、 \ref AILIA_STATUS_INVALID_STATE を返します。 + * + * \~english + * @brief Sets the size of the input image for YoloV3 or YoloX model. + * @param detector A detector instance pointer + * @param input_width Width of the model's input image + * @param input_height Height of the model's input image + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * The same YoloV3 model can be used for any input image size that is a multiple of 32. + * The same YoloX model can be used for any input image size. + * You can use this API if you want to choose the input image size, for example to reduce the calculation complexity. + * It must be called between ailiaCreateDetector() () and ailiaDetectorCompute() (). + * If this API is not used, a default size of 416x416 is assumed. + * If used with some model other than YoloV3 or YoloX, it will return the error status \ref AILIA_STATUS_INVALID_STATE . + */ + int AILIA_API ailiaDetectorSetInputShape(struct AILIADetector *detector, unsigned int input_width, unsigned int input_height); + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA_DETECTOR) */ diff --git a/include/ailia/ailia_feature_extractor.h b/include/ailia/ailia_feature_extractor.h new file mode 100644 index 0000000..c9868ed --- /dev/null +++ b/include/ailia/ailia_feature_extractor.h @@ -0,0 +1,144 @@ +/** +* \~japanese +* @file +* @brief AILIA 特徴抽出ライブラリ +* @copyright AXELL CORPORATION, ax Inc. +* @date 2021/07/28 +* +* \~english +* @file +* @brief AILIA feature extraction library +* @copyright AXELL CORPORATION, ax Inc. +* @date July 28, 2021 +*/ +#if !defined(INCLUDED_AILIA_FEATURE_EXTRACTOR) +#define INCLUDED_AILIA_FEATURE_EXTRACTOR + +/* コアライブラリ */ + +#include "ailia.h" +#include "ailia_format.h" + +/* 呼び出し規約 */ + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************** + * 特徴抽出オブジェクトのインスタンス + **/ + + struct AILIAFeatureExtractor; + + /**************************************************************** + * 距離設定 + **/ + + /** + * \~japanese + * @def AILIA_FEATURE_EXTRACTOR_DISTANCE_L2NORM + * @brief L2ノルム + * + * \~english + * @def AILIA_FEATURE_EXTRACTOR_DISTANCE_L2NORM + * @brief L2 norm + */ + #define AILIA_FEATURE_EXTRACTOR_DISTANCE_L2NORM (0) + + /** + * \~japanese + * @brief 特徴抽出オブジェクトを作成します。 + * @param fextractor 特徴抽出オブジェクトポインタ + * @param net ネットワークオブジェクトポインタ + * @param format ネットワークの画像フォーマット (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param channel ネットワークの画像チャンネル (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param range ネットワークの画像レンジ (AILIA_NETWORK_IMAGE_RANGE_*) + * @param layer_name 特徴に対応したレイヤーの名称 (VGG16の場合はfc1, NULLで最終レイヤー) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Creates a feature extraction instance. + * @param fextractor A feature extraction instance pointer + * @param net A network instance pointer + * @param format The network image format (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param channel The network image channel (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param range The network image range (AILIA_NETWORK_IMAGE_RANGE_*) + * @param layer_name The name of the layer corresponding to the feature (fc1 for VGG16 and NULL for the last layer) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaCreateFeatureExtractor(struct AILIAFeatureExtractor **fextractor, struct AILIANetwork *net, unsigned int format, unsigned int channel, unsigned int range, const char *layer_name); + + /** + * \~japanese + * @brief 特徴抽出オブジェクトを破棄します。 + * @param fextractor 特徴抽出オブジェクトポインタ + * + * \~english + * @brief It destroys the feature extraction instance. + * @param fextractor A feature extraction instance pointer + */ + void AILIA_API ailiaDestroyFeatureExtractor(struct AILIAFeatureExtractor *fextractor); + + /** + * \~japanese + * @brief 特徴の抽出を行います。 + * @param fextractor 特徴抽出オブジェクトポインタ + * @param dst 特徴の格納先ポインタ(numeric型) + * @param dst_size dstのサイズ(byte) + * @param src 画像データ(32bpp) + * @param src_stride 1ラインのバイト数 + * @param src_width 画像幅 + * @param src_height 画像高さ + * @param src_format 画像フォーマット (AILIA_IMAGE_FORMAT_*) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Performs feature extraction. + * @param fextractor A feature extraction instance pointer + * @param dst A pointer to the storage location of the feature (numeric type) + * @param dst_size The size of the dst (bytes) + * @param src Image data (32 bpp) + * @param src_stride The number of bytes in 1 line + * @param src_width Image width + * @param src_height Image height + * @param src_format Image format (AILIA_IMAGE_FORMAT_*) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaFeatureExtractorCompute(struct AILIAFeatureExtractor *fextractor, void *dst, unsigned int dst_size, const void *src, unsigned int src_stride, unsigned int src_width, unsigned int src_height, unsigned int src_format); + + /** + * \~japanese + * @brief 特徴間の距離を計算します。 + * @param fextractor 特徴抽出オブジェクトポインタ + * @param distance 特徴間距離 + * @param distance_type 特徴間距離の種別 + * @param feature1 一方の特徴の格納先ポインタ(numeric型) + * @param feature1_size dstのサイズ(byte) + * @param feature2 他方の特徴の格納先ポインタ(numeric型) + * @param feature2_size dstのサイズ(byte) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Computes distances in feature space. + * @param fextractor A feature extraction instance pointer + * @param distance A distance in feature space + * @param distance_type The type of the distance in feature space + * @param feature1 A pointer to the storage location of one feature (numeric type) + * @param feature1_size The size of the feature1 (bytes) + * @param feature2 A pointer to the storage location of the other feature (numeric type) + * @param feature2_size The size of the feature2 (bytes) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaFeatureExtractorMatch(struct AILIAFeatureExtractor *fextractor, float *distance, unsigned int distace_type, const void *feature1, unsigned int feature1_size, const void *feature2, unsigned int feature2_size); + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA_FEATURE_EXTRACTOR) */ diff --git a/include/ailia/ailia_format.h b/include/ailia/ailia_format.h new file mode 100644 index 0000000..b96645c --- /dev/null +++ b/include/ailia/ailia_format.h @@ -0,0 +1,226 @@ +/** +* \~japanese +* @file +* @brief AILIA フォーマット定義・変換 +* @copyright AXELL CORPORATION, ax Inc. +* @date 2021/07/28 +* +* \~english +* @file +* @brief AILIA format definition and conversion +* @copyright AXELL CORPORATION, ax Inc. +* @date July 28, 2021 +*/ +#if !defined(INCLUDED_AILIA_FORMAT) +#define INCLUDED_AILIA_FORMAT + +/* 呼び出し規約 */ + +#if defined(_M_JS) +#include +#define AILIA_API EMSCRIPTEN_KEEPALIVE +#elif defined(_WIN64) || defined(_M_X64) || defined(__amd64__) || defined(__x86_64__) || defined(__APPLE__) || defined(__ANDROID__) || defined(ANDROID) || defined(__linux__) || defined(NN_NINTENDO_SDK) +#define AILIA_API +#else +#define AILIA_API __stdcall +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************** + * 入力画像フォーマット + **/ + + /** + * \~japanese + * RGBA順 + * + * \~english + * RGBA order + */ + #define AILIA_IMAGE_FORMAT_RGBA (0x00) + /** + * \~japanese + * BGRA順 + * + * \~english + * BGRA order + */ + #define AILIA_IMAGE_FORMAT_BGRA (0x01) + /** + * \~japanese + * RGB順 + * + * \~english + * RGB order + */ + #define AILIA_IMAGE_FORMAT_RGB (0x02) + /** + * \~japanese + * BGR順 + * + * \~english + * BGR order + */ + #define AILIA_IMAGE_FORMAT_BGR (0x03) + + /** + * \~japanese + * RGBA順(Bottom to Top) + * + * \~english + * RGBA order (Bottom to top) + */ + #define AILIA_IMAGE_FORMAT_RGBA_B2T (0x10) + /** + * \~japanese + * BGRA順(Bottom to Top) + * + * \~english + * BGRA order (Bottom to top) + */ + #define AILIA_IMAGE_FORMAT_BGRA_B2T (0x11) + + /**************************************************************** + * ネットワーク画像フォーマット + **/ + + /** + * \~japanese + * BGR順 + * + * \~english + * BGR order + */ + #define AILIA_NETWORK_IMAGE_FORMAT_BGR (0) + /** + * \~japanese + * RGB順 + * + * \~english + * RGB order + */ + #define AILIA_NETWORK_IMAGE_FORMAT_RGB (1) + /** + * \~japanese + * Gray Scale (1ch) + * + * \~english + * Gray Scale (1ch) + */ + #define AILIA_NETWORK_IMAGE_FORMAT_GRAY (2) + /** + * \~japanese + * ヒストグラム平坦化 Gray Scale (1ch) + * + * \~english + * Equalized Gray Scale (1ch) + */ + #define AILIA_NETWORK_IMAGE_FORMAT_GRAY_EQUALIZE (3) + + /** + * \~japanese + * DCYX順 + * + * \~english + * DCYX order + */ + #define AILIA_NETWORK_IMAGE_CHANNEL_FIRST (0) + /** + * \~japanese + * DYXC順 + * + * \~english + * DYXC order + */ + #define AILIA_NETWORK_IMAGE_CHANNEL_LAST (1) + + /** + * \~japanese + * 0 ~ 255 + * + * \~english + * 0 to 255 + */ + #define AILIA_NETWORK_IMAGE_RANGE_UNSIGNED_INT8 (0) + /** + * \~japanese + * -128 ~ 127 + * + * \~english + * -128 to 127 + */ + #define AILIA_NETWORK_IMAGE_RANGE_SIGNED_INT8 (1) + /** + * \~japanese + * 0.0 ~ 1.0 + * + * \~english + * 0.0 to 1.0 + */ + #define AILIA_NETWORK_IMAGE_RANGE_UNSIGNED_FP32 (2) + /** + * \~japanese + * -1.0 ~ 1.0 + * + * \~english + * -1.0 to 1.0 + */ + #define AILIA_NETWORK_IMAGE_RANGE_SIGNED_FP32 (3) + /** + * \~japanese + * ImageNet mean&std normalize + * + * \~english + * ImageNet mean&std normalize + */ + #define AILIA_NETWORK_IMAGE_RANGE_IMAGENET (4) + + + /** + * \~japanese + * @brief 画像のフォーマットを変換します。 + * @param dst 変換後画像の格納先(numeric型、sizeof(float) * dst_width * dst_height * チャンネル数(解説参照)以上のサイズを確保すること) + * @param dst_width 変換後画像の横幅 + * @param dst_height 変換後画像の高さ + * @param dst_format 変換後画像の形式 (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param dst_channel 変換後画像のチャンネル順 (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param dst_range 変換後画像のレンジ (AILIA_NETWORK_IMAGE_RANGE_*) + * @param src 変換元画像の格納先(32bpp) + * @param src_stride 変換元画像のラインバイト数 + * @param src_width 変換元画像の横幅 + * @param src_height 変換元画像の高さ + * @param src_format 変換元画像の形式 (AILIA_IMAGE_FORMAT_*) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * 画像フォーマットを変更します。dst_formatが \ref AILIA_NETWORK_IMAGE_FORMAT_BGR もしくはAILIA_NETWORK_IMAGE_FORMAT_RGB + * の場合、チャンネル数は3, \ref AILIA_NETWORK_IMAGE_FORMAT_GRAY の場合チャンネル数は1となります。 + * + * \~english + * @brief Converts image formats. + * @param dst The storage location of the image after conversion (numeric type; a size of sizeof(float) * dst_width * dst_height * num_of_channel(See Description) or more must be allocated.) + * @param dst_width The width of the image after conversion + * @param dst_height The height of the image after conversion + * @param dst_format The format of the image after conversion (AILIA_NETWORK_IMAGE_FORMAT_*) + * @param dst_channel The channel order of the image after conversion (AILIA_NETWORK_IMAGE_CHANNEL_*) + * @param dst_range The range of the image after conversion (AILIA_NETWORK_IMAGE_RANGE_*) + * @param src The storage location of the source image (32 bpp) + * @param src_stride The line byte number of the source image + * @param src_width The width of the source image + * @param src_height The height of the source image + * @param src_format The format of the source image (AILIA_IMAGE_FORMAT_*) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function converts image formats. If dst_format is set to \ref AILIA_NETWORK_IMAGE_FORMAT_BGR or \ref AILIA_NETWORK_IMAGE_FORMAT_RGB , + * the number of channels is 3, otherwise if set to \ref AILIA_NETWORK_IMAGE_FORMAT_GRAY , the number of channels is 1. + */ + int AILIA_API ailiaFormatConvert(void *dst, unsigned int dst_width, unsigned int dst_height, unsigned int dst_format, unsigned int dst_channel, unsigned int dst_range, const void *src, int src_stride, unsigned int src_width, unsigned int src_height, unsigned int src_format); + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA_FORMAT) */ diff --git a/include/ailia/ailia_pose_estimator.h b/include/ailia/ailia_pose_estimator.h new file mode 100644 index 0000000..5b15e88 --- /dev/null +++ b/include/ailia/ailia_pose_estimator.h @@ -0,0 +1,560 @@ +/** +* \~japanese +* @file +* @brief AILIA 骨格検出・顔特徴点検出ライブラリ +* @copyright AXELL CORPORATION, ax Inc. +* @date 2021/07/28 +* +* \~english +* @file +* @brief AILIA library for human pose estimation and human face landmarks extraction +* @copyright AXELL CORPORATION, ax Inc. +* @date July 28, 2021 +*/ +#if !defined(INCLUDED_AILIA_POSE_ESTIMATOR) +#define INCLUDED_AILIA_POSE_ESTIMATOR + +/* コアライブラリ */ + +#include "ailia.h" +#include "ailia_format.h" + +/* 呼び出し規約 */ + +#ifdef __cplusplus +extern "C" { +#endif + + /**************************************************************** + * 検出オブジェクトのインスタンス + **/ + + struct AILIAPoseEstimator; + + /**************************************************************** + * 物体情報 + **/ + + /** + * \~japanese + * 骨格検出 + * + * \~english + * Human pose estimation + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_ACCULUS_POSE ( 0) + /** + * \~japanese + * 顔特徴点検出 + * + * \~english + * Human face landmarks extraction + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_ACCULUS_FACE ( 1) + /** + * \~japanese + * 近接上半身姿勢検出 + * + * \~english + * Human upper body pose estimation + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_ACCULUS_UPPOSE ( 2) + /** + * \~japanese + * 近接上半身2姿勢検出(FPGA向け) + * + * \~english + * Human upper body pose estimation(FPGA) + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_ACCULUS_UPPOSE_FPGA ( 3) + /** + * \~japanese + * 手姿勢検出 + * + * \~english + * Human hand estimation + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_ACCULUS_HAND ( 5) + /** + * \~japanese + * 骨格検出 + * + * \~english + * Human pose estimation + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_OPEN_POSE (10) + /** + * \~japanese + * 骨格検出 + * + * \~english + * Human pose estimation + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_LW_HUMAN_POSE (11) + /** + * \~japanese + * 骨格検出 + * + * \~english + * Human pose estimation + */ + #define AILIA_POSE_ESTIMATOR_ALGORITHM_OPEN_POSE_SINGLE_SCALE (12) + + /* 骨格検出 関節点 定義 */ + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_NOSE (0) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_EYE_LEFT (1) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_EYE_RIGHT (2) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_EAR_LEFT (3) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_EAR_RIGHT (4) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_SHOULDER_LEFT (5) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_SHOULDER_RIGHT (6) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_ELBOW_LEFT (7) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_ELBOW_RIGHT (8) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_WRIST_LEFT (9) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_WRIST_RIGHT (10) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_HIP_LEFT (11) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_HIP_RIGHT (12) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_KNEE_LEFT (13) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_KNEE_RIGHT (14) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_ANKLE_LEFT (15) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_ANKLE_RIGHT (16) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_SHOULDER_CENTER (17) + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_BODY_CENTER (18) + /** + * \~japanese + * 個数 + * + * \~english + * Count + */ + #define AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_CNT (19) + + /* 顔特徴点検出 定義 */ + /** + * \~japanese + * 個数 + * + * \~english + * Count + */ + #define AILIA_POSE_ESTIMATOR_FACE_KEYPOINT_CNT (68) + + /* 近接上半身姿勢検出 関節点 定義 */ + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_NOSE (0) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_EYE_LEFT (1) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_EYE_RIGHT (2) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_EAR_LEFT (3) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_EAR_RIGHT (4) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_SHOULDER_LEFT (5) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_SHOULDER_RIGHT (6) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_ELBOW_LEFT (7) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_ELBOW_RIGHT (8) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_WRIST_LEFT (9) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_WRIST_RIGHT (10) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_HIP_LEFT (11) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_HIP_RIGHT (12) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_SHOULDER_CENTER (13) + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_BODY_CENTER (14) + /** + * \~japanese + * 個数 + * + * \~english + * Count + */ + #define AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_CNT (15) + + /* 手姿勢検出 点 定義 */ + /** + * \~japanese + * 個数 + * + * \~english + * Count + */ + #define AILIA_POSE_ESTIMATOR_HAND_KEYPOINT_CNT (21) + + typedef struct _AILIAPoseEstimatorKeypoint { + /** + * \~japanese + * 入力画像内 X座標 (0.0 , 1.0) + * + * \~english + * Input image X coordinate (0.0, 1.0) + */ + float x; + /** + * \~japanese + * 入力画像内 Y座標 (0.0 , 1.0) + * + * \~english + * Input image Y coordinate (0.0, 1.0) + */ + float y; + /** + * \~japanese + * 骨格検出のみ有効。体中心を座標0とした時に推定されるローカルZ座標。単位(スケール)は x と同じです。 + * + * \~english + * Valid only for human pose estimation. The local Z coordinate is estimated when the center of the body is defined as coordinate 0. The unit (scale) is the same as that for X. + */ + float z_local; + /** + * \~japanese + * この点の検出信頼度。値が0.0Fの場合、この点は未検出のため使用できません。 + * + * \~english + * The confidence of this point. If the value is 0.0F, then this point is not available as it has not been detected yet. + */ + float score; + /** + * \~japanese + * 通常は0です。この点が未検出で、他の点から補間可能な場合、x,yの値を補間し、interpolated=1となります。 + * + * \~english + * The default is 0. If this point has not been detected and can be interpolated by other points, the x and y values are then interpolated and the value of interpolated is set to 1. + */ + int interpolated; + }AILIAPoseEstimatorKeypoint; + + /** + * \~japanese + * 構造体フォーマットバージョン + * + * \~english + * Version of the struct format + */ + #define AILIA_POSE_ESTIMATOR_OBJECT_POSE_VERSION (1) + typedef struct _AILIAPoseEstimatorObjectPose { + /** + * \~japanese + * 検出した関節点。配列インデックスが関節番号に相当します。 + * + * \~english + * Detected body joint positions. The array index corresponding to a body joint number. + */ + AILIAPoseEstimatorKeypoint points[AILIA_POSE_ESTIMATOR_POSE_KEYPOINT_CNT]; + /** + * \~japanese + * このオブジェクトの検出信頼度 + * + * \~english + * The confidence of this object + */ + float total_score; + /** + * \~japanese + * points[]の中で正常に検出された関節点の個数 + * + * \~english + * The number of body joint positions properly detected in points[] + */ + int num_valid_points; + /** + * \~japanese + * 時間方向に、このオブジェクトにユニークなIDです。1以上の正の値です。 + * + * \~english + * A unique ID for this object in the time direction. An integer value of 1 or more. + */ + int id; + /** + * \~japanese + * このオブジェクトのオイラー角 yaw, pitch, roll [単位radian]。現在yawのみ対応しています。角度が検出されない場合FLT_MAXが格納されます。 + * + * \~english + * Euler angles for this object: yaw, pitch, and roll (in radians). Currently, only yaw is supported. If the angles are not detected, they are set to FLT_MAX. + */ + float angle[3]; + }AILIAPoseEstimatorObjectPose; + + /** + * \~japanese + * 構造体フォーマットバージョン + * + * \~english + * Version of the struct format + */ + #define AILIA_POSE_ESTIMATOR_OBJECT_FACE_VERSION (1) + typedef struct _AILIAPoseEstimatorObjectFace { + /** + * \~japanese + * 検出した顔特徴点。配列インデックスが顔特徴点番号に相当します。 + * + * \~english + * Detected human face landmarks. The array index corresponding to a human face landmark number. + */ + AILIAPoseEstimatorKeypoint points[AILIA_POSE_ESTIMATOR_FACE_KEYPOINT_CNT]; + /** + * \~japanese + * このオブジェクトの検出信頼度 + * + * \~english + * The confidence of this object + */ + float total_score; + }AILIAPoseEstimatorObjectFace; + + /** + * \~japanese + * 構造体フォーマットバージョン + * + * \~english + * Version of the struct format + */ + #define AILIA_POSE_ESTIMATOR_OBJECT_UPPOSE_VERSION (1) + typedef struct _AILIAPoseEstimatorObjectUpPose { + /** + * \~japanese + * 検出した関節点。配列インデックスが関節番号に相当します。 + * + * \~english + * Detected body joint positions. The array index corresponding to a body joint number. + */ + AILIAPoseEstimatorKeypoint points[AILIA_POSE_ESTIMATOR_UPPOSE_KEYPOINT_CNT]; + /** + * \~japanese + * このオブジェクトの検出信頼度 + * + * \~english + * The confidence of this object + */ + float total_score; + /** + * \~japanese + * points[]の中で正常に検出された関節点の個数 + * + * \~english + * The number of body joint positions properly detected in points[] + */ + int num_valid_points; + /** + * \~japanese + * 時間方向に、このオブジェクトにユニークなIDです。1以上の正の値です。 + * + * \~english + * A unique ID for this object in the time direction. An integer value of 1 or more. + */ + int id; + /** + * \~japanese + * このオブジェクトのオイラー角 yaw, pitch, roll [単位radian]。現在yawのみ対応しています。角度が検出されない場合FLT_MAXが格納されます。 + * + * \~english + * Euler angles for this object: yaw, pitch, and roll (in radians). Currently, only yaw is supported. If the angles are not detected, they are set to FLT_MAX. + */ + float angle[3]; + }AILIAPoseEstimatorObjectUpPose; + + /** + * \~japanese + * 構造体フォーマットバージョン + * + * \~english + * Version of the struct format + */ + #define AILIA_POSE_ESTIMATOR_OBJECT_HAND_VERSION (1) + typedef struct _AILIAPoseEstimatorObjectHand { + /** + * \~japanese + * 検出した関節点。配列インデックスが関節番号に相当します。 + * + * \~english + * Detected hand joint positions. The array index corresponding to a hand joint number. + */ + AILIAPoseEstimatorKeypoint points[AILIA_POSE_ESTIMATOR_HAND_KEYPOINT_CNT]; + /** + * \~japanese + * このオブジェクトの検出信頼度 + * + * \~english + * The confidence of this object + */ + float total_score; + }AILIAPoseEstimatorObjectHand; + + /**************************************************************** + * 骨格検出・顔特徴点検出API + **/ + + /** + * \~japanese + * @brief 検出オブジェクトを作成します。 + * @param pose_estimator 検出オブジェクトポインタ + * @param net ネットワークオブジェクトポインタ + * @param algorithm 検出アルゴリズム (AILIA_POSE_ESTIMATOR_ALGORITHM_*) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * @details + * caffemodelとprototxtを読み込んだAILIANetworkから検出オブジェクトを作成します。 + * + * \~english + * @brief Creates a estimator instance. + * @param pose_estimator An estimator instance pointer + * @param net The network instance pointer + * @param algorithm Estimation algorithm(AILIA_POSE_ESTIMATOR_ALGORITHM_*) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + * @details + * This function creates an estimator instance from AILIANetwork when reading caffemodel and prototxt. + */ + int AILIA_API ailiaCreatePoseEstimator(struct AILIAPoseEstimator **pose_estimator, struct AILIANetwork *net, unsigned int algorithm); + + /** + * \~japanese + * @brief 検出オブジェクトを破棄します。 + * @param pose_estimator 検出オブジェクトポインタ + * + * \~english + * @brief Destroys the estimator instance. + * @param pose_estimator An estimator instance pointer + */ + void AILIA_API ailiaDestroyPoseEstimator(struct AILIAPoseEstimator *pose_estimator); + + /** + * \~japanese + * @brief 検出閾値を設定します。 + * @param pose_estimator 検出オブジェクトポインタ + * @param threshold 検出閾値 0.0以上1.0以下の値で、値が小さいほど検出しやすくなります。 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Set the detection threshold. + * @param pose_estimator An estimator instance pointer + * @param threshold The detection threshold (for example, 0.1f) (The smaller it is, the easier the detection will be and the more detected objects found.) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPoseEstimatorSetThreshold(struct AILIAPoseEstimator *pose_estimator, float threshold); + + /** + * \~japanese + * @brief 骨格検出・顔特徴点検出を行います。 + * @param pose_estimator 検出オブジェクトポインタ + * @param src 画像データ(32bpp) + * @param src_stride 1ラインのバイト数 + * @param src_width 画像幅 + * @param src_height 画像高さ + * @param src_format 画像形式 (AILIA_IMAGE_FORMAT_*) + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Performs human pose estimation and human face landmarks extraction. + * @param pose_estimator An estimator instance pointer + * @param src Image data (32 bpp) + * @param src_stride The number of bytes in 1 line + * @param src_width Image width + * @param src_height Image height + * @param src_format Image format (AILIA_IMAGE_FORMAT_*) + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPoseEstimatorCompute(struct AILIAPoseEstimator *pose_estimator, const void *src, unsigned int src_stride, unsigned int src_width, unsigned int src_height, unsigned int src_format); + + /** + * \~japanese + * @brief 検出結果の数を取得します。 + * @param pose_estimator 検出オブジェクトポインタ + * @param obj_count オブジェクト数 顔特徴点の場合は1または0となります。 + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the number of detection results. + * @param pose_estimator An estimator instance pointer + * @param obj_count The number of objects. Set to 1 or 0 for human face landmarks. + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPoseEstimatorGetObjectCount(struct AILIAPoseEstimator *pose_estimator, unsigned int *obj_count); + + /** + * \~japanese + * @brief 骨格検出結果を取得します。 + * @param pose_estimator 検出オブジェクトポインタ + * @param obj オブジェクト情報 + * @param obj_idx オブジェクトインデックス + * @param version AILIA_POSE_ESTIMATOR_OBJECT_POSE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the results of the human pose estimation. + * @param pose_estimator An estimator instance pointer + * @param obj Object information + * @param obj_idx Object index + * @param version AILIA_POSE_ESTIMATOR_OBJECT_POSE_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPoseEstimatorGetObjectPose(struct AILIAPoseEstimator *pose_estimator, AILIAPoseEstimatorObjectPose* obj, unsigned int obj_idx, unsigned int version); + + /** + * \~japanese + * @brief 顔特徴点検出結果を取得します。 + * @param pose_estimator 検出オブジェクトポインタ + * @param obj オブジェクト情報 + * @param obj_idx オブジェクトインデックス 必ず 0 を指定してください。 + * @param version AILIA_POSE_ESTIMATOR_OBJECT_FACE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the results of the human face landmarks extraction. + * @param pose_estimator An estimator instance pointer + * @param obj Object information + * @param obj_idx Object index. Ensure that 0 is specified. + * @param version AILIA_POSE_ESTIMATOR_OBJECT_FACE_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPoseEstimatorGetObjectFace(struct AILIAPoseEstimator *pose_estimator, AILIAPoseEstimatorObjectFace* obj, unsigned int obj_idx, unsigned int version); + + /** + * \~japanese + * @brief UpPose 認識結果を取得します。 + * @param pose_estimator 検出オブジェクトポインタ + * @param obj オブジェクト情報 + * @param obj_idx オブジェクトインデックス + * @param version AILIA_POSE_ESTIMATOR_OBJECT_POSE_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the results of the human up pose estimation. + * @param pose_estimator An estimator instance pointer + * @param obj Object information + * @param obj_idx Object index + * @param version AILIA_POSE_ESTIMATOR_OBJECT_UPPOSE_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPoseEstimatorGetObjectUpPose(struct AILIAPoseEstimator *pose_estimator, AILIAPoseEstimatorObjectUpPose* obj, unsigned int obj_idx, unsigned int version); + + /** + * \~japanese + * @brief Hand 認識結果を取得します。 + * @param pose_estimator 検出オブジェクトポインタ + * @param obj オブジェクト情報 + * @param obj_idx オブジェクトインデックス 必ず 0 を指定してください。 + * @param version AILIA_POSE_ESTIMATOR_OBJECT_HAND_VERSION + * @return + * 成功した場合は \ref AILIA_STATUS_SUCCESS 、そうでなければエラーコードを返す。 + * + * \~english + * @brief Gets the results of the human hand estimation. + * @param pose_estimator An estimator instance pointer + * @param obj Object information + * @param obj_idx Object index. Ensure that 0 is specified. + * @param version AILIA_POSE_ESTIMATOR_OBJECT_HAND_VERSION + * @return + * If this function is successful, it returns \ref AILIA_STATUS_SUCCESS , or an error code otherwise. + */ + int AILIA_API ailiaPoseEstimatorGetObjectHand(struct AILIAPoseEstimator *pose_estimator, AILIAPoseEstimatorObjectHand* obj, unsigned int obj_idx, unsigned int version); + +#ifdef __cplusplus +} +#endif +#endif /* !defined(INCLUDED_AILIA_POSE_ESTIMATOR) */ diff --git a/include/ailia_yolox/ailia_yolox.hpp b/include/ailia_yolox/ailia_yolox.hpp new file mode 100644 index 0000000..3121035 --- /dev/null +++ b/include/ailia_yolox/ailia_yolox.hpp @@ -0,0 +1,66 @@ +#ifndef AILIA_YOLOX__AILIA_YOLOX_HPP_ +#define AILIA_YOLOX__AILIA_YOLOX_HPP_ + +#include + +#include +#include +#include + +// #include +#include "ailia.h" +#include "ailia_detector.h" + + +#define IMAGE_CHANNEL 3 + +namespace ailia_yolox +{ +struct Object +{ + int32_t x_offset; + int32_t y_offset; + int32_t height; + int32_t width; + float score; + int32_t type; +}; + +using ObjectArray = std::vector; +using ObjectArrays = std::vector; + +class AiliaYoloX +{ +public: + AiliaYoloX( + const std::string & model_path, + const std::string & weight_path, + const std::string & precision, + const unsigned int labelNum, + const int algorithm, + const int env_id = AILIA_ENVIRONMENT_ID_AUTO); + ~AiliaYoloX(); + + std::string GetAiliaVersion(); + std::string GetEnvironmentName(); + std::vector GetAllEnvironmentNames(); + + bool doInference(const std::vector & images, ObjectArrays & objects); + + bool HasError(); + std::string GetErrorDescription(); + +private: + AILIANetwork *ailia; + AILIADetector *detector; + std::string error_msg; + bool error_; + const int algorithm_; + + void Preprocess(const cv::Mat& image, cv::Mat& out_image, float& out_scale); + bool CheckError(const int status, const std::string& funcName); +}; + +} // namespace ailia_yolox + +#endif // AILIA_YOLOX__AILIA_YOLOX_HPP_ diff --git a/include/ailia_yolox/ailia_yolox_node.hpp b/include/ailia_yolox/ailia_yolox_node.hpp new file mode 100644 index 0000000..19e65ee --- /dev/null +++ b/include/ailia_yolox/ailia_yolox_node.hpp @@ -0,0 +1,51 @@ + +#ifndef AILIA_YOLOX__AILIA_YOLOX_NODE_HPP_ +#define AILIA_YOLOX__AILIA_YOLOX_NODE_HPP_ + +#include +#include +#include +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include +#include + +#include + +namespace ailia_yolox +{ +class AiliaYoloXNode : public rclcpp::Node +{ +public: + explicit AiliaYoloXNode(const rclcpp::NodeOptions & node_options); + +private: + void onConnect(); + void onImage(const sensor_msgs::msg::Image::ConstSharedPtr msg); + bool readLabelFile(const std::string & label_path); + + image_transport::Publisher image_pub_; + rclcpp::Publisher::SharedPtr + objects_pub_; + + image_transport::Subscriber image_sub_; + + rclcpp::TimerBase::SharedPtr timer_; + + std::map label_map_; + std::unique_ptr ailia_yolox_; +}; + +} // namespace ailia_yolox + +#endif // AILIA_YOLOX__AILIA_YOLOX_NODE_HPP_ diff --git a/include/tensorrt_yolox/tensorrt_yolox.hpp b/include/tensorrt_yolox/tensorrt_yolox.hpp deleted file mode 100644 index 04db80c..0000000 --- a/include/tensorrt_yolox/tensorrt_yolox.hpp +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2022 Tier IV, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef TENSORRT_YOLOX__TENSORRT_YOLOX_HPP_ -#define TENSORRT_YOLOX__TENSORRT_YOLOX_HPP_ - -#include -#include -#include - -#include - -#include -#include -#include - -namespace tensorrt_yolox -{ -using cuda_utils::CudaUniquePtr; -using cuda_utils::makeCudaStream; -using cuda_utils::StreamUniquePtr; - -struct Object -{ - int32_t x_offset; - int32_t y_offset; - int32_t height; - int32_t width; - float score; - int32_t type; -}; - -using ObjectArray = std::vector; -using ObjectArrays = std::vector; - -class TrtYoloX -{ -public: - TrtYoloX( - const std::string & model_path, const std::string & precision, - const std::string & cache_dir = "", - const tensorrt_common::BatchConfig & batch_config = {1, 1, 1}, - const size_t max_workspace_size = (1 << 30)); - - bool doInference(const std::vector & images, ObjectArrays & objects); - -private: - void preprocess(const std::vector & images); - std::unique_ptr trt_common_; - - std::vector input_h_; - CudaUniquePtr input_d_; - CudaUniquePtr out_num_detections_d_; - CudaUniquePtr out_boxes_d_; - CudaUniquePtr out_scores_d_; - CudaUniquePtr out_classes_d_; - - StreamUniquePtr stream_{makeCudaStream()}; - - int32_t max_detections_; - std::vector scales_; -}; - -} // namespace tensorrt_yolox - -#endif // TENSORRT_YOLOX__TENSORRT_YOLOX_HPP_ diff --git a/include/tensorrt_yolox/tensorrt_yolox_node.hpp b/include/tensorrt_yolox/tensorrt_yolox_node.hpp deleted file mode 100644 index 3cea163..0000000 --- a/include/tensorrt_yolox/tensorrt_yolox_node.hpp +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2022 Tier IV, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#ifndef TENSORRT_YOLOX__TENSORRT_YOLOX_NODE_HPP_ -#define TENSORRT_YOLOX__TENSORRT_YOLOX_NODE_HPP_ - -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include -#include -#include -#include -#include -#include - -namespace tensorrt_yolox -{ -using LabelMap = std::map; - -class TrtYoloXNode : public rclcpp::Node -{ -public: - explicit TrtYoloXNode(const rclcpp::NodeOptions & node_options); - -private: - void onConnect(); - void onImage(const sensor_msgs::msg::Image::ConstSharedPtr msg); - bool readLabelFile(const std::string & label_path); - - image_transport::Publisher image_pub_; - rclcpp::Publisher::SharedPtr - objects_pub_; - - image_transport::Subscriber image_sub_; - - rclcpp::TimerBase::SharedPtr timer_; - - LabelMap label_map_; - std::unique_ptr trt_yolox_; -}; - -} // namespace tensorrt_yolox - -#endif // TENSORRT_YOLOX__TENSORRT_YOLOX_NODE_HPP_ diff --git a/package.xml b/package.xml index b82bf8a..5afbb33 100644 --- a/package.xml +++ b/package.xml @@ -1,6 +1,6 @@ - tensorrt_yolox + ailia_yolox 0.0.1 tensorrt library implementation for yolox @@ -10,21 +10,14 @@ Apache License 2.0 ament_cmake_auto - cudnn_cmake_module - tensorrt_cmake_module - - cudnn_cmake_module - tensorrt_cmake_module autoware_auto_perception_msgs - cuda_utils cv_bridge image_transport libopencv-dev rclcpp rclcpp_components sensor_msgs - tensorrt_common tier4_perception_msgs ament_lint_auto diff --git a/src/ailia_yolox.cpp b/src/ailia_yolox.cpp new file mode 100644 index 0000000..6f46d94 --- /dev/null +++ b/src/ailia_yolox.cpp @@ -0,0 +1,225 @@ +#include +#include + +#include +#include +#include +#include +#include +#include + +#define IMAGE_WIDTH 416 // Must be a multiple of 32 +#define IMAGE_HEIGHT 416 +#define THRESHOLD 0.05f +#define IOU 0.45f + +#define AILIA_ENVIRONMENT_TYPE_SCAI (8) + +namespace ailia_yolox +{ +AiliaYoloX::AiliaYoloX( + const std::string &model_path, + const std::string &weight_path, + const std::string &precision, + const unsigned int labelNum, + const int algorithm, + const int env_id) : algorithm_(algorithm) +{ + error_ = false; + unsigned int env_count; + int status; + status = ailiaGetEnvironmentCount(&env_count); + if(CheckError(status, "ailiaGetEnvironmentCount")){ + return; + } + int fp = AILIA_ENVIRONMENT_PROPERTY_NORMAL; + if(precision == "fp16"){ + fp = AILIA_ENVIRONMENT_PROPERTY_FP16; + } + int env_id_ = env_id; + if(env_id_ == AILIA_ENVIRONMENT_ID_AUTO){ + for(unsigned int i = 0; i < env_count; i++){ + AILIAEnvironment *env; + ailiaGetEnvironment(&env, i, AILIA_ENVIRONMENT_VERSION); + if(env->type == AILIA_ENVIRONMENT_TYPE_SCAI && env->props == fp){ + env_id_ = env->id; + break; + } + } + } + if(env_id_ == AILIA_ENVIRONMENT_ID_AUTO){ + for(unsigned int i = 0; i < env_count; i++){ + AILIAEnvironment *env; + ailiaGetEnvironment(&env, i, AILIA_ENVIRONMENT_VERSION); + if(env->type == AILIA_ENVIRONMENT_TYPE_GPU && env->props == fp){ + env_id_ = env->id; + break; + } + } + } + + status = ailiaCreate(&ailia, env_id_, AILIA_MULTITHREAD_AUTO); + if(CheckError(status, "ailiaCreate")){ + return; + } + + status = ailiaOpenStreamFile(ailia, model_path.c_str()); + if(CheckError(status, "ailiaOpenStreamFile")){ + error_msg += "\ninput path: " + model_path + "\n"; + ailiaDestroy(ailia); + return; + } + + status = ailiaOpenWeightFile(ailia, weight_path.c_str()); + if(CheckError(status, "ailiaOpenWeightFile")){ + error_msg += "\ninput path: " + weight_path + "\n"; + ailiaDestroy(ailia); + return; + } + + const unsigned int flags = AILIA_DETECTOR_FLAG_NORMAL; + switch(algorithm_){ + case AILIA_DETECTOR_ALGORITHM_YOLOX: + status = ailiaCreateDetector(&detector, ailia, + AILIA_NETWORK_IMAGE_FORMAT_BGR, + AILIA_NETWORK_IMAGE_CHANNEL_FIRST, + AILIA_NETWORK_IMAGE_RANGE_UNSIGNED_INT8, + AILIA_DETECTOR_ALGORITHM_YOLOX, + labelNum, flags); + break; + case AILIA_DETECTOR_ALGORITHM_YOLOV4: + status = ailiaCreateDetector(&detector, ailia, + AILIA_NETWORK_IMAGE_FORMAT_RGB, + AILIA_NETWORK_IMAGE_CHANNEL_FIRST, + AILIA_NETWORK_IMAGE_RANGE_UNSIGNED_FP32, + AILIA_DETECTOR_ALGORITHM_YOLOV4, + labelNum, flags); + } + if(CheckError(status, "ailiaCreateDetector")){ + ailiaDestroy(ailia); + return; + } + + if(algorithm_ == AILIA_DETECTOR_ALGORITHM_YOLOX){ + status = ailiaDetectorSetInputShape(detector, IMAGE_WIDTH, IMAGE_HEIGHT); + if(CheckError(status, "ailiaDetectorSetInputShape")){ + error_msg += "\nInputShape(w=" + std::to_string(IMAGE_WIDTH) +", h=" + std::to_string(IMAGE_HEIGHT) + ")\n"; + ailiaDestroyDetector(detector); + ailiaDestroy(ailia); + return; + } + } +} + +AiliaYoloX::~AiliaYoloX(){ + ailiaDestroyDetector(detector); + ailiaDestroy(ailia); +} + +std::string AiliaYoloX::GetEnvironmentName(){ + AILIAEnvironment *env = nullptr; + int status = ailiaGetSelectedEnvironment(ailia, &env, AILIA_ENVIRONMENT_VERSION); + if(CheckError(status, "ailiaGetSelectedEnvironment")){ + return ""; + } + return std::string(env->name); +} + +std::vector AiliaYoloX::GetAllEnvironmentNames(){ + std::vector env_names; + unsigned int env_count; + int status; + status = ailiaGetEnvironmentCount(&env_count); + if(CheckError(status, "ailiaGetEnvironmentCount")){ + return env_names; + } + for(unsigned int i = 0; i < env_count; i++){ + AILIAEnvironment *env; + ailiaGetEnvironment(&env, i, AILIA_ENVIRONMENT_VERSION); + env_names.push_back(std::string(env->name)); + } + return env_names; +} + +std::string AiliaYoloX::GetAiliaVersion(){ + return std::string(ailiaGetVersion()); +} + +void AiliaYoloX::Preprocess(const cv::Mat& image, cv::Mat& out_image, float& out_scale) +{ + out_scale = std::min(float(IMAGE_WIDTH) / image.cols, float(IMAGE_HEIGHT) / image.rows); + const auto scale_size = cv::Size(image.cols * out_scale, image.rows * out_scale); + cv::resize(image, out_image, scale_size, 0, 0, cv::INTER_CUBIC); + const auto bottom = IMAGE_HEIGHT - out_image.rows; + const auto right = IMAGE_WIDTH - out_image.cols; + cv::copyMakeBorder( + out_image, out_image, 0, bottom, 0, right, + cv::BORDER_CONSTANT, {0, 0, 0}); +} + +bool AiliaYoloX::doInference(const std::vector & images, ObjectArrays & objects) +{ + int status; + objects.clear(); + for(auto& inimg : images){ + float scale = 1; + cv::Mat img; + + Preprocess(inimg, img, scale); + + status = ailiaDetectorCompute(detector, img.data, + img.cols * 3, img.cols, img.rows, + AILIA_IMAGE_FORMAT_BGR, THRESHOLD, IOU); + + if(CheckError(status, "ailiaDetectorCompute")){ + return false; + } + + uint obj_count; + status = ailiaDetectorGetObjectCount(detector, &obj_count); + if(CheckError(status, "ailiaDetectorGetObjectCount")){ + return false; + } + + ObjectArray object_array(obj_count); + for (uint j = 0; j < obj_count; ++j) { + AILIADetectorObject obj; + status = ailiaDetectorGetObject(detector, &obj, j, AILIA_DETECTOR_OBJECT_VERSION); + if(CheckError(status, "ailiaDetectorGetObject")){ + return false; + } + + Object object{}; + object.x_offset = std::clamp(0, int32_t(IMAGE_WIDTH * obj.x / scale), inimg.cols); + object.y_offset = std::clamp(0, int32_t(IMAGE_HEIGHT * obj.y / scale), inimg.rows); + object.width = int32_t(std::max(0.0F, IMAGE_WIDTH * obj.w / scale)); + object.height = int32_t(std::max(0.0F, IMAGE_HEIGHT * obj.h / scale)); + object.score = obj.prob; + object.type = obj.category; + object_array.emplace_back(object); + } + objects.emplace_back(object_array); + } + + return true; +} + +bool AiliaYoloX::CheckError(const int status, const std::string& funcName){ + if(status != AILIA_STATUS_SUCCESS){ + error_msg = funcName + " failed. " + ailiaGetStatusString(status) + "(" + std::to_string(status) + ")\n"; + error_msg += ailiaGetErrorDetail(ailia); + error_ = true; + return true; + } + return false; +} + +bool AiliaYoloX::HasError(){ + return error_; +} + +std::string AiliaYoloX::GetErrorDescription(){ + return error_msg; +} + +} // namespace tensorrt_yolox diff --git a/src/tensorrt_yolox_node.cpp b/src/ailia_yolox_node.cpp similarity index 62% rename from src/tensorrt_yolox_node.cpp rename to src/ailia_yolox_node.cpp index d1fa2e3..aecdc3d 100644 --- a/src/tensorrt_yolox_node.cpp +++ b/src/ailia_yolox_node.cpp @@ -1,18 +1,4 @@ -// Copyright 2022 Tier IV, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include +#include #include @@ -21,27 +7,60 @@ #include #include #include +#include -namespace tensorrt_yolox +namespace ailia_yolox { -TrtYoloXNode::TrtYoloXNode(const rclcpp::NodeOptions & node_options) -: Node("tensorrt_yolox", node_options) +AiliaYoloXNode::AiliaYoloXNode(const rclcpp::NodeOptions & node_options) +: Node("ailia_yolox", node_options) { using std::placeholders::_1; using namespace std::chrono_literals; + const static std::map algo_list{ + {"yolox", AILIA_DETECTOR_ALGORITHM_YOLOX}, + {"yolov4", AILIA_DETECTOR_ALGORITHM_YOLOV4}, + }; std::string model_path = declare_parameter("model_path", ""); + std::string weight_path = declare_parameter("weight_path", ""); std::string label_path = declare_parameter("label_path", ""); std::string precision = declare_parameter("precision", "fp32"); + std::string algorithm = declare_parameter("algorithm", ""); + + if(algo_list.find(algorithm) == algo_list.end()){ + auto iter = algo_list.begin(); + std::string keys = iter->first; + iter++; + for (; iter != algo_list.end(); iter++) { + keys += ", " + iter->first; + } + RCLCPP_ERROR(this->get_logger(), "Undefined algorithm \"%s\", Please select from [%s]", algorithm.c_str(), keys.c_str()); + rclcpp::shutdown(); + return; + } + const int algorithm_ = algo_list.at(algorithm); + + RCLCPP_INFO(this->get_logger(), "model_path: %s", model_path.c_str()); + RCLCPP_INFO(this->get_logger(), "weight_path: %s", weight_path.c_str()); + RCLCPP_INFO(this->get_logger(), "label_path: %s", label_path.c_str()); + RCLCPP_INFO(this->get_logger(), "precision: %s", precision.c_str()); + RCLCPP_INFO(this->get_logger(), "algorithm: %s", algorithm.c_str()); if (!readLabelFile(label_path)) { RCLCPP_ERROR(this->get_logger(), "Could not find label file"); rclcpp::shutdown(); } - trt_yolox_ = std::make_unique(model_path, precision); + + ailia_yolox_ = std::make_unique(model_path, weight_path, precision, label_map_.size(), algorithm_, AILIA_ENVIRONMENT_ID_AUTO); + RCLCPP_INFO(this->get_logger(), "Ailia version: %s", ailia_yolox_->GetAiliaVersion().c_str()); + if(ailia_yolox_->HasError()){ + RCLCPP_ERROR(this->get_logger(), "Ailia initialize failed."); + RCLCPP_ERROR(this->get_logger(), "%s", ailia_yolox_->GetErrorDescription().c_str()); + } + RCLCPP_INFO(this->get_logger(), "%s", ailia_yolox_->GetEnvironmentName().c_str()); timer_ = rclcpp::create_timer( - this, get_clock(), 100ms, std::bind(&TrtYoloXNode::onConnect, this)); + this, get_clock(), 1000ms, std::bind(&AiliaYoloXNode::onConnect, this)); objects_pub_ = this->create_publisher( @@ -49,7 +68,7 @@ TrtYoloXNode::TrtYoloXNode(const rclcpp::NodeOptions & node_options) image_pub_ = image_transport::create_publisher(this, "~/out/image"); } -void TrtYoloXNode::onConnect() +void AiliaYoloXNode::onConnect() { using std::placeholders::_1; if (objects_pub_->get_subscription_count() == 0 && @@ -59,13 +78,13 @@ void TrtYoloXNode::onConnect() image_sub_.shutdown(); } else if (!image_sub_) { image_sub_ = image_transport::create_subscription( - this, "~/in/image", std::bind(&TrtYoloXNode::onImage, this, _1), "raw", + this, "~/in/image", std::bind(&AiliaYoloXNode::onImage, this, _1), "raw", rmw_qos_profile_sensor_data ); } } -void TrtYoloXNode::onImage(const sensor_msgs::msg::Image::ConstSharedPtr msg) +void AiliaYoloXNode::onImage(const sensor_msgs::msg::Image::ConstSharedPtr msg) { using Label = autoware_auto_perception_msgs::msg::ObjectClassification; @@ -81,9 +100,10 @@ void TrtYoloXNode::onImage(const sensor_msgs::msg::Image::ConstSharedPtr msg) const auto width = in_image_ptr->image.cols; const auto height = in_image_ptr->image.rows; - tensorrt_yolox::ObjectArrays objects; - if (!trt_yolox_->doInference({in_image_ptr->image}, objects)) { + ailia_yolox::ObjectArrays objects; + if (!ailia_yolox_->doInference({in_image_ptr->image}, objects)) { RCLCPP_WARN(this->get_logger(), "Fail to inference"); + RCLCPP_WARN(this->get_logger(), "%s", ailia_yolox_->GetErrorDescription().c_str()); return; } for (const auto & yolox_object : objects.at(0)) { @@ -126,7 +146,7 @@ void TrtYoloXNode::onImage(const sensor_msgs::msg::Image::ConstSharedPtr msg) objects_pub_->publish(out_objects); } -bool TrtYoloXNode::readLabelFile(const std::string & label_path) +bool AiliaYoloXNode::readLabelFile(const std::string & label_path) { std::ifstream label_file(label_path); if (!label_file.is_open()) { @@ -142,7 +162,7 @@ bool TrtYoloXNode::readLabelFile(const std::string & label_path) return true; } -} // namespace tensorrt_yolox +} // namespace ailia_yolox #include "rclcpp_components/register_node_macro.hpp" -RCLCPP_COMPONENTS_REGISTER_NODE(tensorrt_yolox::TrtYoloXNode) +RCLCPP_COMPONENTS_REGISTER_NODE(ailia_yolox::AiliaYoloXNode) diff --git a/src/tensorrt_yolox.cpp b/src/tensorrt_yolox.cpp deleted file mode 100644 index ade8838..0000000 --- a/src/tensorrt_yolox.cpp +++ /dev/null @@ -1,151 +0,0 @@ -// Copyright 2022 Tier IV, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include - -#include -#include -#include -#include -#include - -namespace tensorrt_yolox -{ -TrtYoloX::TrtYoloX( - const std::string & model_path, const std::string & precision, - [[maybe_unused]] const std::string & cache_dir, - const tensorrt_common::BatchConfig & batch_config, const size_t max_workspace_size) -{ - trt_common_ = std::make_unique( - model_path, precision, nullptr, batch_config, max_workspace_size); - trt_common_->setup(); - - if (!trt_common_->isInitialized()) { - return; - } - - // GPU memory allocation - const auto input_dims = trt_common_->getBindingDimensions(0); - const auto input_size = std::accumulate( - input_dims.d + 1, input_dims.d + input_dims.nbDims, 1, std::multiplies()); - const auto out_scores_dims = trt_common_->getBindingDimensions(3); - max_detections_ = out_scores_dims.d[1]; - input_d_ = cuda_utils::make_unique(batch_config[2] * input_size); - out_num_detections_d_ = cuda_utils::make_unique(batch_config[2]); - out_boxes_d_ = cuda_utils::make_unique(batch_config[2] * max_detections_ * 4); - out_scores_d_ = cuda_utils::make_unique(batch_config[2] * max_detections_); - out_classes_d_ = cuda_utils::make_unique(batch_config[2] * max_detections_); -} - -void TrtYoloX::preprocess(const std::vector & images) -{ - const auto batch_size = images.size(); - auto input_dims = trt_common_->getBindingDimensions(0); - input_dims.d[0] = batch_size; - trt_common_->setBindingDimensions(0, input_dims); - const float input_height = static_cast(input_dims.d[2]); - const float input_width = static_cast(input_dims.d[3]); - std::vector dst_images; - scales_.clear(); - for (const auto & image : images) { - cv::Mat dst_image; - const float scale = std::min(input_width / image.cols, input_height / image.rows); - scales_.emplace_back(scale); - const auto scale_size = cv::Size(image.cols * scale, image.rows * scale); - cv::resize(image, dst_image, scale_size, 0, 0, cv::INTER_CUBIC); - const auto bottom = input_height - dst_image.rows; - const auto right = input_width - dst_image.cols; - copyMakeBorder( - dst_image, dst_image, 0, bottom, 0, right, - cv::BORDER_CONSTANT, {114, 114, 114}); - dst_images.emplace_back(dst_image); - } - const auto chw_images = cv::dnn::blobFromImages( - dst_images, 1.0, cv::Size(), cv::Scalar(), false, false, CV_32F); - - const auto data_length = chw_images.total(); - input_h_.reserve(data_length); - const auto flat = chw_images.reshape(1, data_length); - input_h_ = chw_images.isContinuous() ? flat : flat.clone(); -} - -bool TrtYoloX::doInference(const std::vector & images, ObjectArrays & objects) -{ - if (!trt_common_->isInitialized()) { - return false; - } - - preprocess(images); - - CHECK_CUDA_ERROR( - cudaMemcpy( - input_d_.get(), input_h_.data(), input_h_.size() * sizeof(float), cudaMemcpyHostToDevice) - ); - std::vector buffers = { - input_d_.get(), out_num_detections_d_.get(), out_boxes_d_.get(), - out_scores_d_.get(), out_classes_d_.get()}; - - trt_common_->enqueueV2(buffers.data(), *stream_, nullptr); - - const auto batch_size = images.size(); - auto out_num_detections = std::make_unique(batch_size); - auto out_boxes = std::make_unique(4 * batch_size * max_detections_); - auto out_scores = std::make_unique(batch_size * max_detections_); - auto out_classes = std::make_unique(batch_size * max_detections_); - - CHECK_CUDA_ERROR( - cudaMemcpyAsync( - out_num_detections.get(), out_num_detections_d_.get(), - sizeof(int32_t) * batch_size, cudaMemcpyDeviceToHost, - *stream_)); - CHECK_CUDA_ERROR( - cudaMemcpyAsync( - out_boxes.get(), out_boxes_d_.get(), - sizeof(float) * 4 * batch_size * max_detections_, cudaMemcpyDeviceToHost, - *stream_)); - CHECK_CUDA_ERROR( - cudaMemcpyAsync( - out_scores.get(), out_scores_d_.get(), - sizeof(float) * batch_size * max_detections_, cudaMemcpyDeviceToHost, - *stream_)); - CHECK_CUDA_ERROR( - cudaMemcpyAsync( - out_classes.get(), out_classes_d_.get(), - sizeof(int32_t) * batch_size * max_detections_, cudaMemcpyDeviceToHost, - *stream_)); - cudaStreamSynchronize(*stream_); - objects.clear(); - for (size_t i = 0; i < batch_size; ++i) { - const size_t num_detection = static_cast(out_num_detections[i]); - ObjectArray object_array(num_detection); - for (size_t j = 0; j < num_detection; ++j) { - Object object{}; - const auto x1 = out_boxes[i * max_detections_ * 4 + j * 4] / scales_[i]; - const auto y1 = out_boxes[i * max_detections_ * 4 + j * 4 + 1] / scales_[i]; - const auto x2 = out_boxes[i * max_detections_ * 4 + j * 4 + 2] / scales_[i]; - const auto y2 = out_boxes[i * max_detections_ * 4 + j * 4 + 3] / scales_[i]; - object.x_offset = std::clamp(0, static_cast(x1), images[i].cols); - object.y_offset = std::clamp(0, static_cast(y1), images[i].rows); - object.width = static_cast(std::max(0.0F, x2 - x1)); - object.height = static_cast(std::max(0.0F, y2 - y1)); - object.score = out_scores[i * max_detections_ + j]; - object.type = out_classes[i * max_detections_ + j]; - object_array.emplace_back(object); - } - objects.emplace_back(object_array); - } - return true; -} - -} // namespace tensorrt_yolox diff --git a/src/yolox_single_image_inference_node.cpp b/src/yolox_single_image_inference_node.cpp deleted file mode 100644 index 6bee2f5..0000000 --- a/src/yolox_single_image_inference_node.cpp +++ /dev/null @@ -1,73 +0,0 @@ -// Copyright 2022 Tier IV, Inc. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -#include -#include - -#if(defined(_MSC_VER) or (defined(__GNUC__) and (7 <= __GNUC_MAJOR__))) -#include -namespace fs = ::std::filesystem; -#else -#include -namespace fs = ::std::experimental::filesystem; -#endif - -#include -#include - -namespace tensorrt_yolox -{ -class YoloXSingleImageInferenceNode : public rclcpp::Node -{ -public: - explicit YoloXSingleImageInferenceNode(const rclcpp::NodeOptions & node_options) - : Node("yolox_single_image_inference", node_options) - { - const auto image_path = declare_parameter("image_path", ""); - const auto model_path = declare_parameter("model_path", ""); - const auto precision = declare_parameter("precision", "fp32"); - const auto save_image = declare_parameter("save_image", false); - auto p = fs::path(image_path); - const auto ext = p.extension().string(); - p.replace_extension(""); - const auto output_image_path = declare_parameter( - "output_image_path", - p.string() + "_detect" + ext - ); - - auto trt_yolox = std::make_unique(model_path, precision); - auto image = cv::imread(image_path); - tensorrt_yolox::ObjectArrays objects; - trt_yolox->doInference({image}, objects); - for (const auto & object : objects[0]) { - const auto left = object.x_offset; - const auto top = object.y_offset; - const auto right = std::clamp(left + object.width, 0, image.cols); - const auto bottom = std::clamp(top + object.height, 0, image.rows); - cv::rectangle( - image, cv::Point(left, top), cv::Point(right, bottom), cv::Scalar(0, 0, 255), 3, 8, 0); - } - if (!save_image) { - cv::imshow("inference image", image); - cv::waitKey(0); - rclcpp::shutdown(); - } - cv::imwrite(output_image_path, image); - rclcpp::shutdown(); - } -}; -} // namespace tensorrt_yolox - -#include "rclcpp_components/register_node_macro.hpp" -RCLCPP_COMPONENTS_REGISTER_NODE(tensorrt_yolox::YoloXSingleImageInferenceNode)