PageRenderTime 53ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 1ms

/articles/machine-learning-sample-color-quantization-using-k-means-clustering.md

https://github.com/AndyRanZhao/azure-content
Markdown | 154 lines | 117 code | 37 blank | 0 comment | 0 complexity | 484c2023841a7de41f58b4ca00f3c714 MD5 | raw file
  1. <properties title="Azure Machine Learning Sample: Color quantization using K-Means clustering" pageTitle="Machine Learning Sample: Color quantization using K-Means clustering | Azure" description="A sample Azure Machine Learning experiment that evaluates using different K-Means clustering values for quantizing a color image." metaKeywords="" services="" solutions="" documentationCenter="" authors="garye" videoId="" scriptId="" />
  2. <tags ms.service="machine-learning" ms.workload="tbd" ms.tgt_pltfrm="na" ms.devlang="na" ms.topic="article" ms.date="01/01/1900" ms.author="garye" />
  3. #Azure Machine Learning Sample: Color quantization using K-Means clustering
  4. ##Problem description
  5. [Color quantization](http://en.wikipedia.org/wiki/Color_quantization "Color quantization") is the process of reducing the number of distinct colors in an image hence, compressing it. Normally, the intent is to preserve the color appearance of the image as much as possible, while reducing the number of colors, whether for memory limitations or compression.
  6. ##Data
  7. In this sample experiment, we are assuming any given 24-bit RGB image has 256 x 256 x 256 possible colors. And sure, we can build standard color histograms based on these intensity values. But another approach is to explicitly quantize the image and *reduce* the number of colors to say, 16 or 64. This creates a substantially smaller space and (ideally) less noise and variance. For this, we passed the pixel data (each pixel as a dataset row) to our K-Means clustering Module.
  8. ##Model
  9. The model is created as shown in the image below:
  10. ![Model][image1]
  11. We ran K-Means clustering with K=10 through 500 in 5 different branches. First we calculated the clusters and then aggregated the clustering to the mean of their pixels colors (using an R Script).
  12. Finally, we associated each pixel with the aggregated cluster color and sent the new image out in CSV format. Meanwhile, we also calculated the Root Mean Squared Difference of the new pixel colors with the original image and shown them in a R plot (using Execute R Script).
  13. ##Results
  14. We tested the outcome on different number of clusters (colors) as shown on the experiment model below. As it's visible the more clustering create higher quality images with less compression:
  15. <table>
  16. <tr><th>Original</th>
  17. <td><img alt="Original" src="./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2a.jpg"></td>
  18. </tr>
  19. <tr><th>K=10</th>
  20. <td><img alt="K=10" src="./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2b.png"></td>
  21. </tr>
  22. <tr><th>K=20</th>
  23. <td><img alt="K=20" src="./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2c.png"></td>
  24. </tr>
  25. <tr><th>K=50</th>
  26. <td><img alt="K=50" src="./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2d.png"></td>
  27. </tr>
  28. <tr><th>K=100</th>
  29. <td><img alt="K=100" src="./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2e.png"></td>
  30. </tr>
  31. <tr><th>K=500</th>
  32. <td><img alt="K=500" src="./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2f.png"></td>
  33. </tr>
  34. </table>
  35. We have also measured the accuracy using Root Mean Squared Difference to the Original Image Colors which can be seen from the second output port of the "Execute R Script" Module:
  36. ![Output of Execute R Script module][image3]
  37. As it's visible, the more color clusters, the more colors match the original images (better quality).
  38. ##Code to convert images to CSV and reverse
  39. In order to feed the images into ML Studio, we wrote a simple convertor code which can convert image files to a csv format that ML Studio can use, and also one which converts them back to an image. Please feel free to use the following code. In the future we are planning to add a module for reading in images as well.
  40. using System;
  41. using System.Collections.Generic;
  42. using System.Linq;
  43. using System.Text;
  44. using System.Threading.Tasks;
  45. using System.Drawing;
  46. using System.Drawing.Imaging;
  47. using System.IO;
  48. namespace Text2Image
  49. {
  50. class Program
  51. {
  52. static void img2csv(string img_path)
  53. {
  54. FileInfo img_info = new FileInfo(img_path);
  55. string destination_file_directory = img_info.DirectoryName + "\\";
  56. string destination_file_name = img_info.Name.Remove(img_info.Name.LastIndexOf('.'), 4);
  57. string destination_file_path = destination_file_directory + destination_file_name + ".csv";
  58. // Read the image
  59. Bitmap img = new Bitmap(img_path);
  60. // Create the CSV File and write the header values
  61. System.IO.StreamWriter file = new System.IO.StreamWriter(destination_file_path);
  62. file.WriteLine("X,Y,R,G,B");
  63. // Write the Pixel values
  64. for (int x = 0; x < img.Width; x++)
  65. for (int y = 0; y < img.Height; y++)
  66. {
  67. string line = x + "," + y + "," + img.GetPixel(x, y).R + "," + img.GetPixel(x, y).G + "," + img.GetPixel(x, y).B ;
  68. file.WriteLine(line);
  69. }
  70. file.Close();
  71. }
  72. static void csv2img(string csv_path)
  73. {
  74. FileInfo csv_info = new FileInfo(csv_path);
  75. string destination_file_directory = csv_info.DirectoryName + "\\";
  76. string destination_file_name = csv_info.Name.Remove(csv_info.Name.LastIndexOf('.'), 4);
  77. string destination_file_path = destination_file_directory + destination_file_name + ".png";
  78. // Read all the lines in the CSV file
  79. string[] lines = System.IO.File.ReadAllLines(csv_path);
  80. // set a new bitmap image with the provided width and height in the header
  81. string[] wh = lines.Last().Split(new Char[] { ' ', ',', '.', ':', '\t', '{', '}' });
  82. int img_width = Convert.ToInt32(wh[0])+1;
  83. int img_height = Convert.ToInt32(wh[1])+1;
  84. Bitmap bmp_img = new Bitmap(img_width, img_height);
  85. for (int i = 1; i < lines.Length ;i++ )
  86. {
  87. string[] values = lines[i].Split(new Char[] { ' ', ',', '.', ':', '\t', '{', '}' });
  88. if (values.Length < 3)
  89. continue;
  90. int x = Convert.ToInt16(values[0]);
  91. int y = Convert.ToInt32(values[1]);
  92. int r = Convert.ToInt32(values[2]);
  93. int g = Convert.ToInt32(values[3]);
  94. int b = Convert.ToInt32(values[4]);
  95. bmp_img.SetPixel(x, y, Color.FromArgb(r, g, b));
  96. }
  97. bmp_img.Save(destination_file_path);
  98. }
  99. static void Main(string[] args)
  100. {
  101. string source_path = args[1];
  102. FileInfo source_info = new FileInfo(source_path);
  103. if (source_info.Extension == ".csv")
  104. csv2img(source_path);
  105. else
  106. img2csv(source_path);
  107. }
  108. }
  109. }
  110. [image1]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image1.png
  111. [image2a]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2a.jpg
  112. [image2b]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2b.png
  113. [image2c]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2c.png
  114. [image2d]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2d.png
  115. [image2e]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2e.png
  116. [image2f]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image2f.png
  117. [image3]:./media/machine-learning-sample-color-quantization-using-k-means-clustering/image3.png