出力ピクセルの可能な最大値または最小値を所定の範囲で制限する画像フィルタリング用の「適応型」畳み込みを実装しようとしています。私はこれを行うことを可能にするopencvの機能を発見していないので、私は私が探しているものを達成するために自分自身を書きました。 (おそらく別のライブラリはありますか?)唯一の問題は、この関数は約0.9秒かかりますが、cv :: filter2Dが画像をフィルタリングするのにかかる時間は約0.005秒(同じカーネルで)です。誰も私の方法をスピードアップできる方法を知っていますか?畳み込み関数を高速化するC++
私のカーネルに関するいくつかのコメント: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;
}
EDIT:
私はNumbaを使用して約0.2秒に使用していますPythonスクリプトで畳み込みをスピードアップすることができました。私はまだ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
計算 'new_image.at(i、j)'を並列化することは可能ですか? –
AndyG
最も外側のループに "parallel_for_"を使用するのは意味がありますか?私は、parallel_for_ループ内の引数を読み込みからどのように記述するかについては正確にはわかりません。また、特定のC++ライブラリを使用してループを並列化するさまざまな方法があることも確認しています。特にどの方法をお勧めしますか? – RMatt
なぜ畳み込みの後に値*をクランプできないのですか? – beaker