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

时间:2017-12-05 22:16:30

标签: algorithm search image-processing colors cluster-analysis

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

现在的目标不是匹配精确的对象,而是找到与模板颜色接近的任何重要区域。我被困在索引我的数据集。

我尝试了一些聚类算法,比如来自sklearn.cluster的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 个答案:

答案 0 :(得分:0)

通常的方法是只使用所有图像中的代表性样本,只对一次进行聚类。

这是一个预处理步骤,用于生成"字典"。

然后,对于要素提取,您可以将点映射到已修复的群集中心,现在在所有图像中共享。这是一个简单的最近邻映射,没有聚类。