代码如下:
import math
import cv2
import numpy as np
#二分法查找数据的位置
def finddata(d1,list1,i):#i=0,1
d1=d1[i]
list_index_min = 0
list_index_max = len(list1) - 1
if d1<=list1[list_index_min][i]:
return list_index_min
elif d1>=list1[list_index_max][i]:
return list_index_max
else:
s=-1
while list_index_min <= list_index_max:
list_index_middle = (list_index_min + list_index_max) // 2
if list1[list_index_middle][i] < d1:
list_index_min = list_index_middle + 1
elif list1[list_index_middle][i] > d1:
list_index_max = list_index_middle - 1
else:
s=list_index_middle
break
if s==-1:
return list_index_min-1
else:
return s
#1.数据处理,将数据处理为二维数组=======>[(0, 3), (1, 1), (1, 2),........, (1, 3), (1, 4), (1, 5)]
def data_set(data):
list=[]
for i in range(len(data)):
for j in range(len(data[0])):
if data[i][j]!=0:
list.append((i,j))
return list
#2.将1的数组转换为字典,方便后续寻找同类的点
#注意:有两个字典,一个的键是按照行从小到达排列,另一个的键按照列从小到达排列,返回值如下
#dic1 {'0': [(0, 3)], '1': [(1, 1), (1, 2), (1, 3), (1, 4), (1, 5)], '2': [(2, 1), (2, 2), (2, 3), (2, 4), (2, 5)],.........]
#dic2 {'0': [(3, 0)], '1': [(1, 1), (2, 1), (3, 1), (4, 1), (5, 1)], '2': [(1, 2), (2, 2), (3, 2), (4, 2), (5, 2)],.........]
def dic1_dic2(datas):
# 1.对数组分别按照行列进行排序,原数组是按照行排序
datas=sorted(datas)
data_over = sorted(datas, key=lambda x: x[1])
# 2.获得两个行和列从小到达排列的字典
dic1 = {}
dic2 = {}
for item in datas:
if str(item[0]) not in dic1:
dic1[str(item[0])]=[]
dic1[str(item[0])].append(item)
else:
dic1[str(item[0])].append(item)
for item in data_over:
if str(item[1]) not in dic2:
dic2[str(item[1])]=[]
dic2[str(item[1])].append(item)
else:
dic2[str(item[1])].append(item)
return dic1,dic2
#3.获取dic1的第一个键的第一个元素,放入新的字典sigle_dic_class1和sigle_dic_class2,如(0,3)一个的键为0,另一个的键为3
def dic_get_value1(dic1):
#1.获得字典dic1的键值
dic1_key =list(dic1.keys())
sigle_dic_class1 = {}
# 将dic1的第一个元素设为新的类的第一个元素
sigle_dic_class1[dic1_key[0]] = []
sigle_dic_class1[dic1_key[0]].append(dic1[dic1_key[0]][0])
# dic1[dic1_key[0]].append(dic1[dic1_key[0]][0])
return sigle_dic_class1
#4.
def row_dic_del(i,out_index,item,list1,classes,dic1,dic2,sigle_dic_class1,sigle_dic_class2):
out_index2 = out_index
while out_index >= 0:
if ((item[i] - dic2[str(item[1 - i])][out_index][i]) ** 2 + (
item[1 - i] - dic2[str(item[1 - i])][out_index][1 - i]) ** 2) ** 0.5 <= n:
if str(item[1]) not in sigle_dic_class2:
sigle_dic_class2[str(item[1 - i])] = []
sigle_dic_class2[str(item[1 - i])].append(dic2[str(item[1 - i])][out_index])
dic1[str(dic2[str(item[1 - i])][out_index][i])].remove(dic2[str(item[1 - i])][out_index])
classes.append(dic2[str(item[1 - i])][out_index])
ss = dic2[str(item[1 - i])][out_index] # 10.17号新加
if dic1[str(dic2[str(item[1 - i])][out_index][i])] == []: # 如果dic2的某个键的元素为空,则删除该键
del dic1[str(dic2[str(item[1 - i])][out_index][1])]
if str(dic2[str(item[1 - i])][out_index][1]) in sigle_dic_class1:
del sigle_dic_class1[str(dic2[str(item[1 - i])][out_index][i])]
dic2[str(item[1 - i])].remove(dic2[str(item[1 - i])][out_index])
item = ss # 10.17号新加
out_index -= 1
else:
break
out_index = out_index2
while out_index <= len(list1) - 1:
if ((item[i] - dic2[str(item[1 - i])][out_index][1]) ** 2 + (
item[1 - i] - dic2[str(item[1 - i])][out_index][1 - i]) ** 2) ** 0.5 <= n:
if str(item[1 - i]) not in sigle_dic_class2:
sigle_dic_class2[str(item[1 - i])] = []
sigle_dic_class2[str(item[1 - i])].append(dic2[str(item[1 - i])][out_index])
dic1[str(dic2[str(item[1 - i])][out_index][i])].remove(dic2[str(item[1 - i])][out_index])
classes.append(dic2[str(item[1 - i])][out_index])
ss=dic2[str(item[1 - i])][out_index]#10.17号新加
if dic1[str(dic2[str(item[1 - i])][out_index][i])] == []: # 如果dic2的某个键的元素为空,则删除该键
del dic1[str(dic2[str(item[1 - i])][out_index][i])]
if str(dic2[str(item[1 - i])][out_index][i]) in sigle_dic_class1:
del sigle_dic_class1[str(dic2[str(item[1 - i])][out_index][i])]
dic2[str(item[1 - i])].remove(dic2[str(item[1 - i])][out_index])
item=ss #10.17号新加
out_index += 1
else:
break
def col_dic_del(i,out_index,item,list1,classes,dic1,dic2,sigle_dic_class1,sigle_dic_class2):
out_index2 = out_index
while out_index >= 0:
if ((item[i] - dic1[str(item[1-i])][out_index][i]) ** 2 + (
item[1-i] - dic1[str(item[1-i])][out_index][1-i]) ** 2) ** 0.5 <= n:
if str(item[0]) not in sigle_dic_class1:
sigle_dic_class1[str(item[1-i])] = []
sigle_dic_class1[str(item[1-i])].append(dic1[str(item[1-i])][out_index])
dic2[str(dic1[str(item[1-i])][out_index][i])].remove(dic1[str(item[1-i])][out_index])
classes.append(dic1[str(item[1-i])][out_index])
ss=dic1[str(item[1-i])][out_index] #10.17号新加
if dic2[str(dic1[str(item[1-i])][out_index][i])] == []: # 如果dic2的某个键的元素为空,则删除该键
del dic2[str(dic1[str(item[1-i])][out_index][1])]
if str(dic1[str(item[1-i])][out_index][1]) in sigle_dic_class2:
del sigle_dic_class2[str(dic1[str(item[1-i])][out_index][i])]
dic1[str(item[1-i])].remove(dic1[str(item[1-i])][out_index])
item=ss #10.17号新加
out_index -= 1
else:
break
out_index = out_index2
while out_index <= len(list1) - 1:
if ((item[i] - dic1[str(item[1-i])][out_index][1]) ** 2 + (
item[1-i] - dic1[str(item[1-i])][out_index][1-i]) ** 2) ** 0.5 <= n:
if str(item[1-i]) not in sigle_dic_class1:
sigle_dic_class1[str(item[1-i])] = []
sigle_dic_class1[str(item[1-i])].append(dic1[str(item[1-i])][out_index])
dic2[str(dic1[str(item[1-i])][out_index][i])].remove(dic1[str(item[1-i])][out_index])
classes.append(dic1[str(item[1-i])][out_index])
ss = dic1[str(item[1-i])][out_index] # 10.17号新加
if dic2[str(dic1[str(item[1-i])][out_index][i])] == []: # 如果dic2的某个键的元素为空,则删除该键
del dic2[str(dic1[str(item[1-i])][out_index][i])]
if str(dic1[str(item[1-i])][out_index][i]) in sigle_dic_class2:
del sigle_dic_class2[str(dic1[str(item[1-i])][out_index][i])]
dic1[str(item[1-i])].remove(dic1[str(item[1-i])][out_index])
item = ss # 10.17号新加
out_index += 1
else:
break
def cols(key,item,out_index,dic1,dic2,sigle_dic_class2):
out_index2=out_index
while out_index >= 0:
if ((item[0] - dic2[key][out_index][0]) ** 2 + (item[1] - dic2[key][out_index][1]) ** 2) ** 0.5 <= n:
sigle_dic_class2[key].append(dic2[key][out_index])
dic1[str(dic2[key][out_index][0])].remove(dic2[key][out_index])
item=dic2[key][out_index] # 11.17号新加
dic2[key].remove(dic2[key][out_index])
out_index -= 1
else:
break
while out_index2 <= len(dic2[key]) - 1:
if ((item[0] - dic2[key][out_index2][0]) ** 2 + (item[1] - dic2[key][out_index2][1]) ** 2) ** 0.5 <= n:
sigle_dic_class2[key].append(dic2[key][out_index2])
dic1[str(dic2[key][out_index2][0])].remove(dic2[key][out_index2])
item = dic2[key][out_index2] # 11.17号新加
dic2[key].remove(dic2[key][out_index2])
out_index2 += 1
else:
break
def rows(key,out_index,item,dic1,dic2,sigle_dic_class1):
out_index2 = out_index
while out_index >= 0:
if ((item[0] - dic1[key][out_index][0]) ** 2 + (
item[1] - dic1[key][out_index][1]) ** 2) ** 0.5 <= n:
sigle_dic_class1[key].append(dic1[key][out_index])
dic2[str(dic1[key][out_index][1])].remove(dic1[key][out_index])
item = dic1[key][out_index] # 11.17号新加
dic1[key].remove(dic1[key][out_index])
out_index -= 1
else:
break
while out_index2 <= len(dic1[key]) - 1:
if ((item[0] - dic1[key][out_index2][0]) ** 2 + (
item[1] - dic1[key][out_index2][1]) ** 2) ** 0.5 <= n:
sigle_dic_class1[key].append(dic1[key][out_index2])
dic2[str(dic1[key][out_index2][1])].remove(dic1[key][out_index2])
item = dic1[key][out_index2] # 11.17号新加
dic1[key].remove(dic1[key][out_index2])
out_index2 += 1
else:
break
#1.通过某个坐标获得该行所有属于该类的坐标得到sigle_dic_class1
#2.从dic1和dic2删除所有已经处理的行的坐标
#3.通过sigle_dic_class1的行坐标获得每个坐标的列的坐标sigle_dic_class2,并将处理过的列坐标从dic1和dic2删除
def row_index_class(classes,dic1,dic2,sigle_dic_class1,sigle_dic_class2,n,key):
print("...............................某个坐标找到所有符合条件的类................................................")
print("classes",classes)
print("dic1", dic1)
print("dic2", dic2)
print("sigle_dic_class1", sigle_dic_class1)
print("sigle_dic_class2", sigle_dic_class2)
#1.遍历某一行的所有的同类的坐标
print("....................#1.遍历某一行的所有的同类的坐标.............................")
if key in dic1:
while len(dic1[key])>0:
for item in sigle_dic_class1[key]:
if dic1[key]==[]:
break
else:
list1 = dic1[key]
d1 = item
i = 1
print("?????????????????????",item)
print("***********************",dic1[key])
out_index = finddata(d1, list1, i) # 二分法查找该列与该坐标的行坐标相近的坐标
rows(key, out_index, item, dic1, dic2, sigle_dic_class1)#找到该行所有的满足该坐标类的坐标,并将其删除
break
break
if dic1[key]==[]:
del dic1[key]
for items in sigle_dic_class1[key]:#如果dic2键的坐标删完了,则删除该键
if str(items[1]) in dic2:
if dic2[str(items[1])]==[]:
del dic2[str(items[1])]
if items not in classes:
classes.append(items)
#2.sigle_dic_class2获得sigle_dic_class1的元素所在同类的列的所有元素
for item in sigle_dic_class1[key]:
if str(item[1]) in dic2:
if dic2[str(item[1])]==[]:#如果dic2的某个键的元素为空,则删除该键
del dic2[str(item[1])]
if str(item[1]) in sigle_dic_class2: # 如果该键的dic1的元素为空,则将sigle_dic_class1的该键的元素加入classes,然后删除该键
for items in sigle_dic_class2[str(item[1])]:
classes.append(items)
del sigle_dic_class2[str(item[1])]
else:
while len(dic2[str(item[1])])>0:
list1 = dic2[str(item[1])]
d1 = item
i = 0
out_index = finddata(d1, list1, i) # 二分法查找该列与该坐标的行坐标相近的坐标
row_dic_del(i, out_index, item, list1, classes, dic1, dic2, sigle_dic_class1, sigle_dic_class2)#删除该坐标所在的行和列所满足的元素
break
if dic2[str(item[1])] == []:#如果dic2的某个键的元素为空,则删除该键
del dic2[str(item[1])]
if str(item[1]) in sigle_dic_class2: # 如果该键的dic1的元素为空,则将sigle_dic_class1的该键删除
del sigle_dic_class2[str(item[1])]
del sigle_dic_class1[key]#删除sigle_dic_class1的该行
return classes,dic1,dic2,sigle_dic_class1,sigle_dic_class2
#1.通过某个坐标获得该行所有属于该类的坐标得到sigle_dic_class1
#2.从dic1和dic2删除所有已经处理的行的坐标
#3.通过sigle_dic_class1的行坐标获得每个坐标的列的坐标sigle_dic_class2,并将处理过的列坐标从dic1和dic2删除
def col_index_class(classes,dic1,dic2,sigle_dic_class1,sigle_dic_class2,n,key):
# 1.遍历某一行的所有的同类的坐标
print("....................#2.遍历某一行的所有的同类的坐标.............................")
if key in dic2:
while len(dic2[key]) > 0:
for item in sigle_dic_class2[key]:
if dic2[key] == []:
break
else:
while len(dic2[key]) > 0:
list1 = dic2[key]
d1 = item
i = 1
out_index = finddata(d1, list1, i) # 二分法查找该列与该坐标的行坐标相近的坐标
cols(key, item, out_index, dic1, dic2, sigle_dic_class2)#找到该行所有的满足该坐标类的坐标,并将其删除
break
break
if dic2[key] == []: # 如果dic2键的坐标删完了,则删除该键
del dic2[key]
for items in sigle_dic_class2[key]: # 如果dic1键的坐标删完了,则删除该键
if str(items[0]) in dic1:
if dic1[str(items[0])] == []:
del dic1[str(items[0])]
if items not in classes:
classes.append(items)
# 2.sigle_dic_class2获得sigle_dic_class1的元素所在同类的列的所有元素
for item in sigle_dic_class2[key]:
if str(item[0]) in dic1:
if dic1[str(item[0])]==[]:#如果dic1的某个键的元素为空,则删除该键
del dic1[str(item[0])]
if str(item[0]) in sigle_dic_class1:#如果该键的dic1的元素为空,则将sigle_dic_class1的该键的元素加入classes,然后删除该键
for items in sigle_dic_class1[str(item[0])]:
classes.append(items)
del sigle_dic_class1[str(item[0])]
else:
while len(dic1[str(item[0])]) > 0:
list1=dic1[str(item[0])]
d1=item
i=1
out_index=finddata(d1,list1,i)#二分法查找该列与该坐标的行坐标相近的坐标
col_dic_del(i,out_index, item, list1, classes, dic1, dic2, sigle_dic_class1, sigle_dic_class2)#删除该坐标所在的行和列所满足的元素
break
if dic1[str(item[0])]==[]:#如果dic1的某个键的元素为空,则删除该键
del dic1[str(item[0])]
if str(item[0]) in sigle_dic_class1:#如果该键的dic1的元素为空,则将sigle_dic_class1的该键删除
del sigle_dic_class1[str(item[0])]
del sigle_dic_class2[key] # 删除sigle_dic_class1的该行
return classes, dic1, dic2, sigle_dic_class1, sigle_dic_class2
def dic_class(lists,n):
#1.从lists获得dic1,dic2
dic1,dic2=dic1_dic2(lists)
#2.某一个类的新类,获得初始值,且获取这个值后,删除原有类中的元素
sigle_dic_class1=dic_get_value1(dic1)
#3.分别遍历sigle_dic_class1, sigle_dic_class2,其中sigle_dic_class1每个键找dic2
#类存储元素
classes=[]
sigle_dic_class2 = {}
print("......................1111111...........................")
key_1 = list(sigle_dic_class1.keys())
classes.append(sigle_dic_class1[key_1[0]][0])
dic1[key_1[0]].remove(sigle_dic_class1[key_1[0]][0])
dic2[str(sigle_dic_class1[key_1[0]][0][1])].remove(sigle_dic_class1[key_1[0]][0])
print(sigle_dic_class1)
print(classes)
print("......................1111111...........................")
# 3.sigle_dic_class1的键是行坐标,对所对应的所有的列dic1进行遍历,查找符合类的坐标
j = 0
i=0
while len(sigle_dic_class1)>0 or len(sigle_dic_class2)>0:
while len(sigle_dic_class1) > 0:
print("///:", j)
j += 1
key_1 = list(sigle_dic_class1.keys())
if sigle_dic_class1[key_1[0]][0] not in classes:
classes.append(sigle_dic_class1[key_1[0]][0])
classes, dic1, dic2, sigle_dic_class1, sigle_dic_class2 = row_index_class(classes, dic1, dic2, sigle_dic_class1,
sigle_dic_class2, n, key_1[0])
print("dic1", dic1)
print("dic2", dic2)
print("sigle_dic_class2", sigle_dic_class2)
print("sigle_dic_class1", sigle_dic_class1)
print("classes", classes)
# 4.sigle_dic_class2的键是列坐标,对所对应的所有的列dic2进行遍历,查找符合类的坐标
while len(sigle_dic_class2) > 0:
print("======>", i)
i += 1
key_2 = list(sigle_dic_class2.keys())
if sigle_dic_class2[key_2[0]][0] not in classes:
classes.append(sigle_dic_class2[key_2[0]][0])
classes, dic1, dic2, sigle_dic_class1, sigle_dic_class2 = col_index_class(classes, dic1, dic2, sigle_dic_class1,
sigle_dic_class2, n, key_2[0])
print(
".........................................................................................................................................")
print("dic1", dic1)
print("dic2", dic2)
print("sigle_dic_class2", sigle_dic_class2)
print("sigle_dic_class1", sigle_dic_class1)
print("classes", classes)
print(len(classes))
return classes
if __name__ == '__main__':
data = [
[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
[1, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
[1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0],
[1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0],
[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0],
[0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0],
[0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0],
]
data1 = [
[0, 0, 0, 1, 1, 0, 0], # 1
[0, 1, 1, 1, 1, 1, 0], # 2
[0, 1, 1, 1, 1, 1, 0], # 3
[1, 1, 1, 1, 1, 1, 1], # 4
[0, 1, 1, 1, 1, 1, 0], # 5
[0, 1, 1, 1, 1, 1, 0], # 6
[0, 0, 0, 1, 0, 0, 0]] # 7
# 1.数据处理,将数据处理为二维数组=======>[(0, 3), (1, 1), (1, 2),........, (1, 3), (1, 4), (1, 5)]
lists = data_set(data)
print("......................list.......................")
print("1.list:", lists)
# DBSCAN算法中某一个类的拟合
n = 3
classes = dic_class(lists, n)
print(len(lists),len(classes))
for i in range(len(data)):
for j in range(len(data[0])):
if (i, j) in classes:
data[i][j] = 2
data = np.array(data)
print(data)