HSOpticalFlow/main.cpp

原结果输出

root@04feecd3dc8a:/workspace/cuda-samples-master/Samples/5_Domain_Specific/HSOpticalFlow# ./HSOpticalFlow 
HSOpticalFlow Starting...

GPU Device 0: "Ampere" with compute capability 8.6

Loading "frame10.ppm" ...
Loading "frame11.ppm" ...
Computing optical flow on GPU...
Computing optical flow on CPU...
L1 error : 0.044308

加入计算时间函数,结果输出

HSOpticalFlow Starting...

GPU Device 0: "Ampere" with compute capability 8.6

Loading "frame10.ppm" ...
Loading "frame11.ppm" ...
开始计算,预计3分钟
Computing optical flow on GPU...
GPU Processing time: 31.284836 ms
Computing optical flow on CPU...
CPU Processing time: 8843 ms
L1 error : 0.044308

完整代码:

/* Copyright (c) 2022, NVIDIA CORPORATION. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *  * Neither the name of NVIDIA CORPORATION nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

const static char *const sSDKsample = "HSOpticalFlow";

// CPU-GPU discrepancy threshold for self-test
const float THRESHOLD = 0.05f;

#include <cuda_runtime.h>

#include "common.h"
#include "flowGold.h"
#include "flowCUDA.h"

#include <helper_functions.h>
#include <chrono>
#include <cuda_runtime.h>

///
/// \brief save optical flow in format described on vision.middlebury.edu/flow
/// \param[in] name output file name
/// \param[in] w    optical flow field width
/// \param[in] h    optical flow field height
/// \param[in] s    optical flow field row stride
/// \param[in] u    horizontal displacement
/// \param[in] v    vertical displacement
///
void WriteFloFile(const char *name, int w, int h, int s, const float *u,
                  const float *v) {
  FILE *stream;
  stream = fopen(name, "wb");

  if (stream == 0) {
    printf("Could not save flow to \"%s\"\n", name);
    return;
  }

  float data = 202021.25f;
  fwrite(&data, sizeof(float), 1, stream);
  fwrite(&w, sizeof(w), 1, stream);
  fwrite(&h, sizeof(h), 1, stream);

  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      const int pos = j + i * s;
      fwrite(u + pos, sizeof(float), 1, stream);
      fwrite(v + pos, sizeof(float), 1, stream);
    }
  }

  fclose(stream);
}

///
/// \brief
/// load 4-channel unsigned byte image
/// and convert it to single channel FP32 image
/// \param[out] img_data pointer to raw image data
/// \param[out] img_w    image width
/// \param[out] img_h    image height
/// \param[out] img_s    image row stride
/// \param[in]  name     image file name
/// \param[in]  exePath  executable file path
/// \return true if image is successfully loaded or false otherwise
///
bool LoadImageAsFP32(float *&img_data, int &img_w, int &img_h, int &img_s,
                     const char *name, const char *exePath) {
  printf("Loading \"%s\" ...\n", name);
  char *name_ = sdkFindFilePath(name, exePath);

  if (!name_) {
    printf("File not found\n");
    return false;
  }

  unsigned char *data = 0;
  unsigned int w = 0, h = 0;
  bool result = sdkLoadPPM4ub(name_, &data, &w, &h);

  if (result == false) {
    printf("Invalid file format\n");
    return false;
  }

  img_w = w;
  img_h = h;
  img_s = iAlignUp(img_w);

  img_data = new float[img_s * h];

  // source is 4 channel image
  const int widthStep = 4 * img_w;

  for (int i = 0; i < img_h; ++i) {
    for (int j = 0; j < img_w; ++j) {
      img_data[j + i * img_s] = ((float)data[j * 4 + i * widthStep]) / 255.0f;
    }
  }

  return true;
}

///
/// \brief compare given flow field with gold (L1 norm)
/// \param[in] width    optical flow field width
/// \param[in] height   optical flow field height
/// \param[in] stride   optical flow field row stride
/// \param[in] h_uGold  horizontal displacement, gold
/// \param[in] h_vGold  vertical displacement, gold
/// \param[in] h_u      horizontal displacement
/// \param[in] h_v      vertical displacement
/// \return true if discrepancy is lower than a given threshold
///
bool CompareWithGold(int width, int height, int stride, const float *h_uGold,
                     const float *h_vGold, const float *h_u, const float *h_v) {
  float error = 0.0f;

  for (int i = 0; i < height; ++i) {
    for (int j = 0; j < width; ++j) {
      const int pos = j + i * stride;
      error += fabsf(h_u[pos] - h_uGold[pos]) + fabsf(h_v[pos] - h_vGold[pos]);
    }
  }

  error /= (float)(width * height);

  printf("L1 error : %.6f\n", error);

  return (error < THRESHOLD);
}

///
/// application entry point
///
int main(int argc, char **argv) {
  // welcome message
  printf("%s Starting...\n\n", sSDKsample);

  // pick GPU
  findCudaDevice(argc, (const char **)argv);

  // find images
  const char *const sourceFrameName = "frame10.ppm";
  const char *const targetFrameName = "frame11.ppm";

  // image dimensions
  int width;
  int height;
  // row access stride
  int stride;

  // flow is computed from source image to target image
  float *h_source;  // source image, host memory
  float *h_target;  // target image, host memory

  // load image from file
  if (!LoadImageAsFP32(h_source, width, height, stride, sourceFrameName,
                       argv[0])) {
    exit(EXIT_FAILURE);
  }

  if (!LoadImageAsFP32(h_target, width, height, stride, targetFrameName,
                       argv[0])) {
    exit(EXIT_FAILURE);
  }

  // allocate host memory for CPU results
  float *h_uGold = new float[stride * height];
  float *h_vGold = new float[stride * height];

  // allocate host memory for GPU results
  float *h_u = new float[stride * height];
  float *h_v = new float[stride * height];

  // smoothness
  // if image brightness is not within [0,1]
  // this paramter should be scaled appropriately
  const float alpha = 0.2f;

  // number of pyramid levels
  const int nLevels = 5;

  // number of solver iterations on each level
  const int nSolverIters = 500;

  // number of warping iterations
  const int nWarpIters = 3;
  printf("开始计算,预计3分钟\n");
  // Timing GPU computation using CUDA events
  //这里是补充的,计算时间的代码
  cudaEvent_t startGPU, stopGPU;
  cudaEventCreate(&startGPU);
  cudaEventCreate(&stopGPU);
  float millisecondsGPU = 0;

  cudaEventRecord(startGPU);
  printf("Computing optical flow on GPU...\n");
  for (int i = 0; i < 2000; i++) {
        ComputeFlowCUDA(h_source, h_target, width, height, stride, alpha, nLevels, nWarpIters, nSolverIters, h_u, h_v);
        }
  ComputeFlowCUDA(h_source, h_target, width, height, stride, alpha, nLevels, nWarpIters, nSolverIters, h_u, h_v);
  cudaEventRecord(stopGPU);
  cudaEventSynchronize(stopGPU);
  cudaEventElapsedTime(&millisecondsGPU, startGPU, stopGPU);
  
  printf("GPU Processing time: %f ms\n", millisecondsGPU/ 2000);

  // Timing CPU computation using std::chrono
  printf("Computing optical flow on CPU...\n");
  auto startCPU = std::chrono::high_resolution_clock::now();
  for (int i = 0; i < 10; i++) {
  ComputeFlowGold(h_source, h_target, width, height, stride, alpha, nLevels, nWarpIters, nSolverIters, h_uGold, h_vGold);
  }
  auto stopCPU = std::chrono::high_resolution_clock::now();
  auto durationCPU = std::chrono::duration_cast<std::chrono::milliseconds>(stopCPU - startCPU);

  printf("CPU Processing time: %ld ms\n", durationCPU.count()/10);
  // compare results (L1 norm)
  bool status =
      CompareWithGold(width, height, stride, h_uGold, h_vGold, h_u, h_v);

  WriteFloFile("FlowGPU.flo", width, height, stride, h_u, h_v);

  WriteFloFile("FlowCPU.flo", width, height, stride, h_uGold, h_vGold);

  // free resources
  delete[] h_uGold;
  delete[] h_vGold;

  delete[] h_u;
  delete[] h_v;

  delete[] h_source;
  delete[] h_target;

  // report self-test status
  exit(status ? EXIT_SUCCESS : EXIT_FAILURE);
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值