数据处理
import numpy as np
import operator
import os
import copy
from matplotlib.font_manager import FontProperties
from scipy.interpolate import lagrange
import random
import matplotlib.pyplot as plt
import math
np.set_printoptions(suppress=True)
# 把opt文件内的逗号变为空格
#数据在我的百度云数据库txt文件,及opt文件
np.set_printoptions(threshold=np.inf) #输出全部矩阵不带省略号
random.seed(100)
##########################################
data = np.loadtxt('../txt/Vit_3Day.txt')
print(len(data))
# data = data[0:13000]#抽取一部分 # 300十类,2735 1000分类,点数270
x1 = data[:,5]#x起点坐标
x2 = data[:,9]#x终点坐标
y1 = data[:,6]#y起
y2 = data[:,10]#y起
z1 = data[:,4]#IDpart
z2 = data[:,8]#IDpart
diam = data[:,12]
s1 = [a1 for a1 in range(1,len(x1)-1) if z1[a1]==z2[a1-1]!=-1 or z1[a1]!= z2[a1-1]]#id相同不等于0,或id不同
# print(s1)
lx = []#x1,x2相同的部分组成的列表
lxqi = []
lxzg = []
for i1 in range(len(s1)-1):
b1 = x1[s1[i1]:s1[i1+1]]
b1 = b1.tolist()
b2 = x2[s1[i1+1]-1]#s1[i1]相当于a1
# b1 = b1 + [b2]#把与x2最后相连的一个数和x1拼接起来
b5 = z1[s1[i1]]#x,y起点id
b1qi_id = [b5]+b1 +[b2]
b6 = z2[s1[i1+1]-1]#x,y终点id
b1zg_id = [b6] + b1+[b2]
lx.append(b1)
lxqi.append(b1qi_id)
lxzg.append(b1zg_id)
###################################################
ly = []#y坐标以及管径大小
for i3 in range(len(s1)-1):
b3 = y1[s1[i3]:s1[i3+1]]
b3 = b3.tolist()
b4 = y2[s1[i3+1]-1]#y最后一个不相等的数
b3 = b3 + [b4]
dm = diam[s1[i3+1]-1]
b3 = b3 + [dm]#加上管径
ly.append(b3)
#####################################################
#带有起点id的x坐标与y坐标合并
for q1 in range(len(lxqi)):
for q2 in range(len(ly[q1])):
lxqi[q1].append(ly[q1][q2])
#带有终点id的x坐标与y坐标合并
for p1 in range(len(lxzg)):
for p2 in range(len(ly[p1])):
lxzg[p1].append(ly[p1][p2])
lxqi.sort(key=operator.itemgetter(0))#排序,只按照第一个索引大小排序
tou = lxqi
lxzg.sort(key=operator.itemgetter(0))
wei = lxzg
# #########################################
toudeng = []
weideng = []
for dwei in wei:
for i in range(len(tou)-1):
if dwei[0] ==tou[i][0] and dwei[0]==tou[i+1][0]:
toud = [dwei,tou[i],tou[i+1]]
toudeng.append(toud)
for dtou in tou:
for i in range(len(wei)-1):
if dtou[0] == wei[i][0] and dtou[0]==wei[i+1][0]:
weid = [wei[i],wei[i+1],dtou]
weideng.append(weid)
# ###################################################
datatoudeng = []
dataweideng = []
#去掉起点id
for i in range(len(toudeng)):
a = toudeng[i][0][1::]
b = toudeng[i][1][1::]
c = toudeng[i][2][1::]
d = [a]+[b]+[c]
datatoudeng.append(d)
for i in range(len(weideng)):
a1 = weideng[i][0][1::]
b1 = weideng[i][1][1::]
c1 = weideng[i][2][1::]
d1 = [a1]+[b1]+[c1]
dataweideng.append(d1)
####################################################################
#判断管径信息是否加进列表,若未加进则只为x,y坐标,为偶数
for i in range(len(dataweideng)):
a = dataweideng[i]
assert len(a[0])%2==1
assert len(a[1])%2==1
assert len(a[2])%2==1
for i in range(len(datatoudeng)):
a = datatoudeng[i]
assert len(a[0])%2==1
assert len(a[1])%2==1
assert len(a[2])%2==1
final_tou = datatoudeng
##############################################################################
#将尾等分叉排列方式改为,与头等分叉相同的排列方式
final_wei = []
for i in range(len(dataweideng)):
zhu = dataweideng[i][0]
zuo = dataweideng[i][1]
you = dataweideng[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_diam1 = [zhu[-1]]
zuo_diam1 = [zuo[-1]]
you_diam1 = [you[-1]]
zhu_x = zhu[0:len(zhu)//2]
zuo_x = zuo[0:len(zuo)//2]
you_x = you[0:len(you)//2]
zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
you_y = you[len(you)//2:(len(you)-1)]
#反转它们的顺序
zhu_x1 = zhu_x[::-1]
zuo_x1 = zuo_x[::-1]
you_x1 = you_x[::-1]
zhu_y1 = zhu_y[::-1]
zuo_y1 = zuo_y[::-1]
you_y1 = you_y[::-1]
zhu_x = you_x1
zuo_x = zhu_x1
you_x = zuo_x1
zhu_y = you_y1
zuo_y = zhu_y1
you_y = zuo_y1
zhu_diam = you_diam1
zuo_diam = zhu_diam1
you_diam = zuo_diam1
zhu_xy = zhu_x + zhu_y
zuo_xy = zuo_x + zuo_y
you_xy = you_x + you_y
#这里再将坐标点与管径接起来
zhu = zhu_xy + zhu_diam
zuo = zuo_xy + zuo_diam
you = you_xy + you_diam
fencha = [zhu] + [zuo] + [you]
final_wei.append(fencha)
# 这里是将分叉和汇聚都加在了一起
# final = final_tou + final_wei
# 若想把分叉和汇聚分开,则单独提取即可
final = final_tou
############################################################################
# 将所有的分叉主分支反转
final_zhu_reversed = []
for i in range(len(final)):
zhu = final[i][0]
zuo = final[i][1]
you = final[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_x = zhu[0:len(zhu)//2]
zuo_x = zuo[0:len(zuo)//2]
you_x = you[0:len(you)//2]
zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
you_y = you[len(you)//2:(len(you)-1)]
#反转它们的顺序
zhu_x1 = zhu_x[::-1]
zhu_y1 = zhu_y[::-1]
zhu_x = zhu_x1
zhu_y = zhu_y1
zhu_xy = zhu_x + zhu_y
zuo_xy = zuo_x + zuo_y
you_xy = you_x + you_y
#这里再将坐标点与管径接起来
zhu = zhu_xy + zhu_diam
zuo = zuo_xy + zuo_diam
you = you_xy + you_diam
fencha = [zhu] + [zuo] + [you]
final_zhu_reversed.append(fencha)
final = final_zhu_reversed
############################################################################
# 可视化数据
# data = final
# for i in range(len(data)):
# zhu = data[i][0]
# zuo = data[i][1]
# you = data[i][2]
# print(zhu)
# print(zuo)
# print(you)
# zhu_diam = [zhu[-1]]
# zuo_diam = [zuo[-1]]
# you_diam = [you[-1]]
# zhu_x = zhu[0:len(zhu)//2]
# zuo_x = zuo[0:len(zuo)//2]
# you_x = you[0:len(you)//2]
# zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
# zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
# you_y = you[len(you)//2:(len(you)-1)]
# # print(zhu_x)
# # print(zuo_x)
# # print(you_x)
# print("下一个")
##############################################################################
#去除重复的点(包括头部相等和尾部相等)
final1 = []
for i in range(len(final)):
zhu = final[i][0]
zuo = final[i][1]
you = final[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_x = zhu[0:len(zhu)//2]
zuo_x = zuo[0:len(zuo)//2]
you_x = you[0:len(you)//2]
zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
you_y = you[len(you)//2:(len(you)-1)]
###########################################
#前后不相等加进数组,最后再接上原始数组的最后一个
zhu_x1 = []
zhu_y1 = []
for j in range(len(zhu_x)-1):
if zhu_x[j] != zhu_x[j+1] or zhu_y[j] != zhu_y[j+1]:
zhu_x1.append(zhu_x[j])
zhu_y1.append(zhu_y[j])
zhu_x1.append(zhu_x[-1])
zhu_y1.append(zhu_y[-1])
zuo_x1 = []
zuo_y1 = []
for j in range(len(zuo_x)-1):
if zuo_x[j] != zuo_x[j+1] or zuo_y[j] != zuo_y[j+1]:
zuo_x1.append(zuo_x[j])
zuo_y1.append(zuo_y[j])
zuo_x1.append(zuo_x[-1])
zuo_y1.append(zuo_y[-1])
you_x1 = []
you_y1 = []
for j in range(len(you_x)-1):
if you_x[j] != you_x[j+1] or you_y[j] != you_y[j+1]:
you_x1.append(you_x[j])
you_y1.append(you_y[j])
you_x1.append(you_x[-1])
you_y1.append(you_y[-1])
###########################################
zhu_xy = zhu_x1 + zhu_y1
zuo_xy = zuo_x1 + zuo_y1
you_xy = you_x1 + you_y1
#这里再将坐标点与管径接起来
zhu = zhu_xy + zhu_diam
zuo = zuo_xy + zuo_diam
you = you_xy + you_diam
fencha = [zhu] + [zuo] + [you]
final1.append(fencha)
final = final1
############################################################################
#可视化数据,观察哪些数据
# for i in range(len(final)):
# print("第%d个分叉" %i)
# for j in range(len(final[i])):
# print(final[i][j])
# print("**********************")
##############################################################################
#观察每一个分支有多少个坐标点,算上管径最多59,最少为7
axis_num_list = []
extract = []
for i in range(len(final)):
for j in range(len(final[i])):
axis_num = len(final[i][j])
axis_num_list.append(axis_num)
for file in axis_num_list:
if file < 33 :
extract.append(file)
print(len(axis_num_list))
print(len(extract))
print(max(axis_num_list))
##################################################################################
# # 挑选出每个分支小于20个数的分叉
# select_final = []
# for i in range(len(final)):
# point_num = 11
# if len(final[])
# print("下一个")
######################################################################################
# 挑选出每个分支小于33个数的分叉,x,y坐标个数分别为16,管径为1,这些点一个2830个,小于等于33的有2738个
select_final = []
for i in range(len(final)):
point_num = 33
if len(final[i][0]) <= point_num and len(final[i][1]) <= point_num and len(final[i][2]) <= point_num:
select_final.append(final[i])
print("所有分叉:" ,len(final))
print("点数小于33分叉 : " , len(select_final))
final = select_final
#################################################################################
#计算两点之间距离
def get_len(x1,x2,y1,y2):
diff_x = (x1-x2)**2
diff_y = (y1-y2)**2
length = np.sqrt(diff_x+diff_y)
return length
###########################################################################
#旋转数据
def rotate(angle,valuex,valuey):
valuex = np.array(valuex)
valuey = np.array(valuey)
rotatex = math.cos(angle)*valuex - math.sin(angle)*valuey
rotatey = math.cos(angle)*valuey + math.sin(angle)*valuex
rotatex = rotatex.tolist()
rotatey = rotatey.tolist()
return rotatex, rotatey
final2 = []
for i in range(len(final)):
zhu = final[i][0]
zuo = final[i][1]
you = final[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_x = zhu[0:len(zhu)//2]
zuo_x = zuo[0:len(zuo)//2]
you_x = you[0:len(you)//2]
zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
you_y = you[len(you)//2:(len(you)-1)]
###########################################################
#插值 最长为59,x,y为29
insert_num = 16
print(i)
while len(zhu_x)< insert_num:
zhu_lin_list = []
for j in range(1,len(zhu_x)):
zhu_lin_len = get_len(zhu_x[j-1],zhu_x[j],zhu_y[j-1],zhu_y[j])
zhu_lin_list.append(zhu_lin_len)
zhu_max_index = zhu_lin_list.index(max(zhu_lin_list)) #j-1
#不处理的话会出现nan
if abs(zhu_x[zhu_max_index]-zhu_x[zhu_max_index+1])==0:
zhu_x[zhu_max_index+1] = zhu_x[zhu_max_index+1] +1
zhu_insert_x = np.linspace(zhu_x[zhu_max_index],zhu_x[zhu_max_index+1],3)
#插入的点
zhu_insert_x = zhu_insert_x[1]
f_zhu = lagrange([zhu_x[zhu_max_index],zhu_x[zhu_max_index+1]],[zhu_y[zhu_max_index],zhu_y[zhu_max_index+1]])
zhu_insert_y = f_zhu(zhu_insert_x)
zhu_x.insert(zhu_max_index+1,zhu_insert_x)
zhu_y.insert(zhu_max_index+1,zhu_insert_y)
while len(zuo_x) < insert_num:
zuo_lin_list = []
for j in range(1,len(zuo_x)):
zuo_lin_len = get_len(zuo_x[j-1],zuo_x[j],zuo_y[j-1],zuo_y[j])
zuo_lin_list.append(zuo_lin_len)
zuo_max_index = zuo_lin_list.index(max(zuo_lin_list)) #对应j-1
if abs(zuo_x[zuo_max_index]-zuo_x[zuo_max_index+1])==0:
zuo_x[zuo_max_index+1] = zuo_x[zuo_max_index+1] + 1
zuo_insert_x = np.linspace(zuo_x[zuo_max_index],zuo_x[zuo_max_index+1],3)
# #插入的点
zuo_insert_x = zuo_insert_x[1]
f_zuo = lagrange([zuo_x[zuo_max_index],zuo_x[zuo_max_index+1]],[zuo_y[zuo_max_index],zuo_y[zuo_max_index+1]])
zuo_insert_y = f_zuo(zuo_insert_x)
zuo_x.insert(zuo_max_index+1,zuo_insert_x)
zuo_y.insert(zuo_max_index+1,zuo_insert_y)
while len(you_x) < insert_num:
you_lin_list = []
for j in range(1,len(you_x)):
#计算相邻两坐标的距离
you_lin_len = get_len(you_x[j-1],you_x[j],you_y[j-1],you_y[j])
#添加进列表中
you_lin_list.append(you_lin_len)
#计算距离最大的值对应的索引,对应x坐标的j-1和j之间的距离,最大
you_max_index = you_lin_list.index(max(you_lin_list)) #对应j-1
#然后,在两个最大点之间,平均插入一个数,作为插入x点
if abs(you_x[you_max_index]-you_x[you_max_index+1]) == 0:
you_x[you_max_index+1] = you_x[you_max_index+1] + 1
you_insert_x = np.linspace(you_x[you_max_index],you_x[you_max_index+1],3)
#插入的点
you_insert_x = you_insert_x[1]
#拉格朗日计算直线方程
f_you = lagrange([you_x[you_max_index],you_x[you_max_index+1]],[you_y[you_max_index],you_y[you_max_index+1]])
#插入的y点
you_insert_y = f_you(you_insert_x)
#将求得的x,y点插入对应位置
you_x.insert(you_max_index+1,you_insert_x)
you_y.insert(you_max_index+1,you_insert_y)
##############################################################################
rotatedata = []
# 在这里分类,不一定非要360度
for j in range(0,360,1):
zhu_rotatex, zhu_rotatey = rotate(j,zhu_x,zhu_y)
zuo_rotatex, zuo_rotatey = rotate(j,zuo_x,zuo_y)
you_rotatex, you_rotatey = rotate(j,you_x,you_y)
rotatex = zhu_rotatex + zuo_rotatex + you_rotatex
rotatey = zhu_rotatey + zuo_rotatey + you_rotatey
#将列表变为数组方便后面进行加减运算
zhu_rotatex = np.array(zhu_rotatex)
zuo_rotatex = np.array(zuo_rotatex)
you_rotatex = np.array(you_rotatex)
zhu_rotatey = np.array(zhu_rotatey)
zuo_rotatey = np.array(zuo_rotatey)
you_rotatey = np.array(you_rotatey)
#将旋转后的分叉,移到第一象限,x,y最小值都为0
zhu_rotatex = zhu_rotatex - min(rotatex)
zuo_rotatex = zuo_rotatex - min(rotatex)
you_rotatex = you_rotatex - min(rotatex)
zhu_rotatey = zhu_rotatey - min(rotatey)
zuo_rotatey = zuo_rotatey - min(rotatey)
you_rotatey = you_rotatey - min(rotatey)
#再将数组变为列表方便拼接
zhu_rotatex = zhu_rotatex.tolist()
zuo_rotatex = zuo_rotatex.tolist()
you_rotatex = you_rotatex.tolist()
zhu_rotatey = zhu_rotatey.tolist()
zuo_rotatey = zuo_rotatey.tolist()
you_rotatey = you_rotatey.tolist()
#######################################
#可视化旋转效果
# plt.scatter(zhu_rotatex,zhu_rotatey)
# plt.scatter(zuo_rotatex,zuo_rotatey)
# plt.scatter(you_rotatex,you_rotatey)
# plt.xlim(0,1000)
# plt.ylim(0,1000)
# plt.show()
##########################################
zhu_rotatexy = zhu_rotatex + zhu_rotatey
zuo_rotatexy = zuo_rotatex + zuo_rotatey
you_rotatexy = you_rotatex + you_rotatey
#这里再将坐标点与管径接起来
zhu_rotate = zhu_rotatexy + zhu_diam
zuo_rotate = zuo_rotatexy + zuo_diam
you_rotate = you_rotatexy + you_diam
fencha = [zhu_rotate] + [zuo_rotate] + [you_rotate]
rotatedata.append(fencha)
final2.append(rotatedata)
final = []
for file in final2:
for data in file:
final.append(data)
####################################################################
all_point = []
all_diam = []
#找出来final中的最大值和最小值,方便后面进行归一化
for i in range(len(final)):
zhu = final[i][0]
zuo = final[i][1]
you = final[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_x = zhu[0:len(zhu)//2]
zuo_x = zuo[0:len(zuo)//2]
you_x = you[0:len(you)//2]
zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
you_y = you[len(you)//2:(len(you)-1)]
all_xy = zhu_x + zhu_y + zuo_x + zuo_y + you_x + you_y
diam = zhu_diam + zuo_diam + you_diam
for file in all_xy:
all_point.append(file)
for file in diam:
all_diam.append(file)
max_point = max(all_point)
min_point = min(all_point)
#########################################################################
# 将数据分成几个部分
final1 = []
final2 = []
for i in range(len(final)):
zhu = final[i][0]
zuo = final[i][1]
you = final[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_x = zhu[0:len(zhu)//2]
zuo_x = zuo[0:len(zuo)//2]
you_x = you[0:len(you)//2]
zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
you_y = you[len(you)//2:(len(you)-1)]
all_xy = zhu_x + zhu_y + zuo_x + zuo_y + you_x + you_y
if max(all_xy) < 270:
final1.append(final[i])
elif 270 <= max(all_xy) <= max_point:
final2.append(final[i])
print("final分叉:", len(final))
print("final1分叉: ",len(final1))
print("final2分叉: ",len(final2))
#########################################################################
#对所有的管径取log
all_diam = np.array(all_diam)
all_diam = np.log(all_diam)
max_diam = max(all_diam)
min_diam = min(all_diam)
print('max_point:',max_point)
print('min_point:',min_point)
print('max_diam:',max_diam)
print('min_diam:',min_diam)
###################################################################
#对坐标点和管径进行归一处理
select_final1 = True
# 加5或10的目的,是为了不让他们归一化后有等于1的值,只是靠近1,方便后面提取坐标
if select_final1:
final = final1
max_point = 270
else:
final = final2
max_point = max_point
print('max_point/3: ',max_point)
print('min_point/3: ',min_point)
final_norm = []
for i in range(len(final)):
zhu = final[i][0]
zuo = final[i][1]
you = final[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_xy = final[i][0][0:-1]
zuo_xy = final[i][1][0:-1]
you_xy = final[i][2][0:-1]
#列表变为数组
zhu_xy = np.array(zhu_xy)
zuo_xy = np.array(zuo_xy)
you_xy = np.array(you_xy)
#对坐标点进行归一化
norm_zhu_xy = zhu_xy / max_point
norm_zuo_xy = zuo_xy / max_point
norm_you_xy = you_xy / max_point
#将坐标点变为列表
norm_zhu_xy = norm_zhu_xy.tolist()
norm_zuo_xy = norm_zuo_xy.tolist()
norm_you_xy = norm_you_xy.tolist()
#对管径进行归一化
norm_zhu_diam = [(math.log(zhu[-1]) - min_diam)/(max_diam - min_diam)]
norm_zuo_diam = [(math.log(zuo[-1]) - min_diam)/(max_diam - min_diam)]
norm_you_diam = [(math.log(you[-1]) - min_diam)/(max_diam - min_diam)]
norm_zhu = norm_zhu_xy + norm_zhu_diam
norm_zuo = norm_zuo_xy + norm_zuo_diam
norm_you = norm_you_xy + norm_you_diam
norm = [norm_zhu] + [norm_zuo] + [norm_you]
final_norm.append(norm)
final = final_norm
###########################################################################
#将在0-1角落的分叉移到0-1的中间
finaldata = []
for i in range(len(final)):
zhu = final[i][0]
zuo = final[i][1]
you = final[i][2]
zhu_diam = [zhu[-1]]
zuo_diam = [zuo[-1]]
you_diam = [you[-1]]
zhu_x = zhu[0:len(zhu)//2]
zuo_x = zuo[0:len(zuo)//2]
you_x = you[0:len(you)//2]
zhu_y = zhu[len(zhu)//2:(len(zhu)-1)]
zuo_y = zuo[len(zuo)//2:(len(zuo)-1)]
you_y = you[len(you)//2:(len(you)-1)]
######################################################################
#平移之前可视化分叉图
# print(zhu_x,zhu_y)
# print(zuo_x,zuo_y)
# print(you_x,you_y)
# plt.plot(zhu_x,zhu_y)
# plt.plot(zuo_x,zuo_y)
# plt.plot(you_x,you_y)
# plt.xlim(0.,1.)
# plt.ylim(0.,1.)
# plt.show()
######################################################################
x = zhu_x + zuo_x + you_x
y = zhu_y + zuo_y + you_y
# x,y要移的大小
translation_x = (1. - max(x)) / 2
translation_y = (1. - max(y)) / 2
zhu_x = np.array(zhu_x) + translation_x
zuo_x = np.array(zuo_x) + translation_x
you_x = np.array(you_x) + translation_x
zhu_y = np.array(zhu_y) + translation_y
zuo_y = np.array(zuo_y) + translation_y
you_y = np.array(you_y) + translation_y
#再将x,y坐标变为列表
zhu_x = zhu_x.tolist()
zuo_x = zuo_x.tolist()
you_x = you_x.tolist()
zhu_y = zhu_y.tolist()
zuo_y = zuo_y.tolist()
you_y = you_y.tolist()
###################################################################
#平移之后可视化分叉图
# print(zhu_x,zhu_y)
# print(zuo_x,zuo_y)
# print(you_x,you_y)
# plt.plot(zhu_x,zhu_y)
# plt.plot(zuo_x,zuo_y)
# plt.plot(you_x,you_y)
# plt.xlim(0.,1.)
# plt.ylim(0.,1.)
# plt.show()
#####################################################################
#在此改变要补充的值,与排列的顺序
#每个分支个数不一样,在每个分支x,y坐标后补1,然后单独的一个管径后面也补1,最后合在一块的管径不1,都到30
insert_zhu_diam = zhu_diam + [1.] * (insert_num - len(zhu_diam))
insert_zuo_diam = zuo_diam + [1.] * (insert_num - len(zuo_diam))
insert_you_diam = you_diam + [1.] * (insert_num - len(you_diam))
diam = zhu_diam + zuo_diam + you_diam
insert_diam = diam + [1.] * (insert_num - len(diam))
insert = [zhu_x] + [zuo_x] + [you_x] + [zhu_y] + [zuo_y] + [you_y] + [insert_zhu_diam] + [insert_zuo_diam] +[insert_you_diam] + [insert_diam]
finaldata.append(insert)
finaldata = np.array((finaldata))
ones = np.ones((len(finaldata),6,16))
finaldata = np.concatenate((finaldata,ones),1)
finaldata = finaldata.reshape(-1,16,16)
# np.random.shuffle(finaldata)
################################################################################
# 按每张图片进行打标签
label = 0
final_label = []
for i in range(len(finaldata)-1):
if finaldata[i][9].tolist() == finaldata[i+1][9].tolist():
final_label.append((finaldata[i],label))
if finaldata[i][9].tolist() != finaldata[i+1][9].tolist():
final_label.append((finaldata[i],label))
label = label + 1
# 加上最后一个
if i == (len(finaldata)-2):
final_label.append((finaldata[i+1],label))
finaldata = np.array(final_label)
print(finaldata.shape)
##################################################################################
# 保存与加载数据与标签
np.save('../data/单张图1000分类.npy',finaldata)
# print("完成")
# finaldata = np.load('data/data.npy')
# finallabel = np.load('data/label.npy')
##################################################################################
# 分离标签和数据
def input_data(finaldata):
data = []
label = []
for i in range(len(finaldata)):
data.append(finaldata[i][0])
label.append(finaldata[i][1])
data = np.array(data)
label = np.array(label)
return data, label
finaldata,datalabel = input_data(finaldata)
print(finaldata.shape)
print(datalabel.shape)
print(len(datalabel))
# 最大类别
print(np.max(datalabel))
##################################################################################
def save_images(finaldata):
# 挑选出坐标点,并可视化
# (-1,10,10)
finaldata = finaldata.reshape(-1,16,16)
for i in range(len(finaldata)):
zhu_x = finaldata[i][0]
zuo_x = finaldata[i][1]
you_x = finaldata[i][2]
zhu_y = finaldata[i][3]
zuo_y = finaldata[i][4]
you_y = finaldata[i][5]
zhu_diam = finaldata[i][6][0]
zuo_diam = finaldata[i][7][0]
you_diam = finaldata[i][8][0]
ori_zhu_diam = (max_diam - min_diam) * zhu_diam + min_diam
ori_zuo_diam = (max_diam - min_diam) * zuo_diam + min_diam
ori_you_diam = (max_diam - min_diam) * you_diam + min_diam
plt.scatter(zhu_x,zhu_y, color='red', linewidth=ori_zhu_diam)
plt.scatter(zuo_x,zuo_y, color='green', linewidth=ori_zuo_diam)
plt.scatter(you_x,you_y, color='blue', linewidth=ori_you_diam)
plt.xlim(0.,1.)
plt.ylim(0.,1.)
# plt.savefig("C:\\Users\\Administrator\\Desktop\\a\\%d.jpg" %i)
# plt.close()
plt.show()
#####################################################################################
# save_images(finaldata)
分为训练集和测试集
import numpy as np
import tensorflow as tf
import matplotlib.pyplot as plt
data = np.load("../data/单张图1000分类.npy")
# 先打乱一下数据
np.random.shuffle(data)
print(data.shape)
# 剩下得做为验证集
data_val = data[230000::,:]
# 每类挑出十万个作为训练集
data = data[0:230000,:]
np.random.shuffle(data)
print(data[0])
print(data.shape)
print(data_val.shape)
###########################################################################
np.save('../data/单张999分类训练集.npy',data)
np.save('../data/单张999分类测试集.npy',data_val)
############################################################################
# 分离数据与标签
def input_data(finaldata):
data = []
label = []
for i in range(len(finaldata)):
data.append(finaldata[i][0])
label.append(finaldata[i][1])
data = np.array(data)
label = np.array(label)
return data, label
finaldata,datalabel = input_data(data)
# print(finaldata.shape)
# print(datalabel.shape)
##################################################################################
def save_images(finaldata):
# 挑选出坐标点,并可视化
# (-1,10,10)
finaldata = finaldata.reshape(-1,16,16)
for i in range(len(finaldata)):
zhu_x = finaldata[i][0]
zuo_x = finaldata[i][1]
you_x = finaldata[i][2]
zhu_y = finaldata[i][3]
zuo_y = finaldata[i][4]
you_y = finaldata[i][5]
zhu_diam = finaldata[i][6][0]
zuo_diam = finaldata[i][7][0]
you_diam = finaldata[i][8][0]
plt.scatter(zhu_x,zhu_y, color='red')
plt.scatter(zuo_x,zuo_y, color='green')
plt.scatter(you_x,you_y, color='blue')
plt.xlim(0.,1.)
plt.ylim(0.,1.)
# plt.savefig("C:\\Users\\Administrator\\Desktop\\a\\%d.jpg" %i)
# plt.close()
plt.show()
#####################################################################################
# save_images(finaldata)
模型训练
import tensorflow as tf
import numpy as np
import os
np.set_printoptions(threshold=np.inf)
#######################################################################
# 读取数据和标签
finaldata = np.load("../data/999.npy") # 316, 999
finalval = np.load("../data/单张999分类测试集.npy") # 316, 999
np.random.seed(1000)
np.random.shuffle(finaldata)
np.random.shuffle(finalval)
########################################################################
# 超参数
batch_size = 100
learning_rate = 0.001
epochs = 10000
n_class = 999
#######################################################################
# 用numpy进行one_hot编码
def np_one_hot(labels):
n_labels = np.max(labels) + 1
one_hot = np.eye(n_labels)[labels]
return one_hot
######################################################################
# 将数据与标签分离,并对标签进行one_hot编码
def input_data(finaldata):
data = []
label = []
for i in range(len(finaldata)):
data.append(finaldata[i][0])
label.append(finaldata[i][1])
data = np.array(data)
data = data.reshape(-1,16,16,1)
label = np.array(label)
label = np_one_hot(label)
return data, label
# 训练集
data, label = input_data(finaldata)
# 测试集
data_val, label_val = input_data(finalval)
###########################################################################
# 排除管径对分类的影响
ones = np.ones((len(data),10,16,1))
data[:,6::,:,:] = ones
val_ones = np.ones((len(data_val),10,16,1))
data_val[:,6::,:,:] = val_ones
###########################################################################
# 得到batch个数据
# 有数据有label时
def get_batch(inputs=None, labels=None, batch_size=None, shuffle=True):
assert len(inputs) == len(labels)
indices = np.arange(len(inputs))
if shuffle:
np.random.shuffle(indices)
# start_idx为batch_size个数
for start_idx in range(0, len(inputs) -batch_size + 1, batch_size):
if shuffle:
excerpt = indices[start_idx:start_idx + batch_size]
else:
excerpt = indices[start_idx:start_idx + batch_size]
yield inputs[excerpt] , labels[excerpt]
#####################################################################
def inference(images):
# conv1 16x16x1->16x16x96
with tf.variable_scope("conv1") as scope:
weights = tf.get_variable("weights",
shape = [3, 3, 1, 96],
dtype = tf.float32,
initializer = tf.truncated_normal_initializer(stddev=0.05,dtype=tf.float32))
biases = tf.get_variable("biases",
shape = [96],
dtype = tf.float32,
initializer = tf.constant_initializer(0.0))
conv = tf.nn.conv2d(images, weights, strides=[1, 1, 1, 1], padding="SAME")
pre_activation = tf.nn.bias_add(conv, biases)
conv1 = tf.nn.relu(pre_activation, name=scope.name)
# pool1 and norm1 16x16x96->8x8x96
with tf.variable_scope("pooling1_lrn") as scope:
pool1 = tf.nn.max_pool(conv1, ksize=[1, 3, 3, 1], strides=[1, 2, 2 ,1],
padding="SAME", name="pooing1")
norm1 = tf.nn.lrn(pool1, depth_radius=4, bias=1.0, alpha=0.001/9.0,
beta=0.75, name="norm1")
# conv2 8x8x96->8x8x64
with tf.variable_scope("conv2") as scope:
weights = tf.get_variable("weights",
shape = [3, 3, 96, 64],
dtype = tf.float32,
initializer = tf.truncated_normal_initializer(stddev=0.05,dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[64],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
conv = tf.nn.conv2d(norm1, weights, strides=[1,1,1,1],padding='SAME')
pre_activation = tf.nn.bias_add(conv, biases)
conv2 = tf.nn.relu(pre_activation, name='conv2')
#pool2 and norm2 8x8x64->4x4x64
with tf.variable_scope('pooling2_lrn') as scope:
norm2 = tf.nn.lrn(conv2, depth_radius=4, bias=1.0, alpha=0.001/9.0,
beta=0.75,name='norm2')
pool2 = tf.nn.max_pool(norm2, ksize=[1,3,3,1], strides=[1,1,1,1],
padding='SAME',name='pooling2')
print(pool2.shape)
# fc3
with tf.variable_scope("fc3") as scope:
reshape = tf.reshape(pool2, shape=[-1, 8*8*64])
print(reshape.shape)
dim = reshape.get_shape()[1].value
weights = tf.get_variable("weights",
shape=[dim, 512],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.004,dtype=tf.float32))
biases = tf.get_variable("biases",
shape=[512],
dtype = tf.float32,
initializer = tf.constant_initializer(0.1) )
fc3 = tf.nn.relu(tf.matmul(reshape,weights) + biases, name=scope.name)
# fc4
with tf.variable_scope('fc4') as scope:
weights = tf.get_variable('weights',
shape=[512,256],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.004,dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[256],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
local4 = tf.nn.relu(tf.matmul(fc3, weights) + biases, name='fc4')
# softmax
with tf.variable_scope('softmax_linear') as scope:
weights = tf.get_variable('softmax_linear',
shape=[256, n_class],
dtype=tf.float32,
initializer=tf.truncated_normal_initializer(stddev=0.004,dtype=tf.float32))
biases = tf.get_variable('biases',
shape=[n_class],
dtype=tf.float32,
initializer=tf.constant_initializer(0.1))
softmax_linear = tf.add(tf.matmul(local4, weights), biases, name='softmax_linear')
return softmax_linear
######################################################################
# loss函数
def losses(logits, labels):
with tf.variable_scope('loss') as scope:
# to use this loss fuction, one-hot encoding is needed!
cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=logits, labels=labels, name='xentropy_per_example')
loss = tf.reduce_mean(cross_entropy, name='loss')
if not os.path.exists('loss'):
os.makedirs('loss')
tf.summary.scalar(scope.name+'/loss', loss)
return loss
###################################################################################
images = tf.placeholder(tf.float32,[None, 16, 16, 1])
labels = tf.placeholder(tf.float32,[None, n_class])
####################################################################################
# 训练模型
def train():
my_global_step = tf.Variable(0, name='global_step', trainable=False)
logits = inference(images)
prediction = tf.nn.softmax(logits)
correct_prediction = tf.equal(tf.argmax(prediction,1),tf.argmax(labels,1))
# loss值
loss = losses(logits, labels)
# 准确率
accuracy = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
train_op = tf.train.AdamOptimizer(learning_rate).minimize(loss, global_step = my_global_step)
saver = tf.train.Saver(tf.global_variables())
summary_op = tf.summary.merge_all()
sess = tf.Session()
sess.run(tf.global_variables_initializer())
if not os.path.exists('logs'):
os.makedirs('logs')
summary_writer = tf.summary.FileWriter('logs',sess.graph)
for e in range(epochs):
for data_batch,label_batch in get_batch(data,label,batch_size):
_, loss_value ,train_accuracy_value= sess.run([train_op, loss, accuracy], feed_dict={images:data_batch,labels:label_batch})
# 测试机准确率
test_accuraccy_value = sess.run(accuracy,feed_dict={images:data_val,labels:label_val})
print("第%d个epoch: , loss: %.4f, train_accuracy: %.4f, test_accuracy: %.4f" % (e, loss_value, train_accuracy_value,test_accuraccy_value))
if e % 3 ==0:
summary_str = sess.run(summary_op, feed_dict={images:data_batch, labels:label_batch})
summary_writer.add_summary(summary_str, e)
saver.save(sess,"checkpoints/model.ckpt", global_step=e)
sess.close()
train()
def evaluate():
logits = inference(images)
# softmax变为概率,若预测正确,其中最大值接近1
prediction = tf.nn.softmax(logits)
# 预测的最大值的索引,也即使哪一类
prediction_max = tf.argmax(prediction,1)
# 真实的label
label_max = tf.argmax(labels,1)
# 为布尔值
correct_prediction = tf.equal(tf.argmax(prediction,1),tf.argmax(labels,1))
# 将布尔值变为小数
accuracy_arr = tf.cast(correct_prediction, tf.float32)
# 取这一批的ping'jun'zhi
# accuracy_arr = tf.reduce_mean(tf.cast(correct_prediction,tf.float32))
with tf.Session() as sess:
saver = tf.train.Saver(tf.global_variables())
saver.restore(sess, tf.train.latest_checkpoint("checkpoints"))
for test_data, test_label in get_batch(data_val, label_val, 1):
prediction_index,label_index,acc = sess.run([prediction_max,label_max,accuracy_arr],feed_dict={images:test_data,labels:test_label})
prob = acc[0]
print("prob: %.4f " % prob," pre_index:",prediction_index," label_index:",label_index)
# evaluate()