样本文件名例如: N00001C3noFusionP110_456_45_12S12345.npy
其中00001为编号,3noFusion为类型,110_456_45_12为位置信息,为x,y,width,height,12345.npy为文件名
1、首先就是循环遍历这个图片文件夹,并进行相应的图像处理操作。这个在之前的博客里有写到。接下来就是新建文件夹并将npy文件保存进去。
- def save_npy(data,path,name):
- '''
- data为要保存的npy数据
- path为要保存的路径
- name为要保存的文件名
- '''
- if not os.path.exists(path):
- os.makedirs(path) #如果没有该文件夹,创建文件夹
- file = os.path.join(path,name) #保存文件
- if not os.path.isfile(file):
- np.save(file,data)
-
-
- # 所以在主函数中,只需要定义好我们的路径和文件名,调用该函数即可完成新建文件夹和文件的保存。
到这一步,数据集就搞好了,接下来就是比较头疼的匹配环节。
2、提取样本集的各字段
- # 定义样本集的三个要收集的信息--list
- filename_list = []
- filetype_list = []
- fileposition_list = []
-
- #循环遍历样本集,依次获取三种信息并添加到相应list中
- fileList = getFileList(filepath,[],'npy') #这一步是读取样本集中的文件
- #它的输出是包含了这个文件的完整路径 比如 D:\\xxxx\\这种的
- #所以我们需要提前获取到它的真正文件名
- filenameList = []
- for item in fileList:
- #就是去掉所有的路径前缀,保留文件名
- filename = os.path.splitext(os.path.basename(item))[0]
- filenameList.append(filename)
-
- #filenameList中存放的就全部都是每一个文件的文件名了
-
- for fileitem in filenameList:
- name = fileitem.split('S')[1]
- filetype = fileitem.split('C')[1][0:1]
- fileposition = fileitem.split('S')[0][-17:].split('P')[1]
- filename_list.append(name)
- filetype_list.append(filetype)
- fileposition_list.append(fileposition)
-
- #至此,样本集的三个信息均收集完成
具体记录一下提取字符串的split方法
- str = '你好,HelloWorld'
-
- b = str.split(',') #这个就是以 ,为分割,划分这个字符串
- print(b) # 输出会发现,它是数组,['你好','HelloWorld'] 分别存放分割前和后的字符串
- #如果只要逗号后的字符串
- c = str.split(',')[1] # HelloWorld
所以对于文件名就是提取S字符之后的所有字符串就是 split('S')[1]
而文件的类型,其实我需要的只是C3noFusion里面,C后面紧跟的那个数字即可(共分为1,2,3,三类,每一大类里面有小类,就是后面的英文,但实际中只需要大类即可),所以split('C')[1]就是C后面的所有字段,[0:1]就是该字段中的【0,1)的字段,即那个数字 3
fileposition写的很复杂,是因为在给文件夹规定命名格式时,是N+C+P+S,但是我一时疏忽忘记考虑在C这个类型里面,第三类有一个小类中包含了P这个字符,C3noPen....这样子的,所以仅通过找到P是不行的。
- # N00001C3noFusionP110_456_45_12S12345.npy 以这个命名为例
- fileitem.split('S')[0] # N00001C3noFusionP110_456_45_12
- # 从后往前找17位,(这里的17是根据命名位置信息P时是超过x,y,width,height所有的长度上限的)
- #并且如果有时P字段字符较少,也不会查找到C3noP....中的P字段
-
- # 所以假设查找到了 onP110_456_45_12
- 就只需要再split('S')[1]即可
这里就是完成了文件名中的三个信息的收集工作,后面就是样本集和数据集中位置信息的匹配工作。(位置信息就是外界矩形的左上角的x,y坐标,和它的宽高)。先根据position信息,提取到四个值,存到变量中。如 positon1 = [x,y,width,height]
也就是有了两个矩形的位置信息,首先判断它们是否相交,如果相交,判断它们的重合度。
- #计算两个矩形是否相交
- def mat_inter(box1,box2):
- #这里的x01,y01就是左上角的坐标,x02,y02是右下角的坐标
- #所以根据我们的x y width height 还要转换一下右下角坐标
- x01,y01,x02,y02 = box1
- x11,y11,x12,y12 = box2
-
- lx = abs((x01 + x02) / 2 - (x11 + x12) / 2)
- ly = abs((y01 + y02) / 2 - (y11 + y12) / 2)
-
- width1 = abs(x01 - x02)
- height1 = abs(y01 - y02)
- width2 = abs(x11 - x12)
- height2 = abs(y11 - y12)
-
- if(lx <= (width1 + width2) / 2 and ly <= (height1 + height2) / 2):
- return True
- else:
- return False
-
- #计算两个矩形框的重合度
- def solve_inter(box1,box2):
- if mat_inter(box1,box2) == True:
- x01,y01,x02,y02 = box1
- x11,y11,x12,y12 = box2
-
- col = min(x02,x12) - max(x01,x11)
- row = min(y02,y12) - max(y01,y11)
- intersection = col * row
- area1 = abs(x02 - x01) * abs(y02 - y01)
- area2 = abs(x12 - x11) * abs(y12 - y11)
- coincide = intersection / (area1 + area2 - intersection)
- return coincide
- else:
- return False
后续的类型字符段添加还有模型的训练等就不写了