均值濾波器的使用場景:
均值濾波器使用于處理一些如上述藍色線的高斯噪聲場景
紅色曲線是經過均值濾波處理后的數據。主要因為均值濾波設置數據緩沖區(也即延時周期),使得測量值經過緩沖不會出現特別大的變化。
黃色曲線為高斯噪聲,紅色曲線為經過均值濾波處理后的數據。
如果想要更好的濾波效果:
- 增加濾波和,也即往后多取幾幀數據進行累加求和,再處以累加次數;
- 嵌套使用均值濾波,也即用上一均值濾波輸出作為本次濾波輸入;
均值濾波不適合處理類似橙色曲線的脈沖噪聲的數據
藍色曲線為經過均值濾波處理后的數據,雖然整體幅值降低了,但是如61-69區間,實際測量只在61附近出現一次突變,但很快下降正常,但經過均值濾波處理,雖然幅值被降低,但其實也沒有達到理想,反而將突變脈沖以一個恒定的值持續了9s(累加次數,也即緩沖周期)。
目標脈沖值是0,未經過均值濾波處理在61s出現一較大突變,由于系統本身的阻尼等作用,系統實際不會產生太大的振蕩,可能由于來的比較快,系統會微微抖一下就穩定。但如果使用均值濾波處理后,在61s處的尖峰脈沖硬是被拉長了9幀才退出,系統穩定性必定太差。因此脈沖信號噪聲不適合用均值濾波,可以考慮使用低通濾波!
均值濾波作用
均值濾波是一種常見的圖像處理技術,用于平滑圖像中的噪聲或細節。它的主要用途包括:
去除噪聲:圖像中的噪聲是由于圖像采集過程中的各種因素引入的不希望的干擾。均值濾波可以通過計算像素周圍鄰域內像素的平均值來平滑圖像,并減少噪聲的影響。
平滑圖像:在某些情況下,圖像中的細節過多或變化過于劇烈,可能會導致視覺上的不連續或不平滑感覺。均值濾波可以通過平均周圍像素的值來減少這些細節,使圖像更加平滑。
降低圖像分辨率:在一些應用中,需要降低圖像的分辨率以減少計算或存儲的需求。均值濾波可以通過對圖像進行平滑來實現降低分辨率的效果。
圖像預處理:在某些圖像處理任務中,如圖像分割或邊緣檢測,均值濾波可以作為預處理步驟,幫助提取更準確的特征或邊緣。
需要注意的是,均值濾波是一種簡單且常用的濾波方法,但它可能會導致圖像細節的模糊或平滑化。對于某些應用場景,可能需要考慮其他更高級的濾波技術,以在平滑圖像的同時保留更多的細節信息。
均值濾波實現:
#include <stdio.h> #include <stdlib.h>double* weightedMeanFilter(double* input, int length, int windowSize, double* weights) {double* output = (double*)malloc(length * sizeof(double)); // 創建新數組int halfWindowSize = windowSize / 2;for (int i = 0; i < length; i++) {double weightedSum = 0.0;double weightSum = 0.0;for (int j = i - halfWindowSize; j <= i + halfWindowSize; j++) {if (j >= 0 && j < length) {weightedSum += input[j] * weights[j - (i - halfWindowSize)];weightSum += weights[j - (i - halfWindowSize)];}}output[i] = weightedSum / weightSum; // 計算加權平均值}return output; }int main() {double input[] = {1.2, 2.3, 3.4, 4.5, 5.6};int length = sizeof(input) / sizeof(input[0]);int windowSize = 3;double weights[] = {0.1, 0.6, 0.3}; // 示例權重系數數組double* output = weightedMeanFilter(input, length, windowSize, weights);printf("Input: ");for (int i = 0; i < length; i++) {printf("%.2f ", input[i]);}printf("\nOutput: ");for (int i = 0; i < length; i++) {printf("%.2f ", output[i]);}free(output); // 釋放動態分配的內存return 0; } /* Input: 1.20 2.30 3.40 4.50 5.60 Output: 1.57 2.52 3.62 4.72 5.44 */
增加權重系數可以使均值濾波更加靈活,以更好地適應不同的應用場景和需求。具體來說,增加權重系數的意義包括:
強調重要區域:通過調整權重系數,可以使某些像素在計算均值時具有更大的貢獻。這樣可以使均值濾波更加關注重要的區域,從而保留或突出這些區域的細節。例如,在人臉識別中,可以增加權重系數以突出人臉區域,以便更好地提取人臉特征。
抑制噪聲或異常值:某些像素可能受到噪聲或異常值的干擾,導致它們的值與周圍像素明顯不同。通過降低這些像素的權重系數,可以減少它們對均值的影響,從而抑制噪聲或異常值的影響。
考慮空間相關性:在一些情況下,像素之間的空間關系對濾波結果的影響很大。通過調整權重系數以考慮像素之間的空間相關性,可以更好地保留圖像的結構信息。例如,可以使用高斯加權系數來加權計算均值,以便更好地平滑圖像并保留邊緣。
自適應濾波:通過根據像素的特征或屬性來動態調整權重系數,可以實現自適應濾波。這意味著不同的像素可以具有不同的權重,從而使濾波更加適應圖像的局部特征。例如,可以根據像素的梯度值或紋理信息來調整權重系數,以實現更好的平滑效果。
總之,增加權重系數可以提供更多的靈活性和控制力,使均值濾波能夠更好地適應不同的圖像處理需求,并在平滑圖像的同時保留重要的細節。
#include <stdio.h> #include <stdlib.h>double* weightedMeanFilter(double* input, int length, int windowSize, double* weights) {double* output = (double*)malloc(length * sizeof(double)); // 創建新數組int halfWindowSize = windowSize / 2;for (int i = 0; i < length; i++) {double weightedSum = 0.0;double weightSum = 0.0;for (int j = i - halfWindowSize; j <= i + halfWindowSize; j++) {if (j >= 0 && j < length) {weightedSum += input[j] * weights[j - (i - halfWindowSize)];weightSum += weights[j - (i - halfWindowSize)];}}output[i] = weightedSum / weightSum; // 計算加權平均值}return output; }int main() {double input[] = {1.2, 2.3, 3.4, 4.5, 5.6};int length = sizeof(input) / sizeof(input[0]);int windowSize = 3;double weights[] = {0.1, 0.6, 0.3}; // 示例權重系數數組double* output = weightedMeanFilter(input, length, windowSize, weights);printf("Input: ");for (int i = 0; i < length; i++) {printf("%.2f ", input[i]);}printf("\nOutput: ");for (int i = 0; i < length; i++) {printf("%.2f ", output[i]);}free(output); // 釋放動態分配的內存return 0; } /* Input: 1.20 2.30 3.40 4.50 5.60 Output: 1.57 2.52 3.62 4.72 5.44 */
結果對比:
參考:
1、簡單的均值濾波講解(附代碼)_嗶哩嗶哩_bilibili
2、https://www.cnblogs.com/faithlocus/p/17532226.html