获取图像中每种颜色的使用百分比

发布于 2024-12-11 17:10:26 字数 2705 浏览 0 评论 0原文

我有这个工作,但它在 jpeg 图像上太慢了,还需要一些改变。

我需要知道图像中的各个颜色(RGB 的容差为 +/- 1)以及该颜色占图像的百分比。

所以如果图像是黑白的,它会说类似 白色:74% 黑色:26%

下面的代码就像我说的那样工作,但我还需要添加一个容差系统,但我不知道如何做到这一点。

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() + "%)\r\n" + 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;
}

I have this one working but it is so damn slow on jpeg images and also needs some changing.

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.

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;
}

And the other function

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() + "%)\r\n" + 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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

月下客 2024-12-18 17:10:26

GetPixel 并不是真正快速访问图像数据的方法。使用 LockBits 方法。

编辑:

嗯,你正在用字符串做很多事情。以这种方式构建像素数据字典是毫无用处的,为什么不立即处理不同的颜色呢?颜色是一个不可变的结构,所以这已经是我们字典的一个很好的键。

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。

其他一些观察结果:

int hmm = (image.Height * image.Width);
double offset = 100 / double.Parse(hmm.ToString());

您使用了一种非常奇怪且缓慢的方式从 int 转换为 double 。你可以只写double offset = 100 / (double)hmm;,它是一样的(你也可以写100.0而不是100,编译器会为你创建一个double,所以你不需要演员嗯)。

这让我笑了:

IEnumerable<string> query = pixelData.Values.Where(fruit => fruit == value);

为什么是水果!?看来你是从某处复制的。

GetPixel is not really a fast way to access image data. Use the LockBits method.

EDIT:

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);
}

And that should do it, except when you want to make it even faster and use LockBits instead of GetPixel.

Some other observations:

int hmm = (image.Height * image.Width);
double offset = 100 / double.Parse(hmm.ToString());

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).

This made me laugh:

IEnumerable<string> query = pixelData.Values.Where(fruit => fruit == value);

Why fruit!? Seems like you copied this from somewhere.

喵星人汪星人 2024-12-18 17:10:26

这似乎是更大的图像处理目标的一部分。 Aforge 框架 是 .NET 中图像分析和处理的首选,而且速度非常快。它可能已经具有您需要的代码。

您提到了容差系统 - 对我来说,这听起来像您需要量化 - 颜色舍入

一旦你有了量化的位图,你就可以制作一个长度与调色板大小相匹配的数组,LockBits位图,并使用每个像素的颜色索引作为每个像素的数组索引来累积使用统计信息。

您能否分享有关此代码目标的更多信息?它到底应该做什么?

It seems like this is part of a larger image processing goal. The Aforge framework is the go-to choice for image analysis and processing in .NET, and it is extremely fast. It's likely that it already has the code you need.

You mentioned a tolerance system - to me, this sounds like you need quantization - color rounding.

Once you have a quantized bitmap, you can make and array with a length that matches the palette size, LockBits the bitmap, and use the color index for each pixel as the array index for each pixel to accumulate usage statistics.

Could you share more information about your goals for this code? What it is supposed to do exactly?

何处潇湘 2024-12-18 17:10:26

我计算图像颜色百分比的方法如下,这样我们就可以

计算任何颜色的任何像素百分比。

1.在这个位置使用一个名为“ImageJ”的软件,它是免费的。

http://rsb.info.nih.gov/ij/download.html

2.使用此工具打开图像

  1. 进入“分析”菜单并选择“直方图”,它将打开直方图窗口

4.在直方图窗口中,单击左下角的“列表”按钮,它将打开列表窗口

5.在列表窗口中选择“另存为”,这将将每种颜色的像素数保存在 0-256 之间

6. 对于面积测量,根据分辨率计算像素尺寸并乘以像素数

。使用 Excel 进行任何其他数值分析,尤其是数据透视表。

这是我使用的ImageJ软件、excel文件和屏幕截图。

https://www.mediafire.com/?htwk83rwgio4zds

My method of calculation of color percentage of an image is as follow, also in this way we can

calculate any percentage of pixels for any color.

1.Using a software named "ImageJ" at this location, it is free.

http://rsb.info.nih.gov/ij/download.html

2.Open an image with this tool

  1. Go to Analyze menu and select Histogram, it will open histogram window

4.In histogram window, on the bottom left side click "list" button, it will open list window

5.In the list window select "save as", this will save number of pixels per colors between 0-256

6.For area measurement calculate pixel dimension from resolution and multiply with the number of

pixels. Use excel any other numerical analysis, especially pivot tables.

Here is the ImageJ software, excel file I used, and a screenshot.

https://www.mediafire.com/?htwk83rwgio4zds

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文