您的足迹:首页 > 其他 >对图片颜色进行分类

对图片颜色进行分类

对图片颜色进行分类,思路有两种

1. 通过kmeans来获取平均颜色

2. 通过判断像素哪种颜色最多来判断图片属于哪种颜色


kmean实现

java 实现

package com.zhongtiancai.classify;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class KMean implements Classify {
	private int k = 5;
	private int max_iterations = 20;
	private int min_distance = 5;
	private int size = 200;
	private List<Color> colors = new ArrayList<>();
	private List<Cluster> clusters = new ArrayList<>();
	private List<Color> oldClusterCenters = new ArrayList<>();

	public int getK() {
		return k;
	}

	public void setK(int k) {
		this.k = k;
	}

	public int getMax_iterations() {
		return max_iterations;
	}

	public void setMax_iterations(int max_iterations) {
		this.max_iterations = max_iterations;
	}

	public int getMin_distance() {
		return min_distance;
	}

	public void setMin_distance(int min_distance) {
		this.min_distance = min_distance;
	}

	public int getSize() {
		return size;
	}

	public void setSize(int size) {
		this.size = size;
	}

	public KMean(int k, int max_iterations, int min_distance, int size, List<Color> colors) {
		super();
		this.k = k;
		this.max_iterations = max_iterations;
		this.min_distance = min_distance;
		this.size = size;
		this.colors = colors;
		List<Integer> randomList = RandomArray.genRandomArray(colors.size(), k);
		for (int i = 0; i < k; i++) {
			Cluster cluster = new Cluster();
			cluster.setCenter(colors.get(randomList.get(i)));
			clusters.add(cluster);
		}
	}

	/**
	 * 按照距离分簇
	 */
	public void assignClusters(Color pixel) {
		double shortest = Float.MAX_VALUE;
		Cluster nearest = null;
		for (Cluster cluster : this.clusters) {
			double distance = new Distance(cluster.getCenter(), pixel).getDistance();
			if (distance < shortest) {
				shortest = distance;
				nearest = cluster;
			}
		}
		nearest.addPoint(pixel);
	}

	public List<Color> getMainColor() {
		int i = 0;
		while (!shouldExit(i)) {
			this.oldClusterCenters = this.clusters.stream().map(cluster -> cluster.getCenter())
					.collect(Collectors.toList());
			for (Color color : this.colors) {
				assignClusters(color);
			}
			for (Cluster cluster : this.clusters) {
				cluster.setNewCentroid();
			}
			i += 1;
		}
		return this.clusters.stream().map(c -> c.getCenter()).collect(Collectors.toList());
	}

	public boolean shouldExit(int iterations) {
		if (this.oldClusterCenters == null || this.oldClusterCenters.size() <= 0) {
			return false;
		}
		for (int i = 0; i < this.k; i++) {
			if (new Distance(this.getClusters().get(i).getCenter(),
					this.getOldClusterCenters().get(i)).getDistance() < this.min_distance) {
				return true;
			}
		}
		if (iterations <= this.max_iterations) {
			return false;
		}
		return true;
	}

	

	public List<Color> getColors() {
		return colors;
	}

	public void setColors(List<Color> colors) {
		this.colors = colors;
	}

	public List<Cluster> getClusters() {
		return clusters;
	}

	public List<Color> getOldClusterCenters() {
		return oldClusterCenters;
	}

	public void setOldClusterCenters(List<Color> oldClusterCenters) {
		this.oldClusterCenters = oldClusterCenters;
	}

}

python实现

# -*- coding: utf-8 -*-
import random
import numpy

"""
 -------------k_mean_class---------------
功能:使用k值估计计算传入图片的主题颜色
"""

class Cluster(object):

    def __init__(self):
        self.pixels = []
        self.centroid = None

    def addPoint(self, pixel):
        self.pixels.append(pixel)

    def setNewCentroid(self):

        R = [colour[0] for colour in self.pixels]
        G = [colour[1] for colour in self.pixels]
        B = [colour[2] for colour in self.pixels]

        # print(sum(R),len(R))
        # print(sum(G), len(G))
        # print(sum(B), len(B))

        # 画面不含有某个通道的颜色(比如画面颜色较纯等等)
        # 对其进行+1防止被0除
        if len(R)>0:
            R = sum(R) / len(R)
        else:
            R=sum(R)/(len(R)+1)
        if len(G)>0:
            G = sum(G) / len(G)
        else:
            G = sum(G) / (len(G)+1)
        if len(B)>0:
            B = sum(B) / len(B)
        else:
            B = sum(B) / (len(B)+1)

        self.centroid = (R, G, B)
        self.pixels = []

        return self.centroid


class Kmeans(object):

    def __init__(self, k=3, max_iterations=5, min_distance=5.0):
        self.k = k
        self.max_iterations = max_iterations
        self.min_distance = min_distance

    def run(self, pixels):

        self.pixels = pixels
        self.clusters = [None for i in range(self.k)]
        self.oldClusters = None

        randomPixels = random.sample(list(self.pixels), self.k)

        for idx in range(self.k):
            self.clusters[idx] = Cluster()
            self.clusters[idx].centroid = randomPixels[idx]

        iterations = 0

        while self.shouldExit(iterations) is False:

            self.oldClusters = [cluster.centroid for cluster in self.clusters]

            # print(iterations)

            for pixel in self.pixels:
                self.assignClusters(pixel)

            for cluster in self.clusters:
                cluster.setNewCentroid()

            iterations += 1

        return [cluster.centroid for cluster in self.clusters]

    def assignClusters(self, pixel):
        shortest = float('Inf')
        for cluster in self.clusters:
            distance = self.calcDistance(cluster.centroid, pixel)
            if distance < shortest:
                shortest = distance
                nearest = cluster

        nearest.addPoint(pixel)

    def calcDistance(self, a, b):

        result = numpy.sqrt(sum((a - b) ** 2))
        return result

    def shouldExit(self, iterations):

        if self.oldClusters is None:
            return False

        for idx in range(self.k):
            dist = self.calcDistance(
                numpy.array(self.clusters[idx].centroid),
                numpy.array(self.oldClusters[idx])
            )
            if dist < self.min_distance:
                return True

        if iterations <= self.max_iterations:
            return False

        return True


if __name__ == "__main__":
import os

像素所属颜色最多的判断(通过欧氏距离来判断像素属于哪种颜色)

package com.zhongtiancai.classify;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class ClassicClassify implements Classify {
	private List<Color> colors;
	private List<Color> testColors;
	private List<Cluster> clusters = new ArrayList<>();

	// 百分比
	private double rate;

	public List<Color> getColors() {
		return colors;
	}

	public void setColors(List<Color> colors) {
		this.colors = colors;
	}

	public List<Color> getTestColors() {
		return testColors;
	}

	public void setTestColors(List<Color> testColors) {
		this.testColors = testColors;
	}

	public double getRate() {
		return rate;
	}

	public void setRate(double rate) {
		this.rate = rate;
	}

	public ClassicClassify(List<Color> colors, List<Color> testColors,double rate) {
		super();
		this.colors = colors;
		this.testColors = testColors;
		this.rate = rate;
		for (int i = 0; i < testColors.size(); i++) {
			Cluster cluster = new Cluster();
			cluster.setCenter(testColors.get(i));
			clusters.add(cluster);
		}
	}

	public List<Color> getMainColor() {
		for (Color color : this.colors) {
			assignClusters(color);
		}
		clusters.sort(new Comparator<Cluster>() {
			@Override
			public int compare(Cluster o1, Cluster o2) {
				if (o1.getColors().size() > o2.getColors().size()) {
					return -1;
				} else if (o1.getColors().size() < o2.getColors().size()) {
					return 1;
				} else {
					return 0;
				}
			}
		});
		List<Color> color = new ArrayList<>();
		for (Cluster cluster : clusters) {
			System.out.println(cluster.getCenter().toString() + cluster.getColors().size());
			if (colors.size() * rate <= cluster.getColors().size()) {
				color.add(cluster.getCenter());
			}
		}
		return color;
	}

	/**
	 * 按照距离分簇
	 */
	public void assignClusters(Color pixel) {
		double shortest = Float.MAX_VALUE;
		Cluster nearest = null;
		for (Cluster cluster : this.clusters) {
			double distance = new Distance(cluster.getCenter(), pixel).getDistance();
			if (distance < shortest) {
				shortest = distance;
				nearest = cluster;
			}
		}
		nearest.addPoint(pixel);
	}

}



实现方式其实还有很多很多



本博客所有文章如无特别注明均为原创。作者:小天复制或转载请以超链接形式注明转自 钟天才的博客
原文地址《对图片颜色进行分类

相关推荐

网友评论(0)