代码之家  ›  专栏  ›  技术社区  ›  Vitaly Galaychuk

图像搜索引擎中基于聚类的颜色特征提取

  •  0
  • Vitaly Galaychuk  · 技术社区  · 6 年前

    我正在尝试实现一个基于感知的图像搜索引擎,它将允许用户查找图片,其中包含与用户指定模板颜色相对相同或相近的对象(来自样本图像的对象)。

    目前的目标不是匹配精确的对象,而是找到任何颜色接近模板的重要区域。我一直在为我的数据集编制索引。

    我尝试了一些聚类算法,例如sklearn中的k-means。集群(正如我从中读到的 this article ),从样本图像中选择质心作为我的特征,这些特征最终位于CIELab颜色空间中,以获得更大的感知均匀性。但这似乎并不奏效,因为聚类中心是随机生成的,因此即使是在提取同一个对象的对象和图像上,我的度量结果也很差!

    就我而言,简单图像搜索程序中的一个常见算法是使用直方图之间的距离,这是不可接受的,因为我试图维持感知上有效的色差,我的意思是我只能管理两个单独的颜色(可能还有一些附加值)来计算 metrics in CIELab colour space . 我正在使用我自己实现的CMCl:c度量,到目前为止,它产生了良好的结果。

    也许有人可以帮我推荐一种更适合我的算法。

    到目前为止,我已经完成了一些代码:

    import cv2 as cv
    import numpy as np
    from sklearn.cluster import KMeans, MiniBatchKMeans
    from imageproc.color_metrics import *
    
    def feature_extraction(image, features_length=6):
        width, height, dimensions = tuple(image.shape)
    
        image = cv.cvtColor(image, cv.COLOR_BGR2LAB)
        image = cv.medianBlur(image, 7)
    
        image = np.reshape(image, (width * height, dimensions))
    
        clustering_handler = MiniBatchKMeans(n_init=40, tol=0.0, n_clusters=features_length, compute_labels=False,
                                         max_no_improvement=10, max_iter=200, reassignment_ratio=0.01)
    clustering_handler.fit(image)
    
        features = np.array(clustering_handler.cluster_centers_, dtype=np.float64)
        features[:, :1] /= 255.0
        features[:, :1] *= 100.0
        features[:, 1:2] -= 128.0
        features[:, 2:3] -= 128.0
    
        return features
    
    if __name__ == '__main__':
        first_image_name = object_image_name
        second_image_name = image_name
    
        sample_features = list()
        reference_features = list()
    
        for name, features in zip([first_image_name, second_image_name], [sample_features, reference_features]):
            image = cv.imread(name)
            features.extend(feature_extraction(image, 6))
        distance_matrix = np.ndarray((6, 6))
        distance_mappings = {}
    
        for n, i in enumerate(sample_features):
            for k, j in enumerate(reference_features):
                distance_matrix[n][k] = calculate_cmc_distance(i, j)
                distance_mappings.update({distance_matrix[n][k]: (i, j)})
    
    
    
        minimal_distances = []
        for i in distance_matrix:
            minimal_distances.append(min(i))
    
        minimal_distances = sorted(minimal_distances)
        print(minimal_distances)
        for ii in minimal_distances:
            i, j = distance_mappings[ii]
            color_plate1 = np.zeros((300, 300, 3), np.float32)
            color_plate2 = np.zeros((300, 300, 3), np.float32)
    
            color1 = cv.cvtColor(np.float32([[i]]), cv.COLOR_LAB2BGR)[0][0]
            color2 = cv.cvtColor(np.float32([[j]]), cv.COLOR_LAB2BGR)[0][0]
    
            color_plate1[:] = color1
            color_plate2[:] = color2
    
            cv.imshow("s", np.hstack((color_plate1, color_plate2)))
            cv.waitKey()
    
        print(sum(minimal_distances))
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Has QUIT--Anony-Mousse    6 年前

    通常的方法是只进行集群 一旦 ,具有代表性的样本来自 全部的 图像。

    这是一个预处理步骤,用于生成“词典”。

    然后,对于特征提取,您将点映射到 固定的 集群中心 在所有图像中共享 . 这是一个简单的最近邻映射,没有聚类。