【发布时间】: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 慢?