Jump to content

Использования C++ API для камеры


photo

Recommended Posts

Posted

Добрый день, хотел бы задать всем на форуме такой вопрос. Можно ли использовать API для того, чтобы внешней программой взять видеопоток для своих целей?

Posted

Здравствуйте.

Видеопотока внутри движка нет. Как вариант - грэбать текстуру в каждом кадре и потом конвертировать в изображение, а дальше делать с массивом пикселей что угодно. Например:

Spoiler

void VideoFrameCapturer::grabFrame()
{
    auto window = Unigine::WindowManager::getMainWindow();
    Unigine::TexturePtr temporary_texture =
        Unigine::Render::getTemporaryTexture2D(
            window->getClientRenderSize().x, window->getClientRenderSize().y,
            Unigine::Texture::FORMAT_RGBA8);

    temporary_texture->copy2D();

    frames.emplace_back(AsyncTransfer::TextureToImage(temporary_texture), rtc::TimeMicros());

    Unigine::Render::releaseTemporaryTexture(temporary_texture);
}

В sendFrame можно писать свою кастомную логику:

Spoiler

void VideoFrameCapturer::sendFrame()
{
    while (frames.size() > 0 && frames.first().first->completed)
    {
        auto v = frames.takeFirst();
        auto image = v.first->image;

    }
}

На конец кадра подписываемся вот так:

Spoiler

Unigine::WindowManager::getMainWindow()->getEventFuncEndRender().connect(event_connections, this, &VideoFrameCapturer::grabFrame);
Unigine::WindowManager::getMainWindow()->getEventFuncSwap().connect(event_connections, this, &VideoFrameCapturer::sendFrame);

А вот сам конвертер текстуры в изображение:

Spoiler

struct ImageContainer
{
    std::atomic_bool completed = false;
    Unigine::ImagePtr image;
};

UNIGINE_INLINE std::shared_ptr<ImageContainer> TextureToImage(Unigine::TexturePtr texure)
{
    if (!texure)
        return nullptr;
    std::shared_ptr<ImageContainer> ret = std::make_shared<ImageContainer>();
    std::weak_ptr<ImageContainer> weak = ret;
    Unigine::Render::asyncTransferTextureToImage(nullptr, Unigine::MakeCallback([weak](const Unigine::ImagePtr &image)
    {
        if (std::shared_ptr<ImageContainer> spt = weak.lock())
        {
            spt->image = Unigine::Image::create();
            spt->image->swap(image);
            spt->completed = true;
        }
    }),
        texure);

    return ret;
}

 

  • Like 1
Posted
54 minutes ago, arizmenda said:

Здравствуйте.

Видеопотока внутри движка нет. Как вариант - грэбать текстуру в каждом кадре и потом конвертировать в изображение, а дальше делать с массивом пикселей что угодно. Например:

  Hide contents

void VideoFrameCapturer::grabFrame()
{
    auto window = Unigine::WindowManager::getMainWindow();
    Unigine::TexturePtr temporary_texture =
        Unigine::Render::getTemporaryTexture2D(
            window->getClientRenderSize().x, window->getClientRenderSize().y,
            Unigine::Texture::FORMAT_RGBA8);

    temporary_texture->copy2D();

    frames.emplace_back(AsyncTransfer::TextureToImage(temporary_texture), rtc::TimeMicros());

    Unigine::Render::releaseTemporaryTexture(temporary_texture);
}

В sendFrame можно писать свою кастомную логику:

  Hide contents

void VideoFrameCapturer::sendFrame()
{
    while (frames.size() > 0 && frames.first().first->completed)
    {
        auto v = frames.takeFirst();
        auto image = v.first->image;

    }
}

На конец кадра подписываемся вот так:

  Hide contents

Unigine::WindowManager::getMainWindow()->getEventFuncEndRender().connect(event_connections, this, &VideoFrameCapturer::grabFrame);
Unigine::WindowManager::getMainWindow()->getEventFuncSwap().connect(event_connections, this, &VideoFrameCapturer::sendFrame);

А вот сам конвертер текстуры в изображение:

  Hide contents

struct ImageContainer
{
    std::atomic_bool completed = false;
    Unigine::ImagePtr image;
};

UNIGINE_INLINE std::shared_ptr<ImageContainer> TextureToImage(Unigine::TexturePtr texure)
{
    if (!texure)
        return nullptr;
    std::shared_ptr<ImageContainer> ret = std::make_shared<ImageContainer>();
    std::weak_ptr<ImageContainer> weak = ret;
    Unigine::Render::asyncTransferTextureToImage(nullptr, Unigine::MakeCallback([weak](const Unigine::ImagePtr &image)
    {
        if (std::shared_ptr<ImageContainer> spt = weak.lock())
        {
            spt->image = Unigine::Image::create();
            spt->image->swap(image);
            spt->completed = true;
        }
    }),
        texure);

    return ret;
}

 

Хотел бы еще уточнить,я не очень силен в С++, поэтому хотел в Python уже обрабатывать необходимое изображение. Подскажите, в данном формате есть ли ссылка, на которую можно будет сослаться для внешнего приложения на Python?

Posted

Попробуйте изучить HttpImageResponseSample.cpp в demos\cpp_samples_demo_2.19.1\source\network. Это пример того, как png отправляется из движка в браузер.

Можно получить png таким же запросом на Python. Например вот так - get_screen_cmd.py 

 

 

×
×
  • Create New...