您的位置:首页 > 移动开发 > Android开发

android图像像素提取中遇到的算法问题

2015-01-31 14:12 323 查看
在做爆炸特效的过程中遇到一个问题, 虽然这个特效已经绕开这个问题解决了, 但是原问题还想得到解决, 下面是问题描述:

我提取了一个图像的像素数组, 比方百度logo, 看起来好像只有红白蓝几种颜色,  想当然用hashset过滤一下就能出来这几个色值, 奈何过滤后hashset的size仍有688(原数组length=78570), 分析发现, 这些颜色的色差很小, 比如-1762066544, -34209912, -17629308, -17629309, -17760386, -18415766, -18808991, -18808988, -18808981, -1495401354, 1557723508, 449770879,
1070000989, -290532022, -1065312460, 290150957, 41975936; 所以问题产生了, 怎么从这688个数中, 将相似的用一个值代替, 比如-1999, -2001, -2002随便取一个-2001来代替这三个, -2104, -2106, -2107随便取一个2106来代替三个, 以减小数组, 我只想让用户知道这里面有红白蓝这几种颜色, 至于是#FFFFFF还是#FFFFFE用户看不出来, 留一个就行了, 我的解决方案是:

(1)封装一个类似Integer的类RoundInteger, 将这688元素放入HashSet<RoundInteger>中, 关键是里面覆写hashCode(), 将-1999四舍五入为-2000, 将-2001也四舍五入为-2000, 这样出来了一部分相似性, 返回了570个色值, 但这种方式对-2104和-2106这种相似性没有作用;

(2)封装一个类似Integer的类TrunkInteger, 将这688元素放入HashSet<TruncateInteger>中,还是覆写hashCode(), 返回这个元素的个位抹零后的值, 这样出来了一部分相似性, 返回了579个色值, 但这种方式对-1999, -2001, -2002这种相似性没有作用;
(3)建一个Hashset<Integer>, 做两次循环, 一次遍历570色值, 将里面的原值(非四舍五入)放进去, 一次遍历579个色值, 也是将里面的原值(非截断个位)放进去, 出来的size是590个(竟然比那个还多?), 将这个570,
579, 590进行比较后取最小的570;

弄完以后效果有些差, 更令人堪忧的是做了5次循环, 导致耗了219毫秒, 意识到不该去优化, 应该是陷入了一个坑, 所以换了一种方式做像素提取, 但是请问算法比较好的前辈, 这种几千个数组去除相似性的工作如何展开比较好? 

Code:

        long millsec = System.currentTimeMillis();

        HashSet<Integer> hs = new HashSet<Integer>();

        int size = arr.length; //原图像像素数组

        for(int i = 0; i < size; ++i)

        {

            hs.add(arr[i]);

        }

        HashSet<RoundInteger> rihs = new HashSet<RoundInteger>();

        for(Integer i : hs)

        {

            rihs.add(new RoundInteger(i));

        }

        HashSet<TruncateInteger> tihs = new HashSet<TruncateInteger>();

        for(Integer i : hs)

        {

            tihs.add(new TruncateInteger(i));

        }

        HashSet<Integer> ihs = new HashSet<Integer>();

        for(RoundInteger ri : rihs)

        {

            ihs.add(ri.get());

        }

        for(TruncateInteger ti : tihs)

        {

            ihs.add(ti.get());

        }

        Log.e("john", ">>>" + (System.currentTimeMillis() - millsec));

    private static final class RoundInteger

    {

        private final int value;

       

        public RoundInteger(int value) {

            this.value = value;

        }

       

        public int get() {

            return value;

        }

       

        @Override

        public int hashCode() {

            if(value == 0)

                return 0;

            if(value < 0)

            {

                return -((int)(-value / 10.0f + 0.5f) * 10);

            }else{

                return (int)(value / 10.0f + 0.5f) * 10;

            }

        }

       

        @Override

        public boolean equals(Object obj) {

            if (this == obj)

                return true;

            if (obj == null)

                return false;

            if (getClass() != obj.getClass())

                return false;

            RoundInteger other = (RoundInteger) obj;

            if (hashCode() != other.hashCode())

                return false;

            return true;

        }

        @Override

        public String toString() {

            return String.valueOf(value);

        }

    }

   

    private static final class TruncateInteger

    {

        private final int value;

       

        public TruncateInteger(int value) {

            this.value = value;

        }

       

        public int get() {

            return value;

        }

       

        @Override

        public int hashCode() {

                return (int)(value / 10.0f) * 10;

        }

       

        @Override

        public boolean equals(Object obj) {

            if (this == obj)

                return true;

            if (obj == null)

                return false;

            if (getClass() != obj.getClass())

                return false;

            TruncateInteger other = (TruncateInteger) obj;

            if (hashCode() != other.hashCode())

                return false;

            return true;

        }

        @Override

        public String toString() {

            return String.valueOf(value);

        }

    }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息