check this code "std::vector<cv::Mat> Segmentator::process(std::vector<cv::Mat> &frames)
{
    std::vector<cv::Mat> masksOut;
    masksOut.reserve(frames.size());
    int imgNum {0};

    cudaStream_t stream;
    NV_CUDA_CHECK(cudaStreamCreate(&stream));

    // Создание событий CUDA
    cudaEvent_t startEvent, stopEvent;
    NV_CUDA_CHECK(cudaEventCreate(&startEvent));
    NV_CUDA_CHECK(cudaEventCreate(&stopEvent));

    for(cv::Mat& image : frames)
    {
        //resize input image to the size required by neural net
        cv::Mat image_resized(h_, w_, CV_8UC3, input_);
        if (up_crop_ != 0)
        {
            std::int16_t cropRows = image.rows - up_crop_;
            cv::Rect crop(0, up_crop_, image.cols, cropRows);
            cv::Mat img_crop = image(crop);
            cv::resize(img_crop, image_resized, cv::Size(w_, h_));
        }
        else
        {
            cv::resize(image, image_resized, cv::Size(w_, h_));
        }

        // Запись начала события перед копированием на GPU
        NV_CUDA_CHECK(cudaEventRecord(startEvent, stream));

        //normalize image and reshape it such that it has channels-first format (required by neural net)
        NV_CUDA_CHECK(preprocessOnGpuWrapper(input_, inputCf_, h_, w_, coef_, mean_[0], mean_[1], mean_[2], std_[0], std_[1], std_[2]));

        //inference
        buffers_[0] = inputCf_;
        buffers_[1] = outputRaw_;
        context_->getBindingDimensions(0);

        context_->enqueueV2((void **)buffers_, stream, nullptr);

        //compute segmentation masks from raw neural net ouput
        NV_CUDA_CHECK(computeOutputOnGpuWrapper(outputRaw_, outputMask_, h_, w_, numClasses_, threshold_));

        // Запись окончания события после копирования с GPU на хост
        NV_CUDA_CHECK(cudaEventRecord(stopEvent, stream));
        NV_CUDA_CHECK(cudaEventSynchronize(stopEvent));
        float time = 0;
        NV_CUDA_CHECK(cudaEventElapsedTime(&time, startEvent, stopEvent));
        size_t bytes = h_ * w_ * 3 * sizeof(unsigned char);
        float bandwidth = bytes * 1e-6 / time;
        printf("Zero-copy Host to Device effective bandwidth (GB/s): %f\n", bandwidth);
        printf("Kernel + zero-copy time (ms): %f\n", time);

        //resize masks to the size of the input image
        cv::Mat masks(h_, w_, 0, outputMask_);
        if (up_crop_ != 0)
        {
            cv::Mat out, resize_mask;
            cv::Mat zero(up_crop_, image.cols, 0, 0.0);
            
            std::int16_t cropRows = image.rows - up_crop_;
            cv::resize(masks, resize_mask, cv::Size(image.cols, cropRows));
            cv::vconcat(zero, resize_mask, out);
            cv::resize(out, masks, cv::Size(image.cols, image.rows), 0, 0, cv::INTER_NEAREST);
            cv::rectangle(image, cv::Rect(0, up_crop_, image.cols, cropRows), cv::Scalar(0, 0, 255), 1, 4, 0);
        }
        else
        {
            cv::resize(masks, masks, cv::Size(image.cols, image.rows), 0, 0, cv::INTER_NEAREST);
        }
        masksOut.emplace_back(std::move(masks));
        imgNum++;
    }

    // Уничтожение событий
    NV_CUDA_CHECK(cudaEventDestroy(startEvent));
    NV_CUDA_CHECK(cudaEventDestroy(stopEvent));

    // Wait for the work in the stream to complete.
    // Release stream.
    NV_CUDA_CHECK(cudaStreamDestroy(stream));

    return masksOut;
}"