分享

hadoop海量图像处理

想要搭建一个hadoop平台来对大量的图像进行处理,目的就是提高处理速度,并能对处理后的数据进行进一步的分析。但刚刚接触hadoop,对它还不是很了解。有没有做过类似平台的朋友讲讲经验,或者给我指明一个方向。谢谢!

已有(14)人评论

跳转到指定楼层
jixianqiuxue 发表于 2014-11-26 16:36:52
java有图像处理方面的开源工具,然后自己结合到hadoop中看看
回复

使用道具 举报

sstutu 发表于 2014-11-26 16:41:59
目前这方面的资料很少,想学习的话,可以参考这个帖子:

hadoop图形处理文档下载
回复

使用道具 举报

nettman 发表于 2014-11-26 16:49:16




Hadoop对图像处理还是一个新兴的研究方向,我们可以从下图看出hadoop处理图像的流程:
1.png
图二   hadoop处理图像流程
1:图像文件的MapReduce数据流
MapReduce的工作过程分为两个阶段:Map阶段和Reduce阶段。如图三所示:
    用户程序直接把需要处理的图片文件对应路径告诉MapReduce框架,作为MapReduce程序的输入。ImageInputFormat对输入进行划分,ImageRecordReader对输入,进行记录读取,取得key值为ImageSplit对象的路径,value值为ImageWritable。MapReduce框架把读取的<key,value>对传递给map程序进行执行,map程序对图片进行相关操作后,利用reduce程序将处理后的图像分片进行整合,得到处理后的整个图像文件。Reduce程序将构建的对象传递给ImageOutputFormat进行输出。


2:自定义数据类型:ImageWritable类
Hadoop通过Writable对消息进行序列化。Writable接口定义了输入输入流的基本方法,MapReduce程序用他来序列化键 /值对。实验实现了自定义的ImageWritable对图像文件进行编码。
    Writable接口定义了两个方法:一个用于将其状态写入二进制格式的DataOutput流,另一个用于从二进制格式的DataInput流读取其状态。ImageWritable重写了这两个方法,分别写入和读出图片的相关数据:图片的高度和宽度,源图像的y轴高度,图像的路径和图像的像素信息。
(1)   输入格式:ImageInputFormat.ImageInputFormat继承了FileInputFormat类。FileInputFormat是所有使用文件作为数据源的InputFormat实现的基类。ImageInputFormat负责产生输入分片并将它们分割成记录。指定ImageRecordReader将输入分割成记录,用户可以定义记录的大小,他小于或等于分片ImageSplit。键是Text类型,存储该子图片在文件系统的路径。值是一个记录,它是ImageWritable类型。
(2)   记录阅读器:ImageRecordReader。Map任务使用ImageRecordReader来读取记录并且生成键/值对<Text,ImageWritable>,然后传递给mao函数。ImageRecordReader重写了RecordReader定语的所以函数。其基本构造。ImageRecordReader的nextKeyValue()方法是得到下一个键/值对,键位当前的处理的键,值通过计算得到的下一个记录要处理的图像的分片。用户可以自定义ImageWriatble的大小,ImageRecordReader的getConfig()方法用来接受用户传递的数据。Getconfig()函数主要接收3个参数:ImageWritable的大小,需要利用的相邻像素点的便边界个数和当前处理的图像是否为彩色图像。
2.png
图三MapReduce 数据流


Hadoop编码实现图像的分割
Hadoop运行中FileInputFormat都是默认一行读取的,所以必须重载文件输入流,本文中派生出JPEGFileInputFormat,JPEGFileOutputFormat文件流。
图像分割的核心代码
Mapper实现
  1. public static class MyMapper extends Mapper<ImageHeader, FloatImage,Text, IntWritable>
  2.     {
  3.        private Path path;
  4.        private FileSystem fileSystem;
  5.        private Configuration conf;
  6.                 private float red;
  7.                 private float greed;
  8.                 private float blue;
  9.                 private int width;
  10.                 private int high;
  11.                 private final static IntWritable one=new IntWritable(1);
  12.                 private Text word=new Text();
  13.        public void setup(Context jc) throws IOException
  14.        {
  15.            conf = jc.getConfiguration();
  16.            fileSystem = FileSystem.get(conf);
  17.            path = new Path( conf.get("im2gray.outdir"));
  18.            fileSystem.mkdirs(path);
  19.        }
  20.        public void map(ImageHeader key, FloatImage value, Context context) throws IOException, InterruptedException{
  21.            if (value != null) {
  22.               //FloatImage gray = value.convert(FloatImage.RGB2GRAY);
  23.                   width=value.getWidth();
  24.                                high =value.getHeight();
  25.                                for(int i=0;i<width;++i)
  26.                                   for(int j=0;j<high;++j)
  27.                                  {
  28.                              red=value.getPixel(i,j,0);
  29.                      context.write(new Text("R "+(int)(red*255+0.5)),one);
  30.                                     greed=value.getPixel(i,j,1);
  31.                      context.write(new Text("G "+(int)(red*255+0.5)),one);
  32.                                     blue=value.getPixel(i,j,2);
  33.                      context.write(new Text("B "+(int)(red*255+0.5)),one);
  34.                                   }
  35.            }
  36.            else
  37.               context.write(new Text(""), new IntWritable(0));
  38.        }
  39.     }
复制代码


Reduce实现
  1. public void reduce(Text key, Iterable<IntWritable> values, Context context)
  2.        throws IOException, InterruptedException
  3.        {
  4.                      
  5.                        int sum=0;
  6.               for (IntWritable val : values)
  7.               {      
  8.                   sum+=val.get();
  9.               }
  10.                           result.set(sum);
  11.                          context.write(key,result);
  12.       
  13.        }
  14.     }
复制代码


总的来说,本文在hadoop分布式环境中是对一个JPG进行分割读取,并统计RGB值,对统计后的结果绘制直方图。

更多内容
hadoop图像分割.rar (136.62 KB, 下载次数: 117, 售价: 2 云币)
回复

使用道具 举报

evil 发表于 2014-11-26 19:32:02
nettman 发表于 2014-11-26 16:49
Hadoop对图像处理还是一个新兴的研究方向,我们可以从下图看出hadoop处理图像的流程:
图二   hado ...

我有一些疑问。hadoop是不是还没有针对图像处理比较成熟的架构方法?整个框架的核心是在于图像分割吗?图像分割后,map中只具有部分图像信息,而之前的图像处理算法是针对整幅图像来设计的。这意味着要重新设计算法,来适应图像分割吗?
回复

使用道具 举报

evil 发表于 2014-11-26 19:35:58
jixianqiuxue 发表于 2014-11-26 16:36
java有图像处理方面的开源工具,然后自己结合到hadoop中看看

之前用java做过图像处理,很多开源工具的算法都不完善。后来专门做图像处理的同学听说我用java做图像处理。。直接把我鄙视了。。
回复

使用道具 举报

nettman 发表于 2014-11-26 19:46:17
evil 发表于 2014-11-26 19:32
我有一些疑问。hadoop是不是还没有针对图像处理比较成熟的架构方法?整个框架的核心是在于图像分割吗?图 ...


图像的处理研究的不是太深,但是个人认为既然能处理整个图像,那么处理一部分应该问题不大。直接用的话,可能会遇到问题,看看能不能做一定的转化。
回复

使用道具 举报

evil 发表于 2014-11-26 19:55:23
nettman 发表于 2014-11-26 19:46
图像的处理研究的不是太深,但是个人认为既然能处理整个图像,那么处理一部分应该问题不大。直接用的话 ...

确实可以处理部分图像,但我最终的目的是识别,分开的话可能会导致图像特征不明显,识别的准确性变低。那图像分割的意思就是把一张图分成多张图吗?图像的输入与输出都可以借用hadoop自身的方法吗?有没有需要对其进行改进的地方?
回复

使用道具 举报

nettman 发表于 2014-11-26 23:13:18
evil 发表于 2014-11-26 19:55
确实可以处理部分图像,但我最终的目的是识别,分开的话可能会导致图像特征不明显,识别的准确性变低。那 ...



对图像进行了图像分片,并非整个图片,在reduce阶段进行整合,输入输出都是使用hadoop进行的。
回复

使用道具 举报

hadoop小象 发表于 2014-11-27 11:14:25
nettman 发表于 2014-11-26 16:49
Hadoop对图像处理还是一个新兴的研究方向,我们可以从下图看出hadoop处理图像的流程:
图二   hado ...

JPEGFileInputFormat 及 RecordReader怎么实现的,有代码吗?谢谢
回复

使用道具 举报

12下一页
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

推荐上一条 /2 下一条