【问题标题】:OpenCV Merge Mertens taking way more time on C++ as compared to Python与 Python 相比,OpenCV Merge Mertens 在 C++ 上花费的时间更多
【发布时间】:2020-08-09 01:33:03
【问题描述】:

我已经实现了一种使用 OpenCV 的 Merge Mertens 的图像增强技术。我已经用 Python 和 C++ 对其进行了编码。在相同大小和尺寸的同一组图像上,Merge Mertens 在 Python 上用时不到 2 秒,而在 C++ 上用时 11 秒。我希望我的 C++ 代码更快,因为我必须将它部署在 android 设备上。

此外,我尝试在 Python 和 C++ 上实现另一种曝光融合技术。下面是我在 Python 中对Fast Exposure Fusion 的实现。在 python 中需要 2 秒,但在翻译成 C++ 时需要 12 秒。

def merge(pme):

r = 12
eps = 0.25
sig_l = 0.5  
sig_g = 0.2  
sig_d = 0.12 
alpha = 1.1  
W_B = []
W_D = []
B = []
D = []

for img in pme:
    img = img.astype('float32')
    img /= 255

    lum = cv.cvtColor((img), cv.COLOR_RGB2GRAY)
    base_img = cv.ximgproc.guidedFilter(lum, lum, r, eps)
    wl = np.divide(np.square(base_img - 0.5), -2*sig_l*sig_l)
    wg = np.square(np.mean(lum) - 0.5) / (-2*sig_g*sig_g)
    wl = np.exp(wl)
    wg = np.exp(wg)
    wb = wl * wg
    W_B.append(wb)
    B.append(base_img)

    detail_img = img - base_img[:,:,None]
    kernel = np.ones((7, 7),np.float32)/49
    conved = cv.filter2D(lum,-1,kernel)
    wd = np.divide(np.square(conved - 0.5), -2*sig_d*sig_d)
    wd = np.exp(wd)
    W_D.append(wd)
    D.append(detail_img)

wb_s = np.sum(W_B, axis=0)+0.01
wd_s = np.sum(W_D, axis=0)+0.01

final = np.zeros(pme[0].shape)
for i in range(len(pme)):
    wb = np.true_divide(W_B[i], wb_s)
    b = B[i]
    wd = np.true_divide(W_D[i], wd_s)                
    d = D[i]
    final += (wb*b)[:,:,None] + (alpha*(wd[:,:,None]*d))

return final

发生这种情况有什么原因吗?我如何在 C++ 上实现与 Python 相同的时间,因为速度对我来说是必要的,因为我将使用此代码用于 android。

编辑:这是 C++ 代码

void expo_fuse(vector<Mat> pme, Mat &res) {
  float r = 12, eps = 0.25, sig_l = 0.5, sig_g = 0.2, sig_d = 0.12, alpha = 1.1;
  vector<Mat> W_B, W_D, B, D;

  for (int i = 0; i < pme.size(); i++) {
      Mat img = pme[i].clone();
      img.convertTo(img, CV_32FC3);
      img = img / 255;
      Mat lum;
      cvtColor(img, lum, COLOR_RGB2GRAY, 1);
      double max_v;
      minMaxIdx(lum, nullptr, &max_v, nullptr, nullptr);

      Mat wl;
      float wg;
      Mat base = guidedFilter(lum, lum, r, eps);
      wl = (base - 0.5).mul(base - 0.5) / (-2 * sig_l*sig_l);
      float m = mean(lum)[0];
      wg = ((m - 0.5)*(m - 0.5)) / (-2 * sig_l*sig_l);
      exp(wl, wl);
      wg = exp(wg);
      W_B.push_back(wl * wg);
      B.push_back(base);

      wl.release();
      cvtColor(base, base, COLOR_GRAY2RGB);

      Mat detail = img - base;
      base.release();
      Mat kernel = Mat::ones(7, 7, CV_32FC1)*(1 / 49);
      Mat conved, wd;
      filter2D(lum, conved, -1, kernel);
      wd = (conved - 0.5).mul(conved - 0.5) / (-2 * sig_d*sig_d);
      exp(wd, wd);
      W_D.push_back(wd);
      D.push_back(detail);
  }

  Mat wb_s = W_B[0].clone(), wd_s = W_D[0].clone();
  for (int i = 1; i < pme.size(); i++) {
      add(wb_s, W_B[i], wb_s);
      add(wd_s, W_D[i], wd_s);
  }

  Mat dst = Mat::zeros(pme[0].size(), CV_32FC3);
  for (int i = 0; i < pme.size(); i++) {
      Mat wb, wd;
      divide(W_B[i], wb_s, wb);
      divide(W_D[i], wd_s, wd);

      cvtColor(wd, wd, COLOR_GRAY2RGB);
      multiply(wd, D[i], wd);
      wd *= alpha;

      multiply(wb, B[i], wb);
      cvtColor(wb, wb, COLOR_GRAY2RGB);

      dst += wd + wb;

      W_B[i].release(); W_D[i].release(); D[i].release(); B[i].release();
  }
  res = dst.clone();
}

【问题讨论】:

  • 发布 c++ 代码
  • 按要求添加了代码。但问题仍然存在,为什么 OpenCV 在 C++ 中的功能比 Python 慢?

标签: python android c++ opencv


【解决方案1】:

所以我刚刚意识到由于在调试模式下运行我的代码而遇到了这个问题。当我切换到发布模式时,性能与 python 相似。我会把这个留在这里,以防有人遇到和我一样的错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2020-11-16
    • 2013-11-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多