Android中值滤波、直方图均衡化处理数组

前言:简书菜鸟一枚,主要用于记录。如有侵权,望告知,我会下架文章。

所遇场景:有设备采集到512个点位的压力数据。要根据数据跑算法模型得出姿势。跑算法前,要对数据先进行预处理,参考图像预处理的中值滤波、直方图均衡

一、找资源。未能找到直接可用的资源。参考资源:

1.java中值滤波_中值滤波 java实现
2.Java实现图像中值滤波 - 优化
3.直方图均衡化原理
4.JAVA实现直方图均衡化增强灰度和彩色图像
算法与项目结合理解:

image.png

更多中值滤波、直方图理解另找资料。我也是似懂非懂。

二、代码实现

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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容