前言:简书菜鸟一枚,主要用于记录。如有侵权,望告知,我会下架文章。
所遇场景:有设备采集到512个点位的压力数据。要根据数据跑算法模型得出姿势。跑算法前,要对数据先进行预处理,参考图像预处理的中值滤波、直方图均衡
一、找资源。未能找到直接可用的资源。参考资源:
1.java中值滤波_中值滤波 java实现
2.Java实现图像中值滤波 - 优化
3.直方图均衡化原理
4.JAVA实现直方图均衡化增强灰度和彩色图像
算法与项目结合理解:
更多中值滤波、直方图理解另找资料。我也是似懂非懂。
二、代码实现
1.中值滤波:
/**
*
* @param pixels 图像像素点,二维数组
* @param w 二维数组的列
* @param h 二维数组的行
*/
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}};
// 初始实现,发现:冗余了,未去掉边界
// 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("遍历原数组00: " + buffer.toString() + ", i " + index + ", medians =" + Arrays.toString(medians));
// }
// MyLog.i("遍历原数组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("遍历原数组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("遍历原数组中值下标y,x (" + y + "," + x +"), 变化" + value + "->" + filterArray[4] + ", filterArray =" + Arrays.toString(filterArray));
}
MyLog.i("遍历原数组中值: " + buffer.toString());
}
}
中值滤波 优化-减少循环
/**
* http://events.jianshu.io/p/964f68851abc
*
* @param pixel 一维数组
* @param w 一维数组转二维数组的列
* @param h 一维数组转二维数组的行
*/
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}};
// 记录灰度值出现个数
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) {
// 累计灰度值个数
if (count[k] == 0) {
count[k] = 1;
} else {
count[k] += 1;
}
}
}
if (k == 0) MyLog.i("遍历原数组: " + buffer.toString());
}
if (count[k] != 0) MyLog.i("灰度值: " + k + ", 个数 " + count[k]);
}
// 计算各灰度值出现概率
double[] Pr = new double[count.length];
// 对应灰度值概率累计; 第一个灰度值的是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("计算各灰度值出现概率, 灰度值 i " + i + ", 次数 " + count[i] + ", 概率 " + Pr[i] + ", 累计概率 " + sk[i]);
}
}
int[][] newPixels = new int[width][height]; // 统计新图的灰度值
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("遍历处理后的数组: " + buffer.toString());
}
MyLog.i("-----------------------------------");
}
直方图均衡化 优化-减少循环
/**
* @param pixels 一维数组
*/
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};
// 记录灰度值出现个数
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) {
// 累计灰度值个数
count[k] += 1;
}
}
if (count[k] != 0) MyLog.i("灰度值: " + k + ", 个数 " + count[k]);
if (k == count.length - 1) MyLog.i("遍历原数组: \n" + buffer.toString());
}
// 计算各灰度值出现概率
double[] Pr = new double[count.length];
// 对应灰度值概率累计; 第一个灰度值的是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("计算各灰度值出现概率, 灰度值 i " + i + ", 次数 " + 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("遍历处理后的数组: \n" + buffer2.toString());
MyLog.i("-----------------------------------");
}
log输出
2023-02-12 15:52:40.695 MyLog: (BitmapUtil.java:41).histogram 灰度值: 50, 个数 4.0
2023-02-12 15:52:40.696 MyLog: (BitmapUtil.java:41).histogram 灰度值: 128, 个数 3.0
2023-02-12 15:52:40.696 MyLog: (BitmapUtil.java:41).histogram 灰度值: 200, 个数 5.0
2023-02-12 15:52:40.696 MyLog: (BitmapUtil.java:41).histogram 灰度值: 255, 个数 4.0
2023-02-12 15:52:40.697 MyLog: (BitmapUtil.java:42).histogram 遍历原数组:
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 计算各灰度值出现概率, 灰度值 i 50, 次数 4.0, 概率 0.25, 累计概率 0.25
2023-02-12 15:52:40.698 MyLog: (BitmapUtil.java:54).histogram 计算各灰度值出现概率, 灰度值 i 128, 次数 3.0, 概率 0.1875, 累计概率 0.4375
2023-02-12 15:52:40.699 MyLog: (BitmapUtil.java:54).histogram 计算各灰度值出现概率, 灰度值 i 200, 次数 5.0, 概率 0.3125, 累计概率 0.75
2023-02-12 15:52:40.700 MyLog: (BitmapUtil.java:54).histogram 计算各灰度值出现概率, 灰度值 i 255, 次数 4.0, 概率 0.25, 累计概率 1.0
2023-02-12 15:52:40.701 MyLog: (BitmapUtil.java:63).histogram 遍历处理后的数组:
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 遍历原数组中值下标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 遍历原数组中值下标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 遍历原数组中值:
250 144
2023-02-12 15:52:40.703 MyLog: (BitmapUtil.java:177).medianFilter 遍历原数组中值下标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 遍历原数组中值下标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 遍历原数组中值:
250 144
148 150