How to get the main color in a color image

Source: Internet
Author: User

A: Basic ideas

For a color image of the RGB color space, a lot of time we want to get the image through the program has several main colors, but for the general image, at the junction of the color through the pixel mix to achieve a natural transition, so directly scan the image of the pixel value, the different color values may be up to hundreds of and the actual image may only be the main color, how to remove those mixed color, accurately extract the main color of the four-way, according to the characteristics of general images, the image at different color boundaries of the mix of different color values, which can be regarded as one of the edge characteristics of the image, Therefore, it is possible to extract these mixed pixels from a simple edge gradient algorithm to get an array of pixel values, then scan each pixel value, look for the pixels around the specified radius parameter r, find zero, and the value of the pixel closest to the center pixel as the pixel value of the center pixel, and the output number of pixels after the scan is over. Then a linear scan of the array can get the main color RGB value of the picture.

Two: implementation steps

1. Input image array, grayscale of color image

2. For image after grayscale, calculate image gradient, use Sobol operator here

3. For each non-0 pixel to achieve a radius of r in the range of the scan, to find the most similar to zero of the original pixel value

4. A simple scan of the array to get the main color

Where the parameter r is to find the most appropriate value according to the different scenarios. The greater the theoretical image, the greater the value of r should be, otherwise the algorithm will be inaccurate.

Three: original and running effect


Original


Four main colors extracted after the algorithm was run

Four: The algorithm implements the source code

public static BufferedImage Removeblendpixels (bufferedimage image, int raidus) {int width = image.getwidth (); int height =  Image.getheight (); int[] pixels = new Int[width * HEIGHT];GETRGB (image, 0, 0, width, height, pixels);//Create processing result bufferedimage Resultimg = createcompatibledestimage (image, NULL); Setrgb (resultimg, 0, 0, width, height, pixels);//Grayscale and gradient byte[] Gray Data = Getgraydata (pixels, width, height); byte[] BinaryData = Getgrident (graydata, width, height); int index = 0;for (int r ow = 1; Row < height-1; row++) {for (int col = 1; col < width-1; col++) {index = row * width + col;int pixel = (Binarydata[index] & 0xff) if (Pixel > 0) {//RADIUS scan operation int Mindis = Integer.max_value;int Minrow = -1;int Mincol = -1;int NR = 0;int NC = 0;int Inde x2 = 0;for (int subrow =-raidus; Subrow <= Raidus; subrow++) {nr = row + subrow;if (Nr < 0 | | nr >= height) {con Tinue;} for (int subcol =-raidus; Subcol <= Raidus; subcol++) {nc = col + subcol;if (NC < 0 | | NC >= width) {Continue;} Index2 = nr * Width + nc;int value = (Binarydata[index2] & 0xff); if (value = = 0) {int distance = Distancecolor (image.g Etrgb (NC, NR), Image.getrgb (col, Row)); if (distance < Mindis) {Mindis = Distance;minrow = Nr;mincol = NC;}}} Resultimg.setrgb (col, Row, Image.getrgb (Mincol, Minrow));}}} return resultimg;} public static int Distancecolor (int rgb, int rgb2) {//Color oneint r1 = (RGB >> +) & 0xff;int G1 = (RGB &GT;&G T 8) & 0xff;int B1 = RGB & 0xff;//Color twoint r2 = (rgb2 >> +) & 0xff;int g2 = (rgb2 >> 8) &  0xff;int b2 = rgb2 & 0xff;//distanceint rr = r1-r2;int GG = g1-g2;int BB = b1-b2;int sum = (int) math.sqrt (RR * RR + GG * gg + bb * bb); return sum;} public static byte[] Getgraydata (int[] inpixels, int width, int height) {//image grayscale byte[] Outpixels = new Byte[width * Heigh T];int index = 0;for (int row = 0; row < height; row++) {int tr = 0, TG = 0, TB = 0;for (int col = 0; col < width; c ol++) {index = row * Width + COL;TR = (Inpixels[index] >>) & 0xff;tg = (Inpixels[index] >> 8) & 0xff;tb = Inpixels[index] & 0xff;int Gray = (int) (0.299 * TR + 0.587 * TG + 0.114 * TB); Outpixels[index] = (byte) (Gray & 0xFF);}} return outpixels;} public static byte[] Getgrident (byte[] inpixels, int width, int height) {byte[] outpixels = new Byte[width * Height];int I Ndex = 0;for (int row = 0; row < height; row++) {int tr = 0;for (int col = 0; col < width; col++) {if (row = = 0 | | c OL = = 0 | | (row = = height-1) | | (col = = width-1)) {index = row * width + col;outpixels[index] = (byte) (0x00); continue;} 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 >= height) {nrow = 0;} if (Ncol < 0 | | Ncol >= width) {ncol = 0;} index = nrow * width + ncol;tr = (Inpixels[index] & 0xff); XG + X_SOBEL[SR + 1][SC + 1] * Tr;yg + + Y_SOBEL[SR + 1][SC + 1] * TR;}} index = row * Width+ Col;int g = (int) math.sqrt (XG * xg + YG * YG); Outpixels[index] = (byte) (Clamp (g) & 0xFF);}} return outpixels;}
The constant values you need to define are as follows:

public static final int[][] X_sobel = new int[][] {{-1,-2,-1}, {0, 0, 0}, {1, 2, 1}};p ublic static final int[][] Y_sobel = new int[][] {{-1, 0, 1}, {-2, 0, 2}, {-1, 0, 1}};p ublic static final int block_pixel_radius = 5;
The gradient is obtained using the Sobol operator, and the code to retrieve the main color for the subsequent BufferedImage object scan is as follows:

int width = result.getwidth (); int height = result.getheight (); Map<integer, integer> colorindexmap = new Hashmap<integer, integer> (); for (int row = 0; row < height; row++ {for (int col = 0; col < width; col++) {int pixelvalue = Result.getrgb (col, row); if (!colorindexmap.containskey (pixel Value) {colorindexmap.put (Pixelvalue, Pixelvalue);}}} Now scan pixel value//return resultSystem.out.println ("number of color =" + colorindexmap.size ()); return Colorindexma P.keyset (). ToArray (new integer[0]);
The test code is as follows:

public static void Main (string[] args) {File file = new file ("D:\\gloomyfish\\bigmonkey.png"); File Resultfile = new file ("D:\\gloomyfish\\result.png"); try {bufferedimage image = Imageio.read (File); BufferedImage result = Removeblendpixels (image, Block_pixel_radius); Imageio.write (result, "PNG", resultfile); Integer [] colors = extractcolors (result); SYSTEM.OUT.PRINTLN ("Total colors:" + colors.length);} catch (IOException e) {e.printstacktrace ();}}
Note: The main key is to treat the image input to the correct size of the radius, the radius of the size of the image is related to the actual size, and the algorithm can be further optimized to not rely on the radius parameters of the version, know to find a pixel equal to zero.

How to get the main color in a color image

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.