最近修改論文已經到了最後的關口,結果被質疑分類精度評估的方法。
我原來的方法是利用ArcGIS建立格網,格網中心點作爲我的目視解譯點,然後利用ArcGIS收集該點的影像分類結果,再把數據屬性導出用python計算混淆矩陣。
被質疑之後我使用了分層抽樣法,原理我就不贅述了,通過分層抽樣法可以計算出一幅影像每個類別需要的抽樣點爲多少。
之後在分類影像上每個類別的點隨機撒在該類別的位置,再人工目視解譯,與影像分類結果一起計算混淆矩陣即可。
我首先嚐試了Erdas,首先有着ArcGIS的電腦安裝erdas後會出現一定的問題,之後我會再寫一篇文章概述。並且最後發現erdas抽樣的點很難導入ArcGIS或者有個excel表格這樣方便計算混淆矩陣,於是我放棄了。
之後網上搜索到ArcMap 10.4以上版本可以較爲方便的,進行分層抽樣撒點,但是按照高版本的有風險,我目前用10.2
ArcGIS 10.2沒有辦法讓點能夠撒到分類影像上那一類的位置上去,但是我最後發現ENVI可以使用這個功能。
正文如下:----------------------------------------不想看我敘述的可以看這裏------------------------------
1.分類
首先我的分類結果是tif影像,1、2、3這些值來表示各個類別,tif不能直接在ENVI中進行抽樣撒點,要在ENVI中分類,採用決策樹,也就是classification-decision tree,首先先建立一個決策樹,注意這是讓你選b1的波段,先不要選,之前我選了後來換成別的影像存在錯誤。保存之後,使用classification-decision tree-execute exiting decision tree,選擇之前保存的決策樹txt。選擇你的分類結果影像,然後就可以得到分類影像。
2.抽樣撒點
使用envi的classification-post classification-generate random sample-using ground truth image
之後選擇你需要的影像,點確定
之後可以選擇類(注意這裏我給了一個類別給影像上沒有分類的,就是none,可以不選它)
點OK後,選擇分層抽樣,和diproportionnate,然後點擊set class sample sizes,就可以設定每個類別撒多少點了
其他選擇不變保存roi
之後打開影像
選擇overlay-region of interest,就可以看到生成的點(其實就是roi),注意這裏的ROI可能存在之前生成的,不是你這次的,刪掉。以下窗口選擇,選擇File-output roi to shapefile這個,
如下,選擇你需要的類別保存即可,基本是全選
3.shapefile獲取影像分類點+目視解譯
將shp文件在ArcGIS打開,之後選擇spatial analysis tools-extraction-extract values to points,選擇你的shp文件和影像,最後可以得到一個矢量文件,裏面有一欄RASTERVALU屬性就是影像的值。
之後只要打開屬性表,add field增加新的一列,作爲目視解譯的結果,然後右鍵使用柵格計算器,使它等於RASTERVALU這一列即可(這一步是爲了減小工作量,當然也可以自己賦值),然後就可以目視解譯改這個值啦。
4.計算混淆矩陣
得到目視解譯後的點的矢量文件,可以使用python打開shp文件自帶的dbf文件(其實就是屬性表)計算混淆矩陣和kappa係數即可
代碼如下
from sklearn.metrics import confusion_matrix
from sklearn.metrics import accuracy_score
from sklearn.metrics import cohen_kappa_score
from sklearn.metrics import precision_recall_fscore_support
from sklearn.metrics import classification_report
from sklearn.metrics import precision_score
from sklearn.metrics import recall_score
import pandas
import os
from dbfread import DBF
rootdir = "H:\\result_2_type\\points"
list = os.listdir(rootdir)
colnames = ['OID_', 'RASTERVALU', 'true']
true=[]
result=[]
for i in range(0,len(list)):
if not list[i].endswith(".dbf"):
continue
folder = os.path.join(rootdir,list[i])
print(folder)
table = DBF(folder, encoding='GBK')
df = pandas.DataFrame(iter(table))
result_temp = df['RASTERVALU'].tolist()
true_temp = df['true'].tolist()
score=accuracy_score(true_temp, result_temp)
print('score=',score)
kappa=cohen_kappa_score(true_temp, result_temp)
print('kappa=',kappa)
report=classification_report(true_temp, result_temp,digits=4)
print('report=',report)
true.extend(true_temp)
result.extend(result_temp)