sophgo / libsophon

Sophgo AI chips driver and runtime library.
Other
15 stars 12 forks source link

soc模式下使用bmcv_image_draw_lines绘制线条太慢了 #2

Open RaechelliaYao opened 1 year ago

RaechelliaYao commented 1 year ago

代码如下 使用tpu绘制速度比cpu慢了好多个量级

static bm_status_t bmcv_draw_line(bm_handle_t handle, u64 base_addr, int pixel_stride, int row_stride, int height, int width, bmcv_point_t start_point, bmcv_point_t end_point, u8 val)
{
    // Bresenham 直线算法
    int dx = abs(end_point.x - start_point.x);
    int dy = abs(end_point.y - start_point.y);
    int sx, sy;

    if (start_point.x < end_point.x) {
        sx = 1;
    }
    else {
        sx = -1;
    }

    if (start_point.y < end_point.y) {
        sy = 1;
    }
    else {
        sy = -1;
    }

    int err = dx - dy;
    int x = start_point.x;
    int y = start_point.y;

    while (true) {
        // 绘制当前点
        if (x >= 0 && x < width && y >= 0 && y < height) {
            u64 offset = x * pixel_stride + y * row_stride;
            base_addr = base_addr + offset;
            bm_api_memset_byte_t api = { base_addr, 1, 1, 1, 1, 1, 1, 1, pixel_stride, val };

            if (BM_SUCCESS != bm_send_api(handle, (bm_api_id_t)177, (uint8_t*)&api, sizeof(api)))
            {
                std::cout << "draw line send api error\r\n" << std::endl;
                return BM_ERR_FAILURE;
            }
        }

        if (x == end_point.x && y == end_point.y) {
            break;
        }

        int e2 = 2 * err;
        if (e2 > -dy) {
            err = err - dy;
            x = x + sx;
        }
        if (e2 < dx) {
            err = err + dx;
            y = y + sy;
        }
    }

    if (BM_SUCCESS != bm_sync_api(handle)) {
        std::cout << "draw line sync api error\r\n" << std::endl;
        return BM_ERR_FAILURE;
    }

    return BM_SUCCESS;
}
lingwei2023 commented 1 year ago

代码如下 使用tpu绘制速度比cpu慢了好多个量级

static bm_status_t bmcv_draw_line(bm_handle_t handle, u64 base_addr, int pixel_stride, int row_stride, int height, int width, bmcv_point_t start_point, bmcv_point_t end_point, u8 val)
{
  // Bresenham 直线算法
  int dx = abs(end_point.x - start_point.x);
  int dy = abs(end_point.y - start_point.y);
  int sx, sy;

  if (start_point.x < end_point.x) {
      sx = 1;
  }
  else {
      sx = -1;
  }

  if (start_point.y < end_point.y) {
      sy = 1;
  }
  else {
      sy = -1;
  }

  int err = dx - dy;
  int x = start_point.x;
  int y = start_point.y;

  while (true) {
      // 绘制当前点
      if (x >= 0 && x < width && y >= 0 && y < height) {
          u64 offset = x * pixel_stride + y * row_stride;
          base_addr = base_addr + offset;
          bm_api_memset_byte_t api = { base_addr, 1, 1, 1, 1, 1, 1, 1, pixel_stride, val };

          if (BM_SUCCESS != bm_send_api(handle, (bm_api_id_t)177, (uint8_t*)&api, sizeof(api)))
          {
              std::cout << "draw line send api error\r\n" << std::endl;
              return BM_ERR_FAILURE;
          }
      }

      if (x == end_point.x && y == end_point.y) {
          break;
      }

      int e2 = 2 * err;
      if (e2 > -dy) {
          err = err - dy;
          x = x + sx;
      }
      if (e2 < dx) {
          err = err + dx;
          y = y + sy;
      }
  }

  if (BM_SUCCESS != bm_sync_api(handle)) {
      std::cout << "draw line sync api error\r\n" << std::endl;
      return BM_ERR_FAILURE;
  }

  return BM_SUCCESS;
}

您好,首先感谢您使用这个接口,并提出意见,宝贵的意见是我们优化的动力。 从代码看,您使用的是1684 下 tpu 画框的接口,在实现画线的功能。建议您尝试已封装好的接口 bmcv_image_draw_rectangle 来实现画直线的功能。 我们内部测试,画一条1024*1024的直线,耗时在400us左右。

RaechelliaYao commented 1 year ago

@lingwei2023 你好,画一条1024*1024的直线,耗时确实是在400us左右,但是如果需要画斜线需要如何处理呢