def GetCorners(which_content, offset, energy_mode, img_tag, img_rgb, show=False): #滑动窗口求取梯度诶 #平均值 if energy_mode is 'mean': gradients = SlideGradient(AverageEnergy(which_content, 5, img_tag), offset) #最大值法 if energy_mode is 'max': gradients = SlideGradient(MaximalEnergy(which_content, 5, img_tag), offset) #压制非极值点点,使它们为0 peak_content = PickPeak(gradients, True) #寻找脉冲极值点的办法 temp_peak_index = [] for k in range(len(peak_content)): if peak_content[k] != 0: temp_peak_index.append(k) #极值窗口 open_length = 10 #在这个自定义区间内的都是极值 temp_peak_index.sort() #定义一个字典 #索引和周边索引的对应关系 map_index_neighbor = {} #索引和他身边被录用的索引 map_index_indexes = {} #开始创造其中元素 for this_index in temp_peak_index: #单个的索引 map_index_neighbor[this_index] = [ this_index + k for k in range(-open_length, +open_length) ] #被录用的索引(肯定有自己) map_index_indexes[this_index] = [] #判断每个索引和索隐门邻域的对应关系 for this_index in temp_peak_index: for this_neighbor in list(map_index_neighbor.values()): #判断在哪里 if this_index in this_neighbor: map_index_indexes[Dict.DictKeyOfValue( map_index_neighbor, this_neighbor)].append(this_index) #print(map_index_indexes) #真假索引了 temp_indexes = list(map_index_indexes.values()) #真实的indexes集合 indexes = [] #唯一识别 map_sum_indexes = {} #迭代合并同类项 for this_indexes in temp_indexes: indexes.append(sorted(list(set(this_indexes)))) #它们的和 map_sum_indexes[sum(indexes[-1])] = indexes[-1] #print(indexes) #print(map_sum_indexes) #用于加工的indexes列表 true_indexes = list(map_sum_indexes.values()) #求取小区间里的最大值噢 #消除偏移距之前的peak索引 peak_index = [] for this_indexes in true_indexes: #建立小区间内的索引与值的对应关系哦 map_index_value = {} for this_index in this_indexes: map_index_value[this_index] = gradients[this_index] #找到最大值噢 peak_value = np.max(list(map_index_value.values())) #获取最大值的索引 peak_index.append(Dict.DictKeyOfValue(map_index_value, peak_value)) #在gradients曲线上显示计算结果 plt.figure() plt.plot(gradients) #画出峰值点吧 for this_index in peak_index: plt.plot(this_index, gradients[this_index], marker='o', color='red') plt.axis('tight') #即将消除偏移距 map_new_old_index = Dict.SortFromStart(which_content, offset)[1] #还原到真实的叻 corner_index = [map_new_old_index[this_index] for this_index in peak_index] #在图像上还原真实的角点儿 corner_points = [which_content[this_index] for this_index in corner_index] #显示吧 if show: plt.figure() for this_pos in corner_points: Dis.ShowOnePoint(this_pos, img_rgb) return Dict.DictSortByIndex(dict(zip(corner_index, corner_points)), sorted(corner_index))
def CurvedLinesLength(which_content, map_corner_points, lines_amount, img_rgb): #按索引排序 map_corner_points = Dict.DictSortByIndex( map_corner_points, sorted(list(map_corner_points.keys()))) # print(map_corner_points) #计算出几个点的曲线距离 #索引 corner_index = list(map_corner_points.keys()) #索引列表做一下 curve_points = [] for k in range(len(corner_index)): #第一段特殊处理 if k == 0: curve_points.append(which_content[corner_index[-1]:] + which_content[:corner_index[0] + 1]) #其他正常 else: curve_points.append( which_content[corner_index[k - 1]:corner_index[k] + 1]) # print(curve_points) '''简单算法(用于检验)''' # #所有的 # curve_distances=[] # # #计算每一条曲线的曲线长度 # curve_distances=[ContinuousDistance(this_curve_points) for this_curve_points in curve_points] # # print(curve_distances) '''拾取算法''' curve_points_up_and_down = [] #获取两个点的坐标,确定两条层长线 for temp_point in plt.ginput(lines_amount): #点击获取曲线中的点的坐标并转化一下 point = [int(np.round(temp_point[1])), int(np.round(temp_point[0]))] # print(point) #多条线到这个点的距离 #以及用坐标集合当返回值 map_distance_curve_points = {} #先求每条线的中点 for this_curve_points in curve_points: #重心 center = CalculateBaryCenter(this_curve_points) #收录进映射关系 map_distance_curve_points[Distance(center, point)] = this_curve_points curve_points_up_and_down.append(map_distance_curve_points[min( list(map_distance_curve_points.keys()))]) #上下两条边的点集合 curve_points_up, curve_points_down = curve_points_up_and_down return curve_points_up, curve_points_down #上下两条边的长度 curve_length_up = ContinuousDistance(curve_points_up) curve_length_down = ContinuousDistance(curve_points_down) # print(curve_length_up) # print(curve_length_down) Dis.Line2Red(curve_points_up + curve_points_down, img_rgb) return (curve_length_up + curve_length_down) / 2
def RecoverLength(total_fractions, img_rgb, img_tag, rgb_dict, animation_show=False, show=False): #拾取出某个目标layer which_layer=Pick.PickLayer(total_fractions,img_rgb) #目标layer的edge which_edge=which_layer.edge '''HarrisM函数有问题''' #抓出几个角点 #map_corner_points=Cor.GetCorners(which_content,100,'mean',img_tag,img_rgb,True) '''层长恢复''' #节省调试时间,直接给出答案 #暴力增加角点 map_corner_points=Cor.AddCorners(which_edge,4,img_rgb,True) #初始化which_layer的角点 which_layer.corners=list(map_corner_points.values()) #计算曲线的长度 layer_length=Geom.CurvedLinesLength(which_edge,map_corner_points,2,img_rgb) #初始化面积 which_layer.InitArea() #层厚度(其实没什么意义) layer_thickness=which_layer.area/layer_length #初始化厚度和长度 which_layer.thickness=layer_thickness which_layer.length=layer_length #相关联的断层可能多个 """找出这个layer接壤的fault""" '''找到了,处理两侧都有断层的接应点情况''' which_faults=Pick.NeighborFault(which_layer,total_fractions) # print(len(which_faults)) '''一个fault的情况''' if len(which_faults)==1: #one and only which_fault=which_faults[0] #计算那几个角点哪几个离断层比较近 corner_points=list(map_corner_points.values()) #计算重心 fault_center=Geom.CalculateBaryCenter(which_fault.content) #重心到几个角点的距离 map_distances_fault2corners=Geom.DistancesMap(fault_center,corner_points) #距离最小的两个为接应点 map_attachment_points=Dict.DictSortByIndex(map_distances_fault2corners,sorted(list(map_distances_fault2corners.keys()))) #fraction上的两个接应点 fraction_attachment_points=list(map_attachment_points.values())[0:2] #fraction取两个接应点的中点 fraction_attachment_center=np.round(Geom.CalculateBaryCenter(fraction_attachment_points)).astype(int) #再去寻找fault上和接应点 map_distances_attachment2fault=Geom.DistancesMap(fraction_attachment_center,which_fault.edge) #fault上的接应点 fault_attachment_point=map_distances_attachment2fault[min(list(map_distances_attachment2fault.keys()))] #Dis.ShowOnePoint(fault_attachment_point,img_rgb) '''墙类型的填充函数(模型边界)''' #另一端的方向 directional_offset=which_layer.center[1]-fault_attachment_point[1] #边界的i坐标 i_boundary=fault_attachment_point[0] #左侧 if directional_offset<0: # directional_mode='left' #增长的方向 step_sign=+1 #边界的j坐标 j_boundary=fault_attachment_point[1]-layer_length #右侧 if directional_offset>0: # directional_mode='right' #增长的方向 step_sign=-1 #边界的坐标 j_boundary=fault_attachment_point[1]+layer_length #边界的坐标 boundary=np.round([i_boundary,j_boundary]).astype(int) #断层上接应点的索引 if fault_attachment_point in which_fault.edge: fault_attachment_index=which_fault.edge.index(fault_attachment_point) #计数器 count=1 #需要描绘的点 #第一行 points_to_draw=[[fault_attachment_point[0],j] for j in range(boundary[1],fault_attachment_point[1],step_sign)] #用于迭代的总面积 temp_area=len(points_to_draw) #循环结束的标志 flag=(temp_area>=which_layer.area) #建立一个新的tag矩阵 img_tag_temp=np.zeros(np.shape(img_tag)) #开始迭代 while not flag: #本次迭代需要画出的点 that_points_to_draw=[] count+=1 #根据count的奇偶性确定增量的符号 if count%2==0: sign=-1 if count%2==1: sign=1 #单向增量计数器 index_increment=sign*count//2 # print(index_increment) #现在的接应点 that_attachment_point=which_fault.edge[fault_attachment_index+index_increment] #计算这一次迭代面积增量 # area_increment=np.abs(that_attachment_point[1]-boundary[1]) # print(area_increment) # print(temp_area,which_fraction.area) Print=False #图像中填充新增的那一行 #根据边界与接应点的位置关系进行填充 if Print: print('right') print(that_attachment_point) # img_tag_temp[that_attachment_point[0],boundary[1]:that_attachment_point[1]]=which_fraction.tag #将这些点添加至列表 for j in range(boundary[1],that_attachment_point[1],step_sign): # print('plus',j) that_points_to_draw.append([that_attachment_point[0],j]) # print(img_tag_temp[that_attachment_point[0],boundary[1]:that_attachment_point[1]]) #加进大集合里 points_to_draw+=that_points_to_draw if animation_show: #把它们都绘制出 for this_point in points_to_draw: img_tag_temp[this_point[0],this_point[1]]=which_layer.tag #让图片停留几秒钟之后关闭,可以是整数也可以是浮点数 plt.imshow(Im.Tag2RGB(img_tag_temp,rgb_dict)) plt.pause(1) plt.close() #临时面积 temp_area=len(points_to_draw) #更新循环执行的条件 flag=(temp_area>=which_layer.area) '''多个fault的情况''' if len(which_faults)>1: #layer中点 center=np.array(which_layer.center).astype(int) #当下接应点 attachment_point=cp.deepcopy(center) '''以下内容要进入循环的噢''' #装所谓坐标的pocket pocket=[] #在layer的edge中找到一个横线确定以前的长度 for this_pos in which_layer.edge: if this_pos[0]==attachment_point[0]: pocket.append(this_pos[1]) # # #pocket中的两个接应点 # left_attachment_point=[this_pos[0],min(pocket)] # right_attachment_point=[this_pos[0],max(pocket)] # # #将这些点添加至列表 # for j in range(boundary[1],that_attachment_point[1],step_sign): # ## print('plus',j) # that_points_to_draw.append([that_attachment_point[0],j]) # # fitting_interval=FittingInterval(which_layer) #把它们都绘制出 for this_point in points_to_draw: img_tag_temp[this_point[0],this_point[1]]=which_layer.tag #显示呗 if show: plt.imshow(Im.Tag2RGB(img_tag_temp,rgb_dict)) #改变fraction的content which_layer.content=cp.deepcopy(points_to_draw) #更新which_fraction的一切? which_layer.UpdateAll() return which_layer
def InitDict(img_rgb, base_adjust=False, fault_exist=False): #临时变量 rgb_list_temp = [] for i in range(np.shape(img_rgb)[0]): for j in range(np.shape(img_rgb)[1]): if list(img_rgb[i, j].astype(int)) not in rgb_list_temp: rgb_list_temp.append(list(img_rgb[i, j].astype(int))) #判断背景色 if [255, 255, 255] in rgb_list_temp: rgb_list_temp.remove([255, 255, 255]) #只有layer的rgb layer_rgb_list = cp.deepcopy(rgb_list_temp) # print(layer_rgb_list) #fault #有断层的情况哦 if fault_exist: #各种颜色像素点数量的字典 rgb_number_dict = {} for k in range(len(rgb_list_temp)): rgb_number_dict[k] = np.sum(img_rgb == rgb_list_temp[k]) #比较像素点数量的多少 key = list(rgb_number_dict.keys()) value = list(rgb_number_dict.values()) #得到断层的rgb值 fault_rgb = rgb_list_temp[key[value.index(min(value))]] # print(fault_rgb) #删除fault的rgb layer_rgb_list.remove(fault_rgb) # print(layer_rgb_list) #生成rgb_dict,包括layer和fault rgb_dict = {} for i in range(len(layer_rgb_list)): rgb_dict[i + 1] = layer_rgb_list[i] # print(layer_rgb_list) #但是列表不可以作为索引,因此先转化为临时tag列表 tag_list = [index + 1 for index in range(len(layer_rgb_list))] #临时的tag_color索引 rgb_dict_temp = dict(zip(tag_list, layer_rgb_list)) # print(rgb_dict_temp) #比较他们的深度度 depth_list = [] for this_rgb in list(rgb_dict_temp.values()): # print(np.mean(list(np.where(img_rgb==list(this_rgb))[0]))) depth_list.append(np.mean(list( np.where(img_rgb == list(this_rgb))[0]))) # 建立颜色何深度的索引 map_tag_depth_temp = dict(zip(tag_list, depth_list)) # print(map_tag_depth_temp) #对depth进行排序 depth_list.sort() # print(depth_list) #老的tag要修改 tag_list_temp = [] #索引每一个深度值 for this_depth in depth_list: tag_list_temp.append( Dict.DictKeyOfValue(map_tag_depth_temp, this_depth)) # print(depth_list) # print(tag_list_temp) #再按照它找rgb rgb_list = [] for this_tag in tag_list_temp: rgb_list.append(rgb_dict_temp[this_tag]) #最终结果 rgb_dict = dict(zip(tag_list, rgb_list)) if fault_exist: #索引-1代表断层fault rgb_dict[-1] = fault_rgb #重新排序 rgb_dict = Dict.DictSortByIndex(rgb_dict, sorted(list(rgb_dict.keys()))) #base #调整基底哦babe if base_adjust: base_tag = list(rgb_dict.keys())[-1] # print(base_tag) base_rgb = rgb_dict[base_tag] #删除并重命名 del rgb_dict[base_tag] #base_tag的索引定义为-2 rgb_dict[-2] = base_rgb #blank if np.array([255, 255, 255]) in img_rgb: #0代表背景色 rgb_dict[0] = [255, 255, 255] #排序 rgb_dict = Dict.DictSortByIndex(rgb_dict, sorted(list(rgb_dict.keys()))) # print(rgb_dict) return rgb_dict