Kmeans分类 对各类图片中摄像头角度的分类(附代码)

Kmeans分类(角度分类)

上次的气象云分类还在更新中【点击这里】,先记录一下这次在做摄像头角度分类用的算法和代码;
主要是针对摄像头的角度不同使得产生的图片也有差异,这里主要使用的是Kmeans算法进行分类,具体如下:
1、用test.py生成相应的”knn_res1.csv”,之后用class.py文件进行分类
2、这里的Kmeans算法利用sklearn模块中自带的Kmeans算法。进行处理时,先用SIFT读取每个图片的特征,之后用Kmeans算法,得到相应的labels和聚类中心(这里选取的聚类中心为6,分类的种数根据自己要分多少类而定)
代码:

# -*- encoding:utf-8 -*-
__date__ = '19/09/11'
'''
CV_INTER_NN - 最近邻插值,  
CV_INTER_LINEAR - 双线性插值 (缺省使用)  
CV_INTER_AREA - 使用象素关系重采样。当图像缩小时候,该方法可以避免波纹出现。当图像放大时,类似于 CV_INTER_NN 方法..  
CV_INTER_CUBIC - 立方插值
'''

import os, codecs
import cv2
import numpy as np
from sklearn.cluster import KMeans
import pandas as pd
import shutil


def get_file_name(path):
    # '''
    # Args: path to list;  Returns: path with filenames
    # '''
    filenames = os.listdir(path)
    path_filenames = []
    filename_list = []
    for file in filenames:
        if not file.startswith('.'):
            path_filenames.append(os.path.join(path, file))
            filename_list.append(file)

    return path_filenames


def knn_detect(file_list, cluster_nums, randomState=None):
    features = []
    files = file_list
    sift = cv2.xfeatures2d.SIFT_create()
    for file in files:
        print(file)
        img = cv2.imread(file)
        img = cv2.resize(img, (32, 32), interpolation=cv2.INTER_CUBIC)

        gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
        print(gray.dtype)
        _, des = sift.detectAndCompute(gray, None)

        if des is None:
            file_list.remove(file)
            continue

        reshape_feature = des.reshape(-1, 1)
        features.append(reshape_feature[0].tolist())

    input_x = np.array(features)

    kmeans = KMeans(n_clusters=cluster_nums, random_state=randomState).fit(input_x)

    return kmeans.labels_, kmeans.cluster_centers_


def res_fit(filenames, labels):
    list = []
    files = [file.split('/')[-1] for file in filenames]
    for i in range(len(files)):
            
        list.append([files[i], labels[i]])
    # return dict(zip(files, labels))
    return list
# 按照类别保存图片


def save(path, filename, data):
    file = os.path.join(path, filename)
    with codecs.open(file, 'w', encoding='utf-8') as fw:
        for f, l in data.items():
            fw.write("{}\t{}\n".format(f, l))


def main():
    path_filenames = get_file_name("C:/你的路径/classes/samples_1/")

    labels, cluster_centers = knn_detect(path_filenames, 6)

    res_dict = res_fit(path_filenames, labels)
    # save('./', 'knn_res1.txt', res_dict)
    pd.DataFrame(res_dict).to_csv("knn_res1.csv")


if __name__ == "__main__":
    main()

之后用生成的csv文件对数据集进行分类

import csv
import shutil
import os

target_path = "C:/你的路径/classes/"
original_path = "C:/你的路径/classes/samples_1/"
with open('C:/你的路径/classes/knn_res1.csv', "rt", encoding="utf-8") as csvfile:
    reader = csv.reader(csvfile)
    lines = list(reader)  #将reader读取的变为一个list,可以进行去除表的第一行、第一列操作
    #rows= [row for row in reader]
    #for row in rows:
    for i in range(1,len(lines)):
        if os.path.exists(target_path+lines[i][2]) :
            full_path = original_path + lines[i][1]
            shutil.move(full_path,target_path + lines[i][2] +'/')
        else :
            os.makedirs(target_path+lines[i][2])
            full_path = original_path + lines[i][1]
            shutil.move(full_path,target_path + lines[i][2] +'/')
            

之后在同目录下就可以看到已经分好类的6个文件夹了
在这里插入图片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章