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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,835评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,598评论 1 295
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,569评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,159评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,533评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,710评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,923评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,674评论 0 203
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,421评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,622评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,115评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,428评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,114评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,097评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,875评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,753评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,649评论 2 271

推荐阅读更多精彩内容