VideoReader в OpenCV устарел. Есть ли какие-либо обновления от OpenCV или любая замена? - PullRequest
0 голосов
/ 28 августа 2018

Я делаю декодирование видео, чтобы захватить кадр для некоторой постобработки видео. Я использую OpenCV CUDA, поэтому мне действительно нужно видео для чтения из OpenCV CUDA. Тем не менее, я понял:

В NVIDIA Video Codec SDK 8.2.15 говорится, что

Поддержка CUvideosource и связанных API-интерфейсов, включая cuvidCreateVideoSource, cuvidCreateVideoSourceW, cuvidDestroyVideoSource, cuvidSetVideoSourceState, cuvidGetVideoSourceState, cuvidGetSourceVideoFormat, API-интерфейс cuvidGetSource будет удален из будущего. Обратите внимание, что новые примеры приложений декодирования в SDK не используют эти API, но вместо этого используют FFmpeg.

Но чтобы использовать «createVideoReader» в OpenCV Cuda, нам нужно связать «dynlink_nvcuvid.h», который содержит

tcuvidCreateVideoSource               *cuvidCreateVideoSource;
tcuvidCreateVideoSourceW              *cuvidCreateVideoSourceW;
tcuvidDestroyVideoSource              *cuvidDestroyVideoSource;
tcuvidSetVideoSourceState             *cuvidSetVideoSourceState;
tcuvidGetVideoSourceState             *cuvidGetVideoSourceState;
tcuvidGetSourceVideoFormat            *cuvidGetSourceVideoFormat;
tcuvidGetSourceAudioFormat            *cuvidGetSourceAudioFormat;

Есть ли обновление от opencv для декодирования видео? Как мы используем FFmpeg в OpenCV для замены "dynlink_nvcuvid.h"? Я пытаюсь использовать декодирование видео NVIDIA, но я застрял при преобразовании видеокадра в GpuMat.

Я использую Ubuntu 18 Cuda 9.2 OpenCV 3.4.2

Для Cuda-части для декодирования я использовал следующий код:

FFmpegDemuxer demuxer(szInFilePath);
NvDecoder dec(cuContext, demuxer.GetWidth(), demuxer.GetHeight(), true, FFmpeg2NvCodecId(demuxer.GetVideoCodec()));
FramePresenterGL presenter(cuContext, demuxer.GetWidth(), demuxer.GetHeight());
uint8_t *dpFrame = 0;
int nPitch = 0;
int nVideoBytes = 0, nFrameReturned = 0, nFrame = 0;
uint8_t *pVideo = NULL;
uint8_t **ppFrame;
do {
    demuxer.Demux(&pVideo, &nVideoBytes);
    dec.Decode(pVideo, nVideoBytes, &ppFrame, &nFrameReturned);
    if (!nFrame && nFrameReturned)
        LOG(INFO) << dec.GetVideoInfo();

    for (int i = 0; i < nFrameReturned; i++) {
        presenter.GetDeviceFrameBuffer(&dpFrame, &nPitch);
        if (dec.GetBitDepth() == 8)
            Nv12ToBgra32((uint8_t *)ppFrame[i], dec.GetWidth(), (uint8_t *)dpFrame, nPitch, dec.GetWidth(), dec.GetHeight());
        else
            P016ToBgra32((uint8_t *)ppFrame[i], 2 * dec.GetWidth(), (uint8_t *)dpFrame, nPitch, dec.GetWidth(), dec.GetHeight());

        cv::Size sz(dec.GetWidth(),dec.GetHeight());
        cv::Mat mat1(sz,CV_8UC3, ppFrame);
        cv::imshow ("test", mat1);
        cv::waitKey(0);
    }
    nFrame += nFrameReturned;
} while (nVideoBytes);

У кого-нибудь есть опыт использования OpenCV CUDA с реальным API видеокодека? Как поместить видеокадр в GpuMat?

Обновление:

Я попытался преобразовать uint8_t, но изображение отображается неправильно, как показано ниже: enter image description here

Код, который я использовал, обновлен выше. Что я должен изменить, чтобы изображение отображалось правильно? Я пытался https://stackoverflow.com/a/51520728/7939409, но загруженный левый пустой код ниже.

cv::Mat downloadedLeft;
cv::cuda::GpuMat gpuLeft;

cudaMalloc((void **)&ppFrame, gpuLeft.rows*gpuLeft.step);
cudaMemcpyAsync(ppFrame, gpuLeft.ptr<uint8_t>(), gpuLeft.rows*gpuLeft.step, cudaMemcpyDeviceToDevice);

gpuLeft.download(downloadedLeft);
cv::imshow ("test", downloadedLeft);
cv::waitKey(1);

1 Ответ

0 голосов
/ 17 октября 2018

Я нашел простой способ чтения изображений без посторонних лиц.

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

int read_image(FILE *rfile, void *buf, int width, int height, int stride, int elem_size)
{
    char *byte_ptr = buf;
    int i;
    int ret = 1;

    if (width <= 0 || height <= 0 || elem_size <= 0)
    {
        goto fail_or_end;
    }

    for (i = 0; i < height; ++i)
    {
        if (fread(byte_ptr, elem_size, width, rfile) != (size_t)width)
        {
            goto fail_or_end;
        }

        byte_ptr += stride;
    }

    ret = 0;

fail_or_end:
    return ret;
}

кредит на открытый исходный код netflix vmaf (file_io.c). Спасибо, Netflix. После того, как я прочитал изображение, мне удалось продолжить обработку с помощью cuda.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...