前言:簡書菜鳥一枚,主要用于記錄。如有侵權(quán),望告知,我會下架文章。
所遇場景:有設(shè)備采集到512個點位的壓力數(shù)據(jù)。要根據(jù)數(shù)據(jù)跑算法模型得出姿勢。跑算法前,要對數(shù)據(jù)先進行預(yù)處理,參考圖像預(yù)處理的中值濾波、直方圖均衡
一、找資源。未能找到直接可用的資源。參考資源:
1.java中值濾波_中值濾波 java實現(xiàn)
2.Java實現(xiàn)圖像中值濾波 - 優(yōu)化
3.直方圖均衡化原理
4.JAVA實現(xiàn)直方圖均衡化增強灰度和彩色圖像
算法與項目結(jié)合理解:

image.png
更多中值濾波、直方圖理解另找資料。我也是似懂非懂。
二、代碼實現(xiàn)
1.中值濾波:
/**
*
* @param pixels 圖像像素點,二維數(shù)組
* @param w 二維數(shù)組的列
* @param h 二維數(shù)組的行
*/
public static void medianFilter(int[][] pixels, int w, int h) {
w = h = 4;
pixels = new int[][]{
{150, 145, 151, 50},
{146, 250, 144, 50},
{151, 148, 150, 50},
{50, 50, 50, 50}};
// w = h = 3;
// pixels = new int[][]{{150, 145, 151}, {146, 250, 144}, {151, 148, 150}};
// 初始實現(xiàn),發(fā)現(xiàn):冗余了,未去掉邊界
// for (int y = 0; y < h; y++) {
// StringBuffer buffer = new StringBuffer();
// for (int x = 0; x < w; x++) {
// int value = pixels[y][x];
// buffer.append(" " + value);
// int index = y * w + x;
// int[] medians = new int[9]; // 3*3過濾
// for (int i = 0; i < medians.length; i++) {
// int ux = i % 3 + x;
// int uy = y + i / 3;
// if (uy >= h) uy = h - 1;
// if (ux >= w) ux = w - 1;
// medians[i] = pixels[uy][ux];
// }
// MyLog.i("遍歷原數(shù)組00: " + buffer.toString() + ", i " + index + ", medians =" + Arrays.toString(medians));
// }
// MyLog.i("遍歷原數(shù)組11: " + buffer.toString());
// }
StringBuffer buffer = new StringBuffer();
for (int y = 1; y < h - 1; y++) {
buffer.append("\n");
for (int x = 1; x < w - 1; x++) {
int value = pixels[y][x];
buffer.append(" " + value);
int[] filterArray = new int[9]; // 3*3過濾
for (int i = 0; i < filterArray.length; i++) {
int ux = i % 3 + x;
int uy = y + i / 3;
// MyLog.i("遍歷原數(shù)組00: " + uy + ", ux " + ux + ", filterArray =" + Arrays.toString(filterArray));
filterArray[i] = pixels[uy-1][ux-1];
}
Arrays.sort(filterArray);
pixels[y][x] = filterArray[4]; // 中值替換
MyLog.i("遍歷原數(shù)組中值下標y,x (" + y + "," + x +"), 變化" + value + "->" + filterArray[4] + ", filterArray =" + Arrays.toString(filterArray));
}
MyLog.i("遍歷原數(shù)組中值: " + buffer.toString());
}
}
中值濾波 優(yōu)化-減少循環(huán)
/**
* http://events.jianshu.io/p/964f68851abc
*
* @param pixel 一維數(shù)組
* @param w 一維數(shù)組轉(zhuǎn)二維數(shù)組的列
* @param h 一維數(shù)組轉(zhuǎn)二維數(shù)組的行
*/
public static int[] medianFiltering(int[] pixel, int w, int h) {
int[] newPixel = new int[w * h];
int[] tempR = new int[9];
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
if (x == 0 || x == w - 1 || y == 0 || y == h - 1) {
// 首行/列、尾行/列
newPixel[y * w + x] = pixel[y * w + x];
continue;
}
tempR[0] = pixel[x - 1 + (y - 1) * w];
tempR[1] = pixel[x + (y - 1) * w];
tempR[2] = pixel[x + 1 + (y - 1) * w];
tempR[3] = pixel[x - 1 + y * w];
tempR[4] = pixel[x + y * w];
tempR[5] = pixel[x + 1 + y * w];
tempR[6] = pixel[x - 1 + (y + 1) * w];
tempR[7] = pixel[x + (y + 1) * w];
tempR[8] = pixel[x + 1 + (y + 1) * w];
// median value
Arrays.sort(tempR);
newPixel[y * w + x] = tempR[4];
}
}
return newPixel;
}
2.直方圖均衡化:
/**
* //blog.csdn.net/qq_41037012/article/details/104900944
* https://www.freesion.com/article/1932342426/
*
* @return
*/
public static void histogram2(int[][] pixels, int x, int y) {
int width = 4;
int height = 4;
pixels = new int[][]{
{255, 128, 200, 50},
{50, 200, 255, 50},
{255, 200, 128, 128},
{200, 200, 255, 50}};
// 記錄灰度值出現(xiàn)個數(shù)
double[] count = new double[256];
for (int k = 0; k < count.length; k++) {
for (int i = 0; i < width; i++) {
StringBuffer buffer = new StringBuffer();
for (int j = 0; j < height; j++) {
buffer.append(" " + pixels[i][j]);
if (pixels[i][j] == k) {
// 累計灰度值個數(shù)
if (count[k] == 0) {
count[k] = 1;
} else {
count[k] += 1;
}
}
}
if (k == 0) MyLog.i("遍歷原數(shù)組: " + buffer.toString());
}
if (count[k] != 0) MyLog.i("灰度值: " + k + ", 個數(shù) " + count[k]);
}
// 計算各灰度值出現(xiàn)概率
double[] Pr = new double[count.length];
// 對應(yīng)灰度值概率累計; 第一個灰度值的是0.03 = 0 + 0.03; 第二個灰度值的 0.23 = 0.2 + 0.3; ...
double[] sk = new double[Pr.length];
for (int i = 0; i < Pr.length; i++) {
Pr[i] = count[i] / (double) (width * height);
for (int j = 0; j <= i; j++) {
sk[i] += Pr[j];
}
if (count[i] != 0) {
MyLog.i("計算各灰度值出現(xiàn)概率, 灰度值 i " + i + ", 次數(shù) " + count[i] + ", 概率 " + Pr[i] + ", 累計概率 " + sk[i]);
}
}
int[][] newPixels = new int[width][height]; // 統(tǒng)計新圖的灰度值
for (int i = 0; i < width; i++) {
StringBuffer buffer = new StringBuffer();
for (int j = 0; j < height; j++) {
int h = pixels[i][j];
newPixels[i][j] = (int) ((count.length - 1) * sk[h] + 0.5);
buffer.append(" " + newPixels[i][j]);
}
MyLog.i("遍歷處理后的數(shù)組: " + buffer.toString());
}
MyLog.i("-----------------------------------");
}
直方圖均衡化 優(yōu)化-減少循環(huán)
/**
* @param pixels 一維數(shù)組
*/
public static void histogram(int[] pixels) {
pixels = new int[]{255, 128, 200, 50, 50, 200, 255, 50, 255, 200, 128, 128, 200, 200, 255, 50};
// 記錄灰度值出現(xiàn)個數(shù)
double[] count = new double[256];
StringBuffer buffer = new StringBuffer();
for (int k = 0; k < count.length; k++) {
for (int i = 0; i < pixels.length; i++) {
if (k == 0) {
buffer.append(" " + pixels[i]);
if (i % 4 == 3) buffer.append("\n");
}
if (pixels[i] == k) {
// 累計灰度值個數(shù)
count[k] += 1;
}
}
if (count[k] != 0) MyLog.i("灰度值: " + k + ", 個數(shù) " + count[k]);
if (k == count.length - 1) MyLog.i("遍歷原數(shù)組: \n" + buffer.toString());
}
// 計算各灰度值出現(xiàn)概率
double[] Pr = new double[count.length];
// 對應(yīng)灰度值概率累計; 第一個灰度值的是0.03 = 0 + 0.03; 第二個灰度值的 0.23 = 0.2 + 0.3; ...
double[] sk = new double[Pr.length];
for (int i = 0; i < Pr.length; i++) {
Pr[i] = count[i] / (double) pixels.length;
for (int j = 0; j <= i; j++) {
sk[i] += Pr[j];
}
if (count[i] != 0) {
MyLog.i("計算各灰度值出現(xiàn)概率, 灰度值 i " + i + ", 次數(shù) " + count[i] + ", 概率 " + Pr[i] + ", 累計概率 " + sk[i]);
}
}
StringBuffer buffer2 = new StringBuffer();
for (int i = 0; i < pixels.length; i++) {
pixels[i] = (int) ((count.length - 1) * sk[pixels[i]] + 0.5);
buffer2.append(" " + pixels[i]);
if (i % 4 == 3) buffer2.append("\n");
}
MyLog.i("遍歷處理后的數(shù)組: \n" + buffer2.toString());
MyLog.i("-----------------------------------");
}
log輸出
2023-02-12 15:52:40.695 MyLog: (BitmapUtil.java:41).histogram 灰度值: 50, 個數(shù) 4.0
2023-02-12 15:52:40.696 MyLog: (BitmapUtil.java:41).histogram 灰度值: 128, 個數(shù) 3.0
2023-02-12 15:52:40.696 MyLog: (BitmapUtil.java:41).histogram 灰度值: 200, 個數(shù) 5.0
2023-02-12 15:52:40.696 MyLog: (BitmapUtil.java:41).histogram 灰度值: 255, 個數(shù) 4.0
2023-02-12 15:52:40.697 MyLog: (BitmapUtil.java:42).histogram 遍歷原數(shù)組:
255 128 200 50
50 200 255 50
255 200 128 128
200 200 255 50
2023-02-12 15:52:40.697 MyLog: (BitmapUtil.java:54).histogram 計算各灰度值出現(xiàn)概率, 灰度值 i 50, 次數(shù) 4.0, 概率 0.25, 累計概率 0.25
2023-02-12 15:52:40.698 MyLog: (BitmapUtil.java:54).histogram 計算各灰度值出現(xiàn)概率, 灰度值 i 128, 次數(shù) 3.0, 概率 0.1875, 累計概率 0.4375
2023-02-12 15:52:40.699 MyLog: (BitmapUtil.java:54).histogram 計算各灰度值出現(xiàn)概率, 灰度值 i 200, 次數(shù) 5.0, 概率 0.3125, 累計概率 0.75
2023-02-12 15:52:40.700 MyLog: (BitmapUtil.java:54).histogram 計算各灰度值出現(xiàn)概率, 灰度值 i 255, 次數(shù) 4.0, 概率 0.25, 累計概率 1.0
2023-02-12 15:52:40.701 MyLog: (BitmapUtil.java:63).histogram 遍歷處理后的數(shù)組:
255 112 191 64
64 191 255 64
255 191 112 112
191 191 255 64
2023-02-12 15:52:40.701 MyLog: (BitmapUtil.java:64).histogram -----------------------------------
2023-02-12 15:52:40.702 MyLog: (BitmapUtil.java:177).medianFilter 遍歷原數(shù)組中值下標y,x (1,1), 變化250->150, filterArray =[144, 145, 146, 148, 150, 150, 151, 151, 250]
2023-02-12 15:52:40.702 MyLog: (BitmapUtil.java:177).medianFilter 遍歷原數(shù)組中值下標y,x (1,2), 變化144->145, filterArray =[50, 50, 50, 144, 145, 148, 150, 150, 151]
2023-02-12 15:52:40.703 MyLog: (BitmapUtil.java:179).medianFilter 遍歷原數(shù)組中值:
250 144
2023-02-12 15:52:40.703 MyLog: (BitmapUtil.java:177).medianFilter 遍歷原數(shù)組中值下標y,x (2,1), 變化148->146, filterArray =[50, 50, 50, 145, 146, 148, 150, 150, 151]
2023-02-12 15:52:40.704 MyLog: (BitmapUtil.java:177).medianFilter 遍歷原數(shù)組中值下標y,x (2,2), 變化150->50, filterArray =[50, 50, 50, 50, 50, 145, 146, 150, 150]
2023-02-12 15:52:40.704 MyLog: (BitmapUtil.java:179).medianFilter 遍歷原數(shù)組中值:
250 144
148 150