目錄
1 簡介
2 算法原理
3 代碼實現
4 演示Demo
4.1 開發環境
4.2 功能介紹
4.3 下載地址
參考
1 簡介
????????BEEPS(Bias Elimination in Edge-Preserving Smoothing) 是一種基于偏微分方程(PDE)的邊緣保留平滑濾波算法。它能夠在平滑圖像的同時有效消除偏差(Bias),從而更好地保留邊緣和細節。BEEPS 濾波算法廣泛應用于圖像去噪、圖像增強和醫學圖像處理等領域。
2 算法原理
????????BEEPS 濾波的核心思想是通過引入偏差消除項,改進傳統的邊緣保留平滑算法(如各向異性擴散)。其數學模型基于以下偏微分方程:
????????其中
-
I 是圖像。
-
?I 是圖像的梯度。
-
c(∣?I∣) 是擴散系數,控制濾波的強度。
-
是偏差消除項的權重。
-
是原始圖像
????????擴散系數c(∣?I∣) 通常定義為:
????????或
????????其中,k 是一個控制邊緣敏感度的參數。
????????算法步驟:
-
計算圖像的梯度 ?I。
-
根據梯度計算擴散系數 c(∣?I∣)。
-
使用擴散系數更新圖像像素值。
-
重復上述步驟,直到達到指定的迭代次數。
3 代碼實現
????????Anisotropic濾波算法的的C語言實現代碼如下
double Gaussian(int u, int v, double sigma)
{int t = -(u - v) * (u - v);return exp((double)t / sigma);
}
int BEEPSHorizontal(unsigned char* srcPtr, int width, int height, unsigned char* outData, double sigma, int c)
{unsigned char* F = (unsigned char*)malloc(sizeof(unsigned char) * width * height);int *s = (int*)malloc(sizeof(int) * width);int *v = (int*)malloc(sizeof(int) * width);int pos = 0, X = 0, Y = 0;int p = 0;memset(F, 0, width * height);memset(outData, 0, width * height);memset(s, 0, width);memset(v, 0, width);unsigned char* D = outData;for (int y = 0; y < height; y++){for (int x = 0; x < width; x++){X = width - 1 - x;Y = height - 1 - y;if (x == 0){pos = x + y * width;F[pos] = srcPtr[pos];s[0] = srcPtr[pos];p = X;pos = p + Y * width;v[p] = srcPtr[pos];D[pos] = srcPtr[pos];}else{p = x;pos = p + y * width;s[p] = (int)(10.0 * Gaussian(srcPtr[pos], F[pos - 1], sigma));F[pos] = CLIP3((((100 - s[p] * c) * srcPtr[pos] + s[p] * c * F[pos - 1]) / 100), 0, 255);p = X;pos = p + Y * width;v[p] = (int)(10.0 * Gaussian(srcPtr[pos], D[pos + 1], sigma));D[pos] = CLIP3((((100 - v[p] * c) * srcPtr[pos] + v[p] * c * D[pos + 1]) / 100), 0, 255);}}}for (int i = 0; i < height * width; i++){D[i] = CLIP3(((10 * F[i] - (10 - c) * (srcPtr[i]) + 10 * D[i]) / (10 + c)), 0, 255);}free(F);free(s);free(v);return 0;
}int BEEPSVertical(unsigned char* srcPtr, int width, int height, unsigned char* outData, double sigma, int c)
{unsigned char* F = (unsigned char*)malloc(sizeof(unsigned char) * width * height);unsigned char* D = outData;int* s = (int*)malloc(sizeof(int) * height);int* v = (int*)malloc(sizeof(int) * height);int pos = 0, X = 0, Y = 0;memset(s, 0, height);memset(v, 0, height);for (int x = 0; x < width; x++){for (int y = 0; y < height; y++){X = width - 1 - x;Y = height - 1 - y;if (y == 0){pos = x + y * width;F[pos] = srcPtr[pos];s[y] = srcPtr[pos];pos = X + Y * width;D[pos] = srcPtr[pos];v[Y] = srcPtr[pos];}else{pos = x + y * width;s[y] = (int)(10.0 * Gaussian(srcPtr[pos], F[pos - width], sigma));F[pos] = CLIP3((((100 - s[y] * c) * srcPtr[pos] + s[y] * c * F[pos - width]) / 100), 0, 255);pos = X + Y * width;v[Y] = (int)(10.0 * Gaussian(srcPtr[pos], D[pos + width], sigma));D[pos] = CLIP3((((100 - v[Y] * c) * srcPtr[pos] + v[Y] * c * D[pos + width]) / 100), 0, 255);}}}for (int i = 0; i < height*width; i++){D[i] = CLIP3(((10 * F[i] - (10 - c) * (srcPtr[i]) + 10 * D[i]) / (10 + c)), 0, 255);}free(F);free(s);free(v);return 0;
}void BEEPSProcess(unsigned char* srcPtr, int width, int height, float sigma, float c)
{float* GMAP = (float*)malloc(sizeof(float) * 256 * 256);for (int j = 0; j < 256; j++){for (int i = 0; i < 256; i++){GMAP[i + j * 256] = Gaussian(i, j, sigma);}}sigma = sigma > 50 ? 50 : sigma;sigma = sigma * sigma * 2.0f;float Lamba = 10.0f * (float)(1 - (sqrt(2.0f * c * c + 1) - 1) / (c * c));unsigned char* pSrc = srcPtr;unsigned char* hValue = (unsigned char*)malloc(sizeof(unsigned char) * width * height);unsigned char* vValue = (unsigned char*)malloc(sizeof(unsigned char) * width * height);unsigned char* dstValue = (unsigned char*)malloc(sizeof(unsigned char) * width * height);BEEPSHorizontal(pSrc, width, height, hValue, sigma, Lamba);BEEPSVertical(hValue, width, height, vValue, sigma, Lamba);BEEPSVertical(pSrc, width, height, hValue, sigma, Lamba);BEEPSHorizontal(hValue, width, height, dstValue, sigma, Lamba);for (int i = 0; i < width * height; i++){*pSrc++ = CLIP3(((vValue[i] + dstValue[i]) / 2), 0, 255);}free(hValue);free(vValue);free(dstValue);
}int mxBeepsFilter(unsigned char* srcData, int nWidth, int nHeight, int nStride, float delta, float delta_s)
{if (srcData == NULL){return 0;}if (delta == 0 || delta_s == 0)return 0;unsigned char* yData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);unsigned char* cbData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);unsigned char* crData = (unsigned char*)malloc(sizeof(unsigned char) * nWidth * nHeight);unsigned char* pSrc = srcData;int Y, CB, CR;unsigned char* pY = yData;unsigned char* pCb = cbData;unsigned char* pCr = crData;for (int j = 0; j < nHeight; j++){for (int i = 0; i < nWidth; i++){RGBToYCbCr(pSrc[2], pSrc[1], pSrc[0], &Y, &CB, &CR);*pY = Y;*pCb = CB;*pCr = CR;pY++;pCb++;pCr++;pSrc += 4;}}BEEPSProcess(yData, nWidth, nHeight, delta, delta_s);pSrc = srcData;pY = yData;pCb = cbData;pCr = crData;int R, G, B;for (int j = 0; j < nHeight; j++){for (int i = 0; i < nWidth; i++){YCbCrToRGB(*pY, *pCb, *pCr, &R, &G, &B);pSrc[0] = B;pSrc[1] = G;pSrc[2] = R;pY++;pCb++;pCr++;pSrc += 4;}}free(yData);free(cbData);free(crData);return 0;
}
4 演示Demo
4.1 開發環境
-
Windows 10 Pro x64
-
Visual Studio 2015
4.2 功能介紹
????????演示程序主界面如下圖所示,具有圖像讀取、顯示、保存、雙邊濾波、表面模糊、導向濾波、局部均值方差濾波、各向異性擴散濾波、Smart Blur濾波、MeanShift濾波、BEEPS濾波、處理耗時等功能
原圖
濾波效果圖
4.3 下載地址
????????開發環境:
-
Windows 10 pro x64
-
Visual Studio 2015
????????下載地址:圖像保邊濾波之BEEPS濾波算法Demo
參考
????????圖像視頻濾鏡與人像美顏美妝算法詳解. 胡耀武、譚娟、李云夕. 電子工業出版社、2020-07