裁剪图像周围空白区域_基于多分辨率航拍图像的房价分类神经网络-part 1

6789a014363173fe63d363a774af88b6.png

今天带来新的一个原创系列-基于航拍图像的房价分类神经网络。这是我在DFKI做的第一个小项目,虽然比较简单,但是通过这个项目我也大致了解了卫星图像分析的常用工具和一般处理流程,也实践了一下deep learning的一些模型和调参过程。不废话了,los geht‘s~

Intuitive

决定一块区域的房价因素有许多:

从房屋本身的特征

  • 房屋高度
  • 房屋朝向
  • 建筑之间的密集程度
  • 建筑的年份
  • 建筑的结构等

周围环境的影响(surroundings):

  • 周围绿植覆盖(积极特征)
  • 是否临近马路,工厂(消极特征)
  • 是否临近超市,电影院,公园,医院,车站,学校(积极特征)等

传统的估计房价的方法是搜集相关数据,例如周围区域的历史数据,再结合每个具体房产的特征(建筑年份,建筑面积,使用面积),人为的估算。这种方法虽然可以提供一个较为准确的值,但是需要耗费大量的专家知识,效率低下。于是就有如下想法:是否可以利用CNN提取从航拍图像中提取不同的图像特征,来帮助我们预测分类房价呢?

Data preprocessing

数据集总览

DFKI 提供了阿姆斯特丹2015年的整个荷兰的航拍图像,文件格式是.ecw。(吐槽一下这个文件大的一匹,一块区域就有大约20G),这个可以用来当做训练的图像。因为是个分类任务,有了图像,还需要给图像做标注,即哪些图像里的房屋是高房价,哪些是低房价,有的图片里甚至没有房屋,我们需要过滤掉这些图像。City Amsterdam项目提供了许多标注数据,包括阿姆斯特丹的房价分布,城市噪音分布,公园商店分布等。

70a654e7451ebeb54c3d86b4a07f5f50.png

图片来源:city of Amsterdam

下载下来得到的是一个shapefile。利用GIS软件QGIS可以打开可视化shapefile文件,如下:

d379301724cf0b20c13bb9afe7d3e493.png

选中,一块小的子区域,可以查看具体的标注信息:

55a01bacb9e2bab9e3787118fa89ab47.png

可以看到这块子区域的房价区间在2068-2585(因为这块区域包含多出房产)。

裁剪航拍图像

因为DFKI提供的是整个阿姆斯特丹的航拍图像,而我们只有阿姆斯特丹的各类标注信息,所以我们要裁剪航拍图像,使其成为一个一个的小块(patch),并且为每个小块,根据shapefile标注对应的房价标签。

使用gdal工具包可以方便高效的处理这种图像数据。因为提供的图像文件格式是.ecw,而我们要处理的是tiff或者png,所以首先利用gdal_translate完成这种转换。

gdal_translate -srcwin xoff yoff xsize ysize src_dataset dst_dataset

其中,-srcwin 是 “Selects a subwindow from the source image for copying based on pixel/line location.”,也就是选择srcdataset的图像(也就是我们的.ecw文件)的一块子区域,拷贝至dstdataset。需要主义的是,这个坐标的原点定义为左上角,xsize和y_size是以像素为单位的。接着利用gdal_info可以得到.ecw文件的图像信息,包括分辨率啊,坐标格式啊,边界信息等。

gdal_info ****.ecw

得到了边界信息,就可以选定步长,单个图片的大小,来裁剪航拍图像了。因为后面要利用不同分辨率的图像,所以我选择了单个像素分别为0.10m, 0.15m和0.20m的三种不同分辨率的裁剪方式。得到的图像分别如下:

d8acbfa733c8e66ff0dec6743bbe5239.png
左:单个像素0.1m ; 中:单个像素0.15m ; 右:单个像素0.20m

裁剪shapefile文件

现在需要为每个小块航拍图像制作房价标签,为此需要依照每个子块的坐标信息裁剪shapefile。可以使用ogr2ogr:

ogr2ogr -t_srs EPSG 4326 -clipdst xmin ymin xmax ymax input output

注意:这里的坐标信息是 "xmin ymin xmax ymax", 与gdal_translate的坐标输入不同。这样会得到一个个的小shapefile。然后再计算里面的标签信息,为每一个小的航拍图像标记。

label_list=[]

def label(path):
    price_list=[]
    feature = fiona.open(path)
    for i in range(len(feature)):
        x = feature[i]['properties']['SELECTIE']
        price_list.append(int(x))
    if len(price_list) == 0:
        label = 0
    else:
        label = np.mean(np.array(price_list))
    return (os.path.split(path)[1], label)


for file in os.listdir(path):
    if str(file)!='.DS_Store' and os.path.splitext(file)[-1]=='.shp':
        if len(fiona.open(os.path.join(path, file))) != 0:
            label_list.append(list(label(os.path.join(path, file))))

for item in label_list:
    if item[1]<3200:
        item[1]='low'
    else:
        item[1]='high'
  
label=open('label_line.txt','w')
label.writelines(str(label_list))
label.close()

在这里,我设置的分类阈值是3200,并且设置成二分类任务。因为图像数量有限(4000张左右)。

所有数据已经处理好了,下一期将带来训练部分。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值