[英]convolution of float image with 2D function in C
您好,我必須使用以下內核對32位原始圖像進行2D卷積
h(x,y)= a(b* exp^(-squareroot(x^2+y^2))
我不知道如何執行它,因為我是初學者。 我的圖片大小是1024 * 768。 我應該保持相同大小的內核並進行卷積還是要保留一個小的內核? 他們兩個會有所作為嗎? 如果我保留一個小的內核,如何將其與整個圖像進行卷積?
請幫忙
請檢查生成內核的代碼是否正確
謝謝你們的回答。 請檢查下面的生成內核代碼和卷積代碼。 我不確定我做得對嗎
int krowhalf = krow / 2,kcolhalf = kcol / 2;
// sum is for normalization
float sum = 0.0;
// generate kernel
for (int x = -krowhalf; x <= krowhalf; x++)
{
for(int y = -kcolhalf; y <= kcolhalf; y++)
{
r = sqrtl(x*x + y*y);
gKernel[x + krowhalf][y + kcolhalf] = a*(b*exp(-(r));
sum += gKernel[x + krowhalf][y + kcolhalf];
}
}
//normalize the Kernel
for(int i = 0; i < krow; ++i)
for(int j = 0; j < kcol; ++j)
gKernel[i][j] /= sum;
float **convolve2D(float** in, float** out, int h, int v, float **kernel, int kCols, int kRows)
{
int kCenterX = kCols / 2;
int kCenterY = kRows / 2;
int i,j,m,mm,n,nn,ii,jj;
for(i=0; i < h; ++i)
// rows
{
for(j=0; j < v; ++j)
// columns
{
for(m=0; m < kRows; ++m) // kernel rows
{
mm = kRows - 1 - m; // row index of flipped kernel
for(n=0; n < kCols; ++n) // kernel columns
{
nn = kCols - 1 - n; // column index of flipped kernel
//index of input signal, used for checking boundary
ii = i + (m - kCenterY);
jj = j + (n - kCenterX);
// ignore input samples which are out of bound
if( ii >= 0 && ii < h && jj >= 0 && jj < v )
//out[i][j] += in[ii][jj] * (kernel[mm+nn*29]);
out[i][j] += in[ii][jj] * (kernel[mm][nn]);
}
}
}
}
返回 }
您知道如何進行一維信號卷積嗎? 您的過濾器始終為有限長度。 您無法使用數字計算機進行無限卷積。 二維濾波器也總是有限長度的。 例如,最簡單的2-D濾波器拉普拉斯算子只有3X3大小。 過濾器越長,處理就越復雜。
好吧,要使用一個非常大的內核(這將是理論上的確切結果)將永遠花費,因此通常除非您確實需要一些精確的東西,否則通常采用3x3或5x5。 如果您仍然使用精度有限的常規浮點數,則更多的變化不太可能。
可以通過遍歷每個點的兩個簡單的for循環進行卷積。 對於邊緣,一種簡單的方法是擴展圖像(例如,如果使用3x3,則在每一側添加一個像素)並從舊邊緣開始循環。
發布代碼后進行編輯:
在循環代碼中使用ifs將阻止編譯器使用更快的指令(除非您的編譯器非常聰明)同時計算更多的點。 這行代碼: out[i][j] += in[ii][jj] * (kernel[mm][nn]);
可以由編譯器轉換為SIMD指令,同時計算4個值。 正因為如此,通常將填充零添加到邊緣並且不使內核位於這些點上更為有效。
計算高斯濾波器的方法有很多(這是圖像處理中的基本方法)。 這取決於您對性能的要求以及要支持的內核大小范圍。
OpenCV和Intel IPP確實支持此過濾器,您可以在Web上輕松找到開放源代碼。 您還可以查看Deriche(遞歸實現高斯及其衍生函數)和van Vliet(高斯濾波器的遞歸實現)特殊算法:無論大小如何,它們都可以通過每個像素固定數量的運算來計算濾波器。
您的實現似乎正確。 無論如何,我建議您使用過濾器的可分離性:2D高斯是通過1D水平高斯,然后是1D垂直( e^-(X²+Y²)=e^-X².e^-Y²
)獲得的。 這樣,您只需要krow + kcol
即可,而不是每個像素進行krow x kcol
操作。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.