{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 多尺度分割" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "刘**" ] }, { "cell_type": "markdown", "metadata": { "collapsed": true }, "source": [ "```\n", "import numpy as np\n", "import gdal\n", "import pandas as pd\n", "from sklearn import svm\n", "from sklearn import naive_bayes\n", "import lightgbm as lgb\n", "import ecognition_read\n", "import optimal_scale\n", "import os\n", "\n", "\n", "class ImageClassify:\n", " '''\n", " 该程序为面向像素的图像分类程序。\n", " '''\n", "\n", " def __init__(self, train_image_path='july_06_quac.tif', train_label_path='train.dat', rootpath=r'.\\data\\img\\\\'):\n", " '''\n", " :param train_image_path: 训练数据的path\n", " :param train_label_path: 训练数据label的path\n", " :param rootpath: 存储的根目录\n", " '''\n", " # os.chdir(rootpath)\n", " self.dataset_image = gdal.Open(rootpath + train_image_path, gdal.GA_ReadOnly)\n", " self.bands = self.dataset_image.RasterCount\n", " self.xsize = self.dataset_image.RasterXSize\n", " self.ysize = self.dataset_image.RasterYSize\n", " self.image = np.zeros((self.xsize, self.ysize, self.bands))\n", " for band in range(self.bands):\n", " self.image[:, :, band] = self.dataset_image.GetRasterBand(band + 1).ReadAsArray()\n", "\n", " dataset_train = gdal.Open(rootpath + train_label_path, gdal.GA_ReadOnly)\n", " self.image_label = dataset_train.GetRasterBand(1).ReadAsArray()\n", " self.fit(self.image, self.image_label)\n", " pass\n", "\n", " def fit(self, image=None, image_label=None, clf=None):\n", " '''\n", " :param image: xsize, ysize, bands 的图像\n", " :param train_label: xsize, ysize 的label\n", " :return:\n", " '''\n", " if image is None:\n", " image = self.image\n", " if image_label is None:\n", " image_label = self.image_label\n", " image = image.reshape(-1, self.bands) # [sample_num, bands]\n", " image_label = image_label.reshape(-1) # [sample_num]\n", " loc = np.where(image_label != 0)\n", " image = image[loc, :].reshape(-1, self.bands) # [sample_num - unclassify]\n", " image_label = image_label[loc] # [sample_num - unclassify]\n", " if clf is None:\n", " self.clf = naive_bayes.GaussianNB()\n", " # self.clf = naive_bayes.BernoulliNB()\n", " # self.clf = svm.SVC()\n", " # self.clf = lgb.LGBMClassifier()\n", " else:\n", " self.clf = clf\n", " self.clf.fit(image, image_label)\n", " print(self.clf.score(image, image_label))\n", " # predict_log_proba(X)\n", " # predict_proba(X)\n", " pass\n", "\n", " def predict(self, test_image):\n", " '''\n", " 传入一个新的图像,进行预测\n", " :param test_image: 新的图像,可以理解为是其它尺度的平均光谱和特征后的图像\n", " :return: 分类图像,以及分类图像的后验概率\n", " '''\n", " assert (self.xsize, self.ysize, self.bands) == test_image.shape # 保证训练数据和测试数据的特征数目、图像大小是一样的\n", " test_image = test_image.reshape(-1, self.bands)\n", " classify_image = self.clf.predict(test_image)\n", " proba_image = self.clf.predict_proba(test_image)\n", " classify_image = classify_image.reshape(self.xsize, self.ysize)\n", " proba_image_shape = proba_image.shape\n", " proba_image = proba_image.reshape(self.xsize, self.ysize, proba_image_shape[-1])\n", " return classify_image, proba_image\n", "\n", " def write_array(self, data, path):\n", " # write_array(gl30_array_mask, r'E:\\Liulicong\\GUD scale\\data\\clip\\gl30_mask.tif', dataset_gl30)\n", " if data.dtype == 'uint8' or data.dtype == 'bool_':\n", " gdal_type = 1\n", " data = data.astype('uint8')\n", " else:\n", " gdal_type = 6\n", " data = data.astype('float32')\n", " if len(data.shape) == 2:\n", " band_num = 1\n", " else:\n", " band_num = data.shape[2]\n", " out_ds = gdal.GetDriverByName('GTiff').Create(\n", " path, data.shape[1], data.shape[0], band_num, gdal_type)\n", " out_ds.SetProjection(self.dataset_image.GetProjection())\n", " out_ds.SetGeoTransform(self.dataset_image.GetGeoTransform())\n", "\n", " print(gdal_type)\n", " print(data.dtype)\n", " if band_num == 1:\n", " out_band = out_ds.GetRasterBand(1)\n", " out_band.WriteArray(data)\n", " out_band.FlushCache()\n", " # out_ds.BuildOverviews('average', [2, 4, 8, 16, 32])\n", " del out_ds\n", " else:\n", " for i in range(band_num):\n", " out_band = out_ds.GetRasterBand(i + 1)\n", " out_band.WriteArray(data[:, :, i])\n", " out_band.FlushCache()\n", " # out_ds.BuildOverviews('average', [2, 4, 8, 16, 32])\n", " del out_ds\n", " return True\n", "\n", " def get_object_images(self, ecord: ecognition_read.ecoRead):\n", " id_images = ecord.get_id_images() # (xsize, ysize, scales)\n", " feature_dfs = ecord.get_feature_csv()\n", " self.scales = id_images.shape[-1]\n", " object_image = np.zeros((self.xsize, self.ysize, self.bands)) # 使用迭代器进行返回,以节约内存\n", " for scale_i in range(self.scales):\n", " id_image = id_images[:, :, scale_i]\n", " feature_df = feature_dfs[scale_i]\n", " object_num = np.max(id_image)\n", " assert object_num <= 65536\n", " id_image_pd = pd.DataFrame({'id': id_image.reshape(-1)}) # 为一列的pd,该列为id\n", " id_image_pd = pd.merge(id_image_pd, feature_df, on='id', how='left') # 使用pandas的链接操作可以极大的加快速度\n", " object_image = id_image_pd.iloc[:, 2:8].values.reshape(self.xsize, self.ysize, self.bands)\n", " # for i in range(object_num + 1): 循环30000次在python里面太慢了,这里考虑使用链接操作\n", " # loc = np.where(id_image == i)\n", " # object_image[loc, :] = feature_df.iloc[i, 1:7]\n", " print(object_image[200, 200, :])\n", " yield object_image, ecord.names[scale_i]\n", "\n", "\n", "if __name__ == \"__main__\":\n", " image_classify = ImageClassify()\n", " # image_classify.fit() 该类会自动调用fit算法,除非传入新的训练数据\n", " ecord = ecognition_read.ecoRead()\n", " # image, image_proba = image_classify.predict(image_classify.image)\n", " # image_classify.write_array(image, 'pixel_classify.tif')\n", " os = optimal_scale.OptimalScale()\n", " best_classify_map = os.get_class_map()\n", " image_classify.write_array(best_classify_map, 'best_classify.tif')\n", "\n", " # object_image_iteration = image_classify.get_object_images(ecord)\n", " # for object_image, sclae_name in object_image_iteration:\n", " # image, image_proba = image_classify.predict(object_image)\n", " # image_classify.write_array(image, 'level{}_classify.tif'.format(sclae_name))\n", " # image_classify.write_array(image_proba, 'level{}_proba.tif'.format(sclae_name))\n", "```" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "metadata": { "anaconda-cloud": {}, "kernelspec": { "display_name": "Python [default]", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.0" } }, "nbformat": 4, "nbformat_minor": 2 }