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);
}
}
我提取了一个图像的像素数组, 比方百度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);
}
}
相关文章推荐
- android-->图像旋转遇到的问题
- 【C】用C语言提取bmp图片像素,并进行K-means聚类分析——容易遇到的问题
- 图像隐藏与提取的问题
- [导入]蛙蛙推荐:基于标记窗的网页正文提取算法的一些细节问题
- android 操作图像像素
- 自己在使用Android Maps API 开发地图应用程序时遇到的问题,以及解决的办法
- linux 下安装android遇到的问题及解决
- 新手求助解决如何提取像素点RGB值的问题
- Android : 新上手遇到的几个问题
- android 环境待建遇到的问题
- opencv图像显示遇到的一个问题
- android开发过程中遇到的一些问题汇总
- 开发Android过程中遇到到的问题
- 安装android-ndk-1.5_r1遇到的问题及解决方法
- 对于复合文档碎片提取遇到的问题
- Android环境搭建及遇到的小问题
- 蛙蛙推荐:基于标记窗的网页正文提取算法的一些细节问题
- [原创]修正DV拍摄时图像抖动的问题所需的算法
- 怎样提取图像像素的灰度值,色度值和饱和度值等?
- ubuntu9.04下编译android源码遇到的问题