简介

因为one-stage 的检测模型一般要指定检测目标的长宽比和范围,类似ssd,yolov3等,那么,就有统计样本长宽的聚类需求,分析样本数据,根据样本数据的情况,对长宽比和范围进行设置,代码比较简单,下面就是代码。

代码

代码主要包括voc的 读取部分,产生长宽比数据部分,以及进行kmeans计算部分,具体代码如下:

#!/usr/bin/env python
# -*- coding: utf8 -*-
import sys
from  .etree import ElementTree
from  .etree.ElementTree import Element, SubElement
from l  import etree
import numpy as np
import os
import sys
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans

 _EXT = \'. \'
ENCODE_METHOD = \'utf-8\'

#pascalVocReader readers the voc   files parse it
class PascalVocReader:
    \"\"\"
    this class will be used to get transfered width and height from voc   files
    \"\"\"
    def __init__(self, filepath,width,height):
        # shapes type:
        # [labbel, [(x1,y1), (x2,y2), (x3,y3), (x4,y4)], color, color, difficult]
        self.shapes = []
        self.filepath = filepath
        self.verified = False
        self.width=width
        self.height=height

        try:
            self.parse ()
        except:
            pass

    def getShapes(self):
        return self.shapes

    def addShape(self, bndbox, width,height):
        xmin = int(bndbox.find(\'xmin\').text)
        ymin = int(bndbox.find(\'ymin\').text)
        xmax = int(bndbox.find(\'xmax\').text)
        ymax = int(bndbox.find(\'ymax\').text)
        width_trans = (xmax - xmin)/width*self.width
        height_trans = (ymax-ymin)/height *self.height
        points = [width_trans,height_trans]
        self.shapes.append((points))

    def parse (self):
        assert self.filepath.endswith( _EXT), \"Unsupport file format\"
        parser = etree. Parser(encoding=ENCODE_METHOD)
         tree = ElementTree.parse(self.filepath, parser=parser).getroot()
        pic_size =  tree.find(\'size\')
        size = (int(pic_size.find(\'width\').text),int(pic_size.find(\'height\').text))
        for  _iter in  tree.findall(\' \'):
            bndbox =  _iter.find(\"bndbox\")
            self.addShape(bndbox, *size)
        return True

class create_w_h_txt:
    def __init__(self,voc _path,txt_path):
        self.voc_path = voc _path
        self.txt_path = txt_path
    def _gether_w_h(self):
        pass
    def _write_to_txt(self):
        pass
    def process_file(self):
        file_w = open(self.txt_path,\'a\')
       # print (self.txt_path)
        for file in os.listdir(self.voc_path):
            file_path = os.path.join(self.voc_path, file)
             _parse = PascalVocReader(file_path,304,304)
            data =  _parse.getShapes()
            for w,h in data :
                txtstr = str(w)+\' \'+str(h)+\'\\n\'
                #print (txtstr)
                file_w.write(txtstr)
        file_w.close()

class kMean_parse:
    def __init__(self,path_txt):
        self.path = path_txt
        self.km = KMeans(n_clusters=5,init=\"k-means++\",n_init=10,max_iter=3000000,tol=1e-3,random_state=0)
        self._load_data()

    def _load_data (self):
        self.data = np.loadtxt(self.path)

    def parse_data (self):
        self.y_k = self.km.fit_predict(self.data)
        print(self.km.cluster_centers_)

    def plot_data (self):
        plt.scatter(self.data[self.y_k == 0, 0], self.data[self.y_k == 0, 1], s=50, c=\"orange\", marker=\"o\", label=\"cluster 1\")
        plt.scatter(self.data[self.y_k == 1, 0], self.data[self.y_k == 1, 1], s=50, c=\"green\", marker=\"s\", label=\"cluster 2\")
        plt.scatter(self.data[self.y_k == 2, 0], self.data[self.y_k == 2, 1], s=50, c=\"blue\", marker=\"^\", label=\"cluster 3\")
        plt.scatter(self.data[self.y_k == 3, 0], self.data[self.y_k == 3, 1], s=50, c=\"gray\", marker=\"*\",label=\"cluster 4\")
        plt.scatter(self.data[self.y_k == 4, 0], self.data[self.y_k == 4, 1], s=50, c=\"yellow\", marker=\"d\",label=\"cluster 5\")
       # draw the centers
        plt.scatter(self.km.cluster_centers_[:, 0], self.km.cluster_centers_[:, 1], s=250, marker=\"*\", c=\"red\", label=\"cluster center\")
        plt.legend()
        plt.grid()
        plt.show()




if __name__ == \'__main__\':
     whtxt = create_w_h_txt(\"./voc/Annotations\",\"./data1.txt\") #指定为voc标注路径,以及存放生成文件路径
     whtxt.process_file()
     kmean_parse = kMean_parse(\"./data1.txt\")#路径和生成文件相同。
     kmean_parse.parse_data()
     kmean_parse.plot_data() #绘图部分只支持五个簇,要增加,需要自家改代码即可

结果如下图所示:
\"聚类结果\"

收藏 打印