我有这个工作,但它在 jpeg 图像上太慢了,还需要一些改变.
I have this one working but it is so damn slow on jpeg images and also needs some changing.
我需要知道图像中的各个颜色(RGB 的容差为 +/- 1)以及该颜色在图像中的百分比.
I need to know the individual colours in an image (with a tolerance of +/- 1 for RGB) and the % of the image that is that colour.
所以如果图像是黑白的,它会说类似白色:74%黑色:26%
so if an image was black and white it would say something like White : 74% Black : 26%
下面的代码像我说的那样工作,但我还需要添加一个容差系统,我不知道该怎么做.
The code below works like I said but I need to add a tolerance system as well and I have no idea on how I would do that.
private Dictionary<string, string> getPixelData(Bitmap image)
{
Dictionary<string, string> pixelData = new Dictionary<string, string>();
//int col, row;
//int r, g, b;
Color pixel;
double offset = 0.000001;
int hmm = (image.Height * image.Width);
double current = 0;
offset = 100 / double.Parse(hmm.ToString());// 0.01;// 100 / (image.Height * image.Width) * 10000;
try
{
for (int i = 0; i < image.Height; i++)
{
for (int j = 0; j < image.Width; j++)
{
current = current + offset;
pixel = image.GetPixel(i, j);
pixelData.Add(i + "," + j, (pixel.R.ToString() + " " + pixel.G.ToString() + " " + pixel.B.ToString()));
pBarprocess.Value = int.Parse(Math.Floor(current).ToString());
pBarprocess.Update();
Application.DoEvents();
}
}
}
catch (Exception ex)
{
MessageBox.Show("Unable to parse image " + ex);
}
return pixelData;
}
其他功能
private void btnProcess_Click(object sender, EventArgs e)
{
pBarprocess.Value = 0;
pBarprocess.Enabled = false;
Bitmap foo = Bitmap.FromFile(@txtFileName.Text) as Bitmap;
Dictionary<string, string> pixelData = new Dictionary<string, string>();
lblProcess.Text = "Processing pixel map";
pixelData = getPixelData(foo);
lblProcess.Text = "Calculating Density";
lblProcess.Update();
var distinctList = pixelData.Values.Distinct().ToList();
Console.WriteLine("DL = " + distinctList.Count);
double offset = 100 / double.Parse(distinctList.Count.ToString());
double current = 0;
foreach (var value in distinctList)
{
IEnumerable<string> query = pixelData.Values.Where(fruit => fruit == value);
double perc = (double.Parse(query.Count().ToString()) / double.Parse(pixelData.Count.ToString())) * 100;
Console.WriteLine(value + " = " + query.Count() + "(" + perc + "%)");
txtAnalysis.Text = "Colour " + value + " : " + query.Count() + " (" + perc.ToString() + "%)
" + txtAnalysis.Text;
txtAnalysis.Update();
pBarprocess.Value = int.Parse(Math.Floor(current).ToString());
pBarprocess.Update();
Application.DoEvents();
}
lblProcess.Text = "Finished.";
pBarprocess.Value = 0;
pBarprocess.Enabled = false;
}
GetPixel 并不是访问图像数据的真正快捷方式.使用 LockBits 方法.
GetPixel is not really a fast way to access image data. Use the LockBits method.
好吧,您正在用字符串做很多事情.以这种方式构建 pixelData Dictionary 非常无用,为什么不立即处理不同的颜色?颜色是一个不可变的结构体,所以它已经是我们字典的一个很好的键了.
Well you're doing a lot of things with strings. Building the pixelData Dictionary that way is pretty useless, why don't you process the distinct colors right away? Color is an immutable struct, so that's a good key for our dictionary already.
Dictionary<Color, int> frequency = new Dictionary<Color, int>();
for (int i = 0; i < image.Height; i++) {
for (int j = 0; j < image.Width; j++) {
pixel = image.GetPixel(i, j);
if (frequency.ContainsKey(pixel)) frequency[pixel]++;
else frequency.Add(pixel, 1);
}
}
// and finally
int totalPixels = image.Width * image.Height;
foreach (var kvp in frequency) {
Console.WriteLine("Color (R={0},G={1},B={2}): {3}", kvp.Key.R, kvp.Key.G, kvp.Key.B, kvp.Value / (double)totalPixels);
}
这应该可以,除非您想使其更快并使用 LockBits 而不是 GetPixel.
And that should do it, except when you want to make it even faster and use LockBits instead of GetPixel.
其他一些观察:
int hmm = (image.Height * image.Width);
double offset = 100 / double.Parse(hmm.ToString());
您使用了一种非常奇怪且缓慢的从 int 转换为 double 的方法.你可以只写 double offset = 100/(double)hmm; 并且它是一样的(你也可以写 100.0 而不是 100,编译器会为你创建一个 double 所以你不需要投嗯).
You're using a very strange and slow way of casting from int to double. You can just write double offset = 100 / (double)hmm; and it's the same (you could also write 100.0 and not 100 and the compiler will create a double for you so you don't need to cast hmm).
这让我笑了:
IEnumerable<string> query = pixelData.Values.Where(fruit => fruit == value);
为什么是水果!?好像你从某个地方复制了这个.
Why fruit!? Seems like you copied this from somewhere.
这篇关于获取图像中每种颜色的使用百分比的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持html5模板网!
右键单击 Silverlight 4 应用程序中的列表框Right-click on a Listbox in a Silverlight 4 app(右键单击 Silverlight 4 应用程序中的列表框)
WPF c# webbrowser 在顶部菜单上滚动WPF c# webbrowser scrolls over top menu(WPF c# webbrowser 在顶部菜单上滚动)
C# 控制台应用程序 - 如何制作交互式菜单?C# Console app - How do I make an interactive menu?(C# 控制台应用程序 - 如何制作交互式菜单?)
如何避免在 .NET Windows Forms 中创建重复的表单?How to avoid duplicate form creation in .NET Windows Forms?(如何避免在 .NET Windows Forms 中创建重复的表单?)
UI自动化控制桌面应用程序并单击菜单条UI Automation Control Desktop Application and Click on Menu Strip(UI自动化控制桌面应用程序并单击菜单条)
删除菜单项周围的细边框Removing thin border around the menuitems(删除菜单项周围的细边框)