Este artículo describe el código de ejemplo de Java para obtener el color principal en una imagen de color. Compártelo para su referencia, como sigue:
1: Ideas básicas
Para una imagen de color en el espacio de color RGB, queremos obtener varios colores principales de la imagen a través del programa en muchas veces. Sin embargo, para las imágenes generales, la mezcla de píxeles se logra en el cruce de color. Por lo tanto, escanear directamente los valores de píxeles de la imagen puede dar como resultado hasta cientos de valores de color diferentes. De hecho, la imagen solo puede tener de 3 a 4 colores principales. Cómo eliminar esos colores mixtos y extraer con precisión los colores principales de estos 3 a 4. Según las características de la imagen general, la imagen no mezclará diferentes valores de color en el límite del mismo color puede considerarse como una de las características de borde de la imagen. Por lo tanto, el extracto de estos píxeles mixtos se puede lograr de acuerdo con un algoritmo de gradiente de borde simple para obtener la matriz de valor de píxel de salida, y luego escanear cada valor de píxel, buscando los píxeles alrededor del parámetro RADIUS especificado R y encontrar cero, y el valor del punto de píxel más cercano al píxel central se utiliza como el valor de los píxeles del pixel central. Después de completar el escaneo, la matriz de píxeles se puede emitir y luego escanear linealmente la matriz se puede obtener para obtener el valor RGB de color principal de la imagen.
Dos: Pasos de implementación
1. Ingrese una matriz de imágenes a la escala de grises de la imagen de color;
2. Para la imagen de la escala de grises, calcule el gradiente de imagen y use el operador Sobol aquí;
3. Para cada punto de píxel distinto de cero, escanee dentro del rango de radio R y encuentre el valor de píxel original más cercano de cero;
4. Simplemente escanee la matriz obtenida para obtener el color principal.
El parámetro R es encontrar el valor más adecuado de acuerdo con diferentes escenarios de aplicación. Teóricamente, cuanto mayor sea la imagen, mayor será el valor de R, de lo contrario, el algoritmo será inexacto.
Tres: Imagen original y efecto de operación
Imagen original
Después de que se ejecuta el algoritmo, se extraen cuatro colores principales
Cuatro: código fuente de implementación de algoritmo
public static BufferedImage RemoLBlendPiXels (Imagen de BufferedImage, int Raidus) {int width = image.getWidth (); int hight = image.getheight (); int [] píxeles = new int [width * altura]; getrgb (imagen, 0, 0, ancho, altura, píxeles); // Crear resultado ProcessBufferedImage resultimg = CreateCompatibleDeMage (Imagen, NULL); setrgb (resultimg, 0, 0, ancho, altura, píxeles); // Crear resultado ProcessBufferedImage resultimg = CreateCompatibleDeMage (Imagen, NULL); setrgb (resultimg, 0, 0, ancho, altura, píxeles); // byte de escala de grises y gradientes [] GrayData = getGrayData (píxeles, ancho, altura); byte [] binaryData = getGrident (GrayData, ancho, altura); int index = 0; for (int fila = 1; fila <altura - 1; fila ++) {for (int col = 1; col <width - 1; col ++) {index = fila * ancho+col; int pixel = (binaryData [index] & 0xff); if (pixel> 0) {// operación de escaneo de radio int nindis = integer.max_value; int minRow = -1; int mincol = -1; int nr = 0; int nc = 0; int index2 = 0; for (int subrow = -raidus; subrow <= raidus; subrow ++) {nr = row+subrow; if (nr <0 || nr> = altura) {continuar; } for (int subcol = -raidus; subcol <= raidus; subcol ++) {nc = col+subcol; if (nc <0 || nc> = width) {continuar; } index2 = nr * width + nc; int value = (binaryData [index2] & 0xff); if (value == 0) {int Distance = DistancEcolor (image.getRgb (nc, nr), image.getrgb (col, row)); if (distancia <mindis) {mindis = distancia; minRow = nr; mincol = nc; }}}} resultimg.setRgb (col, fila, image.getrgb (mincol, minrow)); }}} return resultimg; } public static int distancecolor (int rgb, int rgb2) {// colore one int r1 = (rgb >> 16) & 0xff; int g1 = (rgb >> 8) y 0xff; int b1 = rgb & 0xff; // Color dos int r2 = (rgb2 >> 16) y 0xff; int g2 = (rgb2 >> 8) y 0xff; int b2 = rgb2 y 0xff; // Distancia int rr = r1 - r2; int gg = g1 - g2; int bb = b1 - b2; int sum = (int) math.sqrt (rr * rr + gg * gg + bb * bb); suma de retorno; } public static byte [] getgrayData (int [] inpixels, int width, int hight) {// Image Grayscale byte [] Outpixels = new Byte [Width * Height]; int index = 0; for (int row = 0; fila <altura; fila ++) {int tr = 0, tg = 0, tb = 0; for (int col = 0; col <width; col ++) {index = row * width+col; tr = (inpixels [índice] >> 16) y 0xff; tg = (inpixels [índice] >> 8) y 0xff; tb = inpixels [índice] & 0xff; int gris = (int) (0.299 * tr + 0.587 * tg + 0.114 * tb); OUTPIXELS [index] = (byte) (gris & 0xff); }} return outpixels; } public static byte [] getGrident (byte [] inpixels, int width, int hight) {byte [] outpixels = new byte [width * altura]; int index = 0; for (int fila = 0; fila <high; fila ++) {int tr = 0; for (int col = 0; col <width; col ++) {if (fila == 0 || col == 0 || (fila == altura - 1) || (col == ancho - 1)) {index = row * width+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 = row+sr; int ncol = col + sc; if (nrow <0 || nrow> = altura) {nrow = 0; } if (ncol <0 || ncol> = width) {ncol = 0; } index = nrow * width + ncol; tr = (inpixels [índice] & 0xff); xg + = x_sobel [sr + 1] [sc + 1] * tr; yg + = y_sobel [sr + 1] [sc + 1] * tr; }} índice = fila * ancho + col; int g = (int) math.sqrt (xg * xg + yg * yg); OUTPIXELS [index] = (byte) (abrazadera (g) y 0xff); }} return outpixels; } Los valores constantes que deben definirse son los siguientes:
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; La adquisición de gradiente utiliza el operador Sobol. El código para escanear el objeto BufferedImage después del procesamiento para obtener el color principal es el siguiente:
int width = result.getWidth (); int altura = resultado.getheight (); MAP <Integer, Integer> ColorIndexMap = new HashMap <Integer, Integer> (); for (int row = 0; fila <hight; row ++) {for (int col = 0; col <width; col ++) {int pixelvalue = result.getRgb (col, fila); if (! colorindexmap.containskey (pixelvalue)) {colorindexmap.put (pixelValue, pixelValue); }}} // ahora escanee el valor de píxel // return system.out.println ("número de color =" + colorindexmap.size ()); return colorIndexMap.KeySet (). ToArray (nuevo entero [0]); El código de prueba es el siguiente:
public static void main (string [] args) {archivo archivo = nuevo archivo ("d: //gloomyfish//bigmonkey.png"); Archivo resultFile = nuevo archivo ("d: //gloomyfish//result.png"); intente {bufferedImage image = imageIO.read (archivo); Resultado de BufferedImage = removeBlendPixels (imagen, block_pixel_radius); ImageIO.Write (resultado, "PNG", ResultFile); Integer [] Colors = ExtractColors (resultado); System.out.println ("Total Colors:" + Colors.length); } catch (ioException e) {E.PrintStackTrace (); }}Nota: La clave principal es ingresar el tamaño correcto de la imagen a procesar. Este tamaño de radio está relacionado con el tamaño real de la imagen, y el algoritmo se puede optimizar un paso más en una versión que no depende del parámetro RADIUS, hasta que encuentre un píxel igual a cero.
Lo anterior es todo el contenido de este artículo. Espero que sea útil para el aprendizaje de todos y espero que todos apoyen más a Wulin.com.