我一直在浏览网页上的算法,该算法分析图像并返回最不同和最常用的颜色 - 但没有运气。
例如;
如果我在25% red (255,0,0)
,RGB
和50% fully blue (0,0,255)
25% pink (255,0,255)
的位图
我希望算法返回在使用中排序的这三种(或更多,取决于可用颜色)颜色,所以:
1. Blue
2. Red / Pink
3. Red / Pink
任何人都知道某种方式我可以开始这个吗?也许有些文章需要阅读等等。我从未在C#中使用过像这样的图像。
答案 0 :(得分:1)
最常用的颜色
通过一点谷歌努力,你会发现直方图。如果您想将阴影用作单独的颜色,那么您有256^3
种颜色。因此要么使用一些动态列表,要么忽略几个最低有效位来降低数字。您还可以通过标准化颜色来更改动态范围。
并且其他所有内容都将矢量大小更改为Max
,例如
Max = 2^5-1 = 31
normalized color = color * Max / |color|
现在算法:
为所有颜色组合创建一个计数器表cnt
Max = 31
,的大小为2^15 = 32768
。将整个表设置为零。
int cnt[32768];
for (int i=0;i<32768;i++) cnt[i]=0;
浏览整个图像和每个像素
adr = (R) | (G<<5) | (B<<10)
)cnt[adr]++;
在此之后,您在cnt[]
中有直方图。所以现在索引按cnt
的值对其进行排序,你已经获得了按用途排序的颜色
最不同的颜色
你会如何定义它?我会使用直方图中的数据并搜索其中2种颜色之间的max
距离(标准化后)
d = |color1 - color2|
不需要sqrt
...如果您使用d^2
,您将获得相同的结果。忽略cnt[adr]==0
(未使用的颜色)的所有条目。这仍然是O(n^2)
...更像是~T(n*n/2)
...在运行时术语中,但n
不是图像中的像素数。相反,它只是图像中不同使用颜色的数量远远少于...也是在索引排序直方图和删除/忽略所有cnt[adr]==0
条目甚至情人之后。
答案 1 :(得分:0)
如果我正确理解了这个问题,这可能对你有所帮助(当然你必须根据你的需要阅读数据):
/// <summary>
/// Gets the bitmap image color statistics
/// </summary>
/// <param name="bit">The bitmap image you want to analyze</param>
/// <returns></returns>
public static List<KeyValuePair<Color, int>> GetStatistics(Bitmap bit)
{
Dictionary<Color, int> countDictionary = new Dictionary<Color, int>();
for (int wid = 0; wid < bit.Width; wid++)
{//for every column in the image
for (int he = 0; he < bit.Height; he++)
{//for every row in the image
//Get the color of the pixel reached (i.e. at the current column and row)
Color currentColor = bit.GetPixel(wid, he);
//If a record already exists for this color, set the count, otherwise just set it as 0
int currentCount = (countDictionary.ContainsKey(currentColor) ? countDictionary[currentColor] : 0);
if (currentCount == 0)
{//If this color doesnt already exists in the dictionary, add it
countDictionary.Add(currentColor, 1);
}
else
{//If it exists, increment the value and update it
countDictionary[currentColor] = currentCount + 1;
}
}
}
//order the list from most used to least used before returning
List<KeyValuePair<Color, int>> l = countDictionary.OrderByDescending(o => o.Value).ToList();
return l;
}
}