[英]Speed up Convolution Function C++
我正在嘗試為圖像過濾實現“自適應”卷積,將輸出像素的最大或最小可能值限制為預定范圍。 我沒有在opencv中找到任何允許執行此操作的函數,因此我編寫了自己的函數來實現我想要的功能。 (也許有一個不同的庫嗎?)唯一的問題是此功能大約需要0.9秒,而cv :: filter2D過濾圖像所需的時間大約是0.005秒(兩者都具有相同的內核)。 有誰知道我如何加快我的方法?
關於我的內核的幾點評論:這是一個9x9的自定義銳化過濾器,內核是不可分離的。 我嘗試將濾波器重新設計為可分離的,但無法達到預期的效果。 有什么想法嗎? 以下是我用於代碼的函數:
Mat& adaptive_convolution(Mat& img)
{
fstream in("kernel.txt");
string line;
float v[9][9];
int i = 0, k = 0;
while (getline(in, line))
{
float value;
int k = 0;
stringstream ss(line);
while (ss >> value)
{
v[i][k] = value;
++k;
}
++i;
}
clock_t init, end;
double minVal;
double maxVal;
Point minLoc;
Point maxLoc;
int pad_fact = 4;
int top, left, bottom, right;
Mat new_image = img;
top = pad_fact; bottom = pad_fact;
left = pad_fact; right = pad_fact;
copyMakeBorder(img, new_image, top, bottom, left, right, BORDER_CONSTANT, 0);
minMaxLoc(img, &minVal, &maxVal, &minLoc, &maxLoc);
new_image / 2^8;
init = clock();
double temp = 0;
for (int i = pad_fact; i < img.rows + pad_fact; i++)
{
for (int j = pad_fact; j < img.cols + pad_fact; j++)
{
for (int ii = -pad_fact; ii <= pad_fact; ii++)
{
for (int jj = -pad_fact; jj <= pad_fact; jj++)
{
//temp = double(v[ii + 2*pad_fact][jj + 2*pad_fact]);
temp = temp + double(v[ii + pad_fact][jj + pad_fact] * float(new_image.at<uchar>(i - jj, j - ii)));
//temp = double(new_image.at<uchar>(i - jj, j - ii));
}
}
if (temp > maxVal)
{
temp = maxVal;
}
else
{
if (temp < minVal)
{
temp = minVal;
}
}
new_image.at<uchar>(i, j) = temp;
temp = 0;
}
}
img = new_image;
end = clock();
cout << float(end - init)/1000 << endl;
return img;
}
編輯:
我使用Numba可以將我正在使用的python腳本中的卷積加速到大約0.2秒。 我仍然需要看到使用c ++的這種改進。 我可以通過使用opencv獲得幫助嗎?
import numba as nb
import numpy as np
@nb.autojit
def custom_convolve(image,kernel,pad_fact):
pad_fact = int(pad_fact)
filt_im = np.zeros(image.shape)
rows = image.shape[0]
columns = image.shape[1]
glob_max = np.max(image)
glob_min = np.min(image)
for x in range(pad_fact,columns-pad_fact,1):
for y in range(pad_fact,rows-pad_fact,1):
pix_sum = 0
for k in range(-pad_fact,pad_fact,1):
for j in range(-pad_fact,pad_fact,1):
pix_sum = pix_sum + kernel[k+pad_fact,j+pad_fact]*image[y-j,x-k]
if pix_sum > glob_max:
pix_sum = glob_max
elif pix_sum < glob_min:
pix_sum = glob_min
filt_im[y,x] = pix_sum
return filt_im
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.