Este artigo descreve o código de exemplo de Java para obter a cor principal em uma imagem colorida. Compartilhe -o para sua referência, como segue:
1: Idéias básicas
Para uma imagem colorida no espaço de cores RGB, queremos obter várias cores principais da imagem através do programa em muitas vezes. No entanto, para imagens gerais, a mistura de pixels é alcançada na junção colorida. Portanto, examinar diretamente os valores de pixel da imagem pode resultar em centenas de valores de cores diferentes. De fato, a imagem pode ter apenas 3 a 4 cores principais. Como remover essas cores mistas e extrair com precisão as cores principais desses 3 a 4. De acordo com as características da imagem geral, a imagem não estará misturando diferentes valores de cores no limite da mesma cor, pode ser considerado como uma das características da borda da imagem. Therefore, the extract of these mixed pixels can be achieved according to a simple edge gradient algorithm to obtain the output pixel value array, and then scanning each pixel value, looking for the pixels around the specified radius parameter R, and finding zero, and the value of the pixel point closest to the center pixel is used as the pixel value of the center pixel. Após a conclusão da varredura, a matriz de pixels pode ser emitida e, em seguida, examinar linearmente a matriz, pode ser obtida para obter o valor principal RGB da cor da imagem.
Dois: etapas de implementação
1. Digite uma matriz de imagem para escalar a imagem colorida;
2. Para a imagem em escala de cinza, calcule o gradiente de imagem e use o operador de Sobol aqui;
3. Para cada ponto pixel diferente de zero, digitalize dentro da faixa de raio r e encontre o valor de pixel original mais próximo de zero;
4. Basta escanear a matriz obtida para obter a cor principal.
O parâmetro r é encontrar o valor mais adequado de acordo com diferentes cenários de aplicação. Teoricamente, quanto maior a imagem, maior será o valor de R, caso contrário, o algoritmo será impreciso.
Três: imagem original e efeito de operação
Imagem original
Depois que o algoritmo é executado, quatro cores principais são extraídas
Quatro: Código Fonte de Implementação de Algoritmo
public static bufferImage RemowBlendPixels (imagem bufferImage, int Raidus) {int width = image.getWidth (); int height = image.getHeight (); int [] pixels = new int [largura * altura]; getrgb (imagem, 0, 0, largura, altura, pixels); // Crie Processing resultBufferImage resultImg = CreateCompatiBledestImage (Image, NULL); setRGB (resultimg, 0, 0, largura, altura, pixels); // Crie Processing resultBufferImage resultImg = CreateCompatiBledestImage (Image, NULL); setRGB (resultimg, 0, 0, largura, altura, pixels); // byte de cinza e gradiente [] GrayData = getGrayData (pixels, largura, altura); byte [] binaryData = getGrident (GrayData, largura, altura); int index = 0; for (int linha = 1; linha <altura - 1; linha ++) {for (int col = 1; col <width - 1; col ++) {index = linha * largura+col; int pixel = (binaryData [index] e 0xff); if (pixel> 0) {// RADIUS SCAN Operação int mindis = Integer.max_value; int minrow = -1; int miCol = -1; int nr = 0; int nc = 0; int index2 = 0; for (int subrow = -idus; subrow <= Raidus; subrow ++) {nr = linha+subrow; if (nr <0 || nr> = altura) {continue; } para (int subcol = -aidus; subcol <= Raidus; subcol ++) {nc = col+subcol; if (nc <0 || nc> = width) {continua; } index2 = nr * largura + nc; int vale = (binaryData [index2] e 0xff); if (value == 0) {int distance = Distancecolor (image.getRgb (nc, nr), image.getRgb (col, linha)); if (distância <mindis) {Mindis = distance; minrow = nr; miCol = nc; }}}} resultImg.setrgb (col, line, image.getRgb (mincol, minrow)); }}} retornar resultimg; } public static int distancecolor (int rgb, int rgb2) {// color um int r1 = (rgb >> 16) & 0xff; int g1 = (rgb >> 8) e 0xff; int b1 = rgb & 0xff; // coloria dois int r2 = (rgb2 >> 16) e 0xff; int g2 = (rgb2 >> 8) e 0xff; int b2 = rgb2 e 0xff; // distância int rr = r1 - r2; int gg = g1 - g2; int bb = b1 - b2; int sum = (int) math.sqrt (rr * rr + gg * gg + bb * bb); soma de retorno; } public static byte [] getGrayData (int [] inpixels, int width, int alting) {// Image GrayScale byte [] outpixels = new Byte [largura * altura]; int index = 0; for (int linha = 0; linha <altura; linha ++) {int tr = 0, tg = 0, tb = 0; for (int col = 0; col <width; col ++) {index = linha * width+col; tr = (inpixels [index] >> 16) e 0xff; tg = (inpixels [index] >> 8) e 0xff; tb = inpixels [index] & 0xff; int cinza = (int) (0,299 * tr + 0,587 * tg + 0,114 * tb); outpixels [index] = (byte) (Gray & 0xff); }} retorna outpixels; } public static byte [] getGrident (byte [] inpixels, int width, int alting) {byte [] outpixels = new Byte [largura * altura]; int index = 0; for (int linha = 0; linha <altura; linha ++) {int tr = 0; para (int col = 0; col <width; col ++) {if (linha == 0 || col == 0 || (linha == altura - 1) || (col == width - 1)) {index = linha * largura+col; outpixels [index] = (byte) (0x00); continuar; } int xg = 0, yg = 0; for (int sr = -1; sr <= 1; sr ++) {for (int sc = -1; sc <= 1; sc ++) {int nrow = linha+sr; int ncol = col + sc; if (nrow <0 || nrow> = altura) {nrow = 0; } if (ncol <0 || ncol> = largura) {ncol = 0; } index = nrow * width + ncol; tr = (inpixels [index] e 0xff); xg + = x_sobel [sr + 1] [sc + 1] * tr; yg + = y_sobel [sr + 1] [sc + 1] * tr; }} index = linha * largura + col; int g = (int) math.sqrt (xg * xg + yg * yg); outpixels [index] = (byte) (grampo (g) e 0xff); }} retorna outpixels; } Os valores constantes que precisam ser definidos são os seguintes:
public static final int [] [] x_sobel = new int [] [] {{-1, -2, -1}, {0, 0, 0}, {1, 2, 1}}; public static final int [] [] y_sobel = new int [] [] {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}}; public static final int block_pixel_radius = 5; Aquisição de gradiente usa o operador de Sobol. O código para digitalizar o objeto bufferimage após o processamento para obter a cor principal é a seguinte:
int width = resultado.getWidth (); int height = resultado.getHeight (); Mapa <Inteiro, Inteiro> colorIndexmap = new Hashmap <Inteiro, Integer> (); for (int linha = 0; linha <altura; linha ++) {for (int col = 0; col <width; col ++) {int pixelValue = resultado.getRgb (col, linha); if (! colorIndexmap.containsKey (pixelValue)) {colorIndexmap.put (pixelValue, pixelValue); }}} // Agora digitalize o valor do pixel // Return Result System.out.println ("Número de color =" + colorIndexmap.size ()); retornar colorindexmap.keyset (). ToArray (novo número inteiro [0]); O código de teste é o seguinte:
public static void main (string [] args) {arquivo file = new File ("d: //gloomyfish//bigmonkey.png"); Arquivo ResultFile = new File ("d: //gloomyfish//result.png"); tente {buffaredImage image = imageio.read (arquivo); Resultado bufferedImage = removeblendpixels (imagem, block_pixel_radius); Imageio.write (resultado, "png", resultfile); Inteiro [] Cores = ExtractColors (resultado); System.out.println ("Total Colors:" + Colors.Length); } catch (ioexception e) {e.printStackTrace (); }}Nota: A chave principal é inserir o tamanho correto da imagem a ser processada. Esse tamanho de raio está relacionado ao tamanho real da imagem, e o algoritmo pode ser otimizado uma etapa mais adiante em uma versão que não depende do parâmetro RADIUS, até encontrar um pixel igual a zero.
O exposto acima é todo o conteúdo deste artigo. Espero que seja útil para o aprendizado de todos e espero que todos apoiem mais o wulin.com.