{ "cells": [ { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import openpifpaf\n", "openpifpaf.plugin.register()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Plugins\n", "\n", "Plugins are Python modules that extend the functionality of OpenPifPaf. Plugins are developed independently of OpenPifPaf (i.e. you don't need to clone and modify OpenPifPaf's core code).\n", "\n", "This is an overview of OpenPifPaf's main components and which are extendible with plugins:\n", "![plugin overview](images/plugins_overview.png)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Discovery\n", "\n", "Plugins are modules whose name starts with `openpifpaf_`. Some plugins are also included in `openpifpaf.plugins`. During the discovery process, every plugin's `register()` function is called. A simple plugin that does nothing, the `nothingplugin` would have this file structure:\n", "\n", "```\n", "|- openpifpaf_nothingplugin # project directory (root directory for version control)\n", " |- Readme.md\n", " |- openpifpaf_nothingplugin # Python module\n", " |- __init__.py\n", "```\n", "\n", "where the `__init__.py` file would contain an empty `register()` function:\n", "\n", "```py\n", "def register():\n", " pass\n", "```" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Registrations\n", "\n", "A plugin contains new implementations of base classes provided by OpenPifPaf. The `register()` function adds these implementations to OpenPifPaf's lists of implementations. Those lists are:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.DATAMODULES" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.DECODERS" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.BASE_TYPES" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.BASE_FACTORIES" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.HEADS" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.LOSSES" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.MODEL_MIGRATION" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.CHECKPOINT_URLS" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.PAINTERS" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The relevant base classes that must be derived from to extend the above lists are `DataModule` (in {ref}`api:datasets`), `decoder.Generator` (in {ref}`api:decoder`), `BaseNetwork` and `HeadNetwork` (both in {ref}`api:network`)." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Headmeta" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Headmeta (see {ref}`api:headmeta`) is a class that holds configuration data about a head network. It is instantiated in a DataModule (above) and used throughout OpenPifPaf to configure various other parts. For example, the `cocokp` head meta instances are: " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.plugins.coco.CocoKp().head_metas[0]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "openpifpaf.plugins.coco.CocoKp().head_metas[1]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When a new network is created, information from the head metas will be used to create the appropriate torch graph for the heads. It will use the type of the head meta (`openpifpaf.headmeta.Cif`, `openpifpaf.headmeta.Caf`, ...) and information like the number of keypoints in Cif or the number of skeleton connections in Caf to know how many feature maps to create.\n", "\n", "Similarly, the decoder will look for heads that are of type `headmeta.Cif` and `headmeta.Caf` to instantiate the CifCaf decoder.\n", "\n", "To get started, have a look how the head metas are created in `CocoKp` for new pose datasets and in `CocoDet` for new detection datasets." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.5-final" } }, "nbformat": 4, "nbformat_minor": 2 }