一維高斯函數(shù):
??高斯函數(shù)具有線性可分的性質(zhì)押框,即可以通過2個(gè)一維的高斯函數(shù)敢辩,分別對(duì)圖像進(jìn)行縱向和橫向進(jìn)行一次處理,就能得到和二維高斯函數(shù)一致的效果逛万。
??重點(diǎn)在于泳猬,一維高斯函數(shù)處理圖像的復(fù)雜度為 2xy2r,而二維高斯函數(shù)的復(fù)雜度達(dá)到了xy4r^2,一維比二維降低了指數(shù)級(jí)的復(fù)雜度宇植!
QT代碼:
void getWeights1D(double* weights,int r){
//計(jì)算高斯核權(quán)重
const float sigma = (r*2+1) / 2.0;
const float exp = std::exp(1);
const float sigma2 = sigma*sigma;
const float dSigma2 = 2*sigma2;
const float k = 1 / sqrt(2*3.1415926*sigma2);
double sum = 0;
for(int i = -r;i<=r;i++){
int absI =abs(i);
int it = i+r;
weights[it] = k * std::pow(exp,-absI*absI / dSigma2);
sum+= weights[it];
}
for(int i = 0;i<=r*2;++i)
weights[i] /= sum;
}
void MainWindow::GuassianBlur1D(){
int r = 10;
double* weights = new double[r*2+1];
getWeights1D(weights,r);
int width = m_srcImg.width();
int height = m_srcImg.height();
QImage newImg(m_srcImg);
auto startTime = clock();
//橫向模糊
for(int i = 0 ;i<width;++i){
for(int j =0;j<height;++j){
float sumR = 0;
float sumG = 0;
float sumB = 0;
for(int x = -r;x<=r;++x){
int pos = i+x;
if(pos < 0 || pos >= width)
pos = i - x;
QColor color = m_srcImg.pixel(pos,j);
sumR += color.red()*weights[x+r];
sumG += color.green()*weights[x+r];
sumB += color.blue()*weights[x+r];
}
QColor finalColor;
int r = std::round(sumR);
int g = std::round(sumG);
int b = std::round(sumB);
finalColor.setRed(r);
finalColor.setGreen(g);
finalColor.setBlue(b);
QPoint point(i,j);
newImg.setPixelColor(point,finalColor);
}
}
//縱向模糊
for(int i = 0 ;i<width;++i){
for(int j =0;j<height;++j){
float sumR = 0;
float sumG = 0;
float sumB = 0;
for(int x = -r;x<=r;++x){
int pos = j + x;
if(pos < 0 || pos >= height)
pos = j - x;
QColor color = newImg.pixel(i,pos);
sumR += color.red()*weights[x+r];
sumG += color.green()*weights[x+r];
sumB += color.blue()*weights[x+r];
}
QColor finalColor;
int r = std::round(sumR);
int g = std::round(sumG);
int b = std::round(sumB);
finalColor.setRed(r);
finalColor.setGreen(g);
finalColor.setBlue(b);
QPoint point(i,j);
newImg.setPixelColor(point,finalColor);
}
}
auto endTime = clock();
qDebug()<<"模糊耗時(shí)"<<endTime - startTime;
newImg.save("D:/tag.jpg");
qDebug()<<"done";
delete [] weights;
}
void MainWindow::on_btnGaussBlur_clicked()
{
//GuassianBlur2D();
GuassianBlur1D();
}
運(yùn)行結(jié)果為:
模糊耗時(shí) 1457
done
比二維高斯函數(shù)快了近10倍得封!
原圖:
一維高斯模糊效果圖: