【问题标题】:Averaging color of an Image平均图像的颜色
【发布时间】:2012-07-28 07:43:23
【问题描述】:

我正在使用此代码来计算图像的平均颜色,但这并没有按预期工作。结果不准确。 如何找到图像的平均颜色?

Private Sub btnAvg_Click() Handles btnAvg.Click
    Dim x, y As Integer
    bmp = New Bitmap(picBox.Tag.ToString)

    For y = picBox.Top To picBox.Bottom
        For x = picBox.Left To picBox.Right
            With bmp.GetPixel(x, y)
                totalR = totalR + .R : totalG = totalG + .G : totalB = totalB + .B
            End With
        Next x
    Next y

    avgR = totalR / ((picBox.Bottom - picBox.Top) * (picBox.Right - picBox.Left))
    avgG = totalG / ((picBox.Bottom - picBox.Top) * (picBox.Right - picBox.Left))
    avgB = totalB / ((picBox.Bottom - picBox.Top) * (picBox.Right - picBox.Left))
End Sub

我正在寻找一个准确率超过 80% 的高速结果。这不是一个重复的问题,因为其他问题仅涉及 C#

【问题讨论】:

  • This is not a duplicate question as other questions deals with C# only - 我真的不会说这原谅你。
  • GetPixel 非常慢。锁定位图并读取返回的字节数组。 msdn.microsoft.com/en-us/library/5ey6h79d.aspx
  • @asawyer 我也可以克服缩略图的问题:P
  • @DarinDimitrov 是的,你是对的 :D 但我也尝试过代码转换器!
  • 您发布的代码有什么问题?是太慢了,还是结果不准确?您的具体问题不清楚。

标签: vb.net vb.net-2010


【解决方案1】:

一般来说,平均颜色没有多大意义。粉红色和海军黄色的平均值是多少?您现在计算它的方式会产生完全不同的颜色。

您需要在不同的色彩空间中工作。 HSB 是一种易于使用的工具,并由 Color 类型直接支持。尽管它不处理人眼的强烈非线性颜色感知。 Color.GetHue() 返回色调,一个与颜色成正比的值。您还应该创建一个直方图,这样照片的背景就不会过多地干扰结果。或者至少从照片的中心向外工作。这是否足以检测肤色是相当值得怀疑的。

【讨论】:

  • +1 提供一些想法,但请建议如何解决问题[一些算法或代码]:P!
  • 对不起,我不能为你做你的工作。这不是我会承担的项目,像这样的图像处理是出了名的困难。
  • 这个问题需要更多的思考......正如汉斯所说,平均在成像中没有意义。这将假设整个图像同样重要。在人像中,重要的是脸,而不是背景!所以你需要说明为什么你需要一个平均值?例如,降低质量、添加或管理图像效果、压缩甚至排序图像都在平均水平的某个部分起作用,但每个都有特定的算法。这些算法具有平均意义。也看看这个:(stackoverflow.com/questions/5050250/…)
【解决方案2】:

这应该可行:

Private Function getAverageColor(ByVal imageFilePath As String) As Color
    Dim bmp As New Bitmap(imageFilePath)
    Dim totalR As Integer = 0
    Dim totalG As Integer = 0
    Dim totalB As Integer = 0
    For x As Integer = 0 To bmp.Width - 1
        For y As Integer = 0 To bmp.Height - 1
            Dim pixel As Color = bmp.GetPixel(x, y)
            totalR += pixel.R
            totalG += pixel.G
            totalB += pixel.B
        Next
    Next
    Dim totalPixels As Integer = bmp.Height * bmp.Width
    Dim averageR As Integer = totalR \ totalPixels
    Dim averageg As Integer = totalG \ totalPixels
    Dim averageb As Integer = totalB \ totalPixels
    Return Color.FromArgb(averageR, averageg, averageb)
End Function

【讨论】:

  • 你是说这不起作用,还是说它起作用但你不明白为什么?
  • 1.我认为你的代码和我的代码是一样的。 2. 结果不理想。 也许问题出在算法上,找到了粉红色和海军黄色的平均值
  • 同意,这是基于您实际上想要所有像素的平均 R、G 和 B 的前提。如果这不是您想要的,那么这些都不是解决方案。但是,您的代码和我的代码之间的主要区别在于,我的代码从 0 循环到位图的高度和宽度,而不是 PictureBox 控件的顶部和底部。使用图片框的位置和大小将无法正常工作,除非它的位置为 0、0 并且大小与位图完全匹配。
猜你喜欢
  • 1970-01-01
  • 2013-06-04
  • 2012-09-06
  • 1970-01-01
  • 1970-01-01
  • 2015-06-05
  • 2014-02-15
  • 2011-02-02
相关资源
最近更新 更多