vb.net 教程 5-13 图像处理之像素处理 8-1

版权声明:本文为博主原创文章,转载请在显著位置标明本文出处以及作者网名,未经作者允许不得用于商业目的。
昨天看一个朋友发的旅游照片,照片处理成了灰度,但是留着蓝色。

突然想到以前的Lumia830手机上也有这样一款软件可以处理颜色,只留下红色、绿色或者蓝色这样的单一颜色。

于是写了以下的代码,为了便于理解,这里先用的像素的方法,以后有机会我再补上内存的方法。

运行时候的效果还不错,先来看看效果:

在写这个代码之前,我先考虑了主要颜色的算法,所以有了初始设定:

    红色 R>128 R-G>100 & R-B>100
    绿色 G>128 G-R>100 & G-B>100
    蓝色 B>128 B-R>100 & B-G>100

    紫色 R>128 B>128 B>=R  R-G>128 B-R>128
    黄色 R>190 G>190 R>=G  R-B>128 G-B>128
    普蓝 G>190 B>190 B>=G  B-R>128 G-R>128

但是当代码写好后发现效果不理想,但是颜色又不是线性分布的,所以在这个基础上做了改动:

    Private Function getSingleColor(ByVal rgb As Color) As String
        Dim R, G, B As Integer
        R = rgb.R
        G = rgb.G
        B = rgb.B
        If (R > 128) AndAlso (R - G > 30) AndAlso (R - B > 30) Then Return "R"
        If (G > 80) AndAlso (G - R > 5) AndAlso ((G - B > 20) Or (B - G) < 10) Then Return "G"
        If (B > 80) AndAlso (B - R > 50) AndAlso (B - G > 30) Then Return "B"
        If (R > 128) AndAlso (B > 128) AndAlso (R - G > 30) AndAlso (B - G > 30) Then Return "P"
        If (R > 140) AndAlso (G > 120) AndAlso (Math.Abs(G - R) < 40) AndAlso (R - B > 80) AndAlso (G - B > 80) Then Return "Y"
        If (G > 180) AndAlso (B > 180) AndAlso ((B >= G) Or (G - B) < 10) AndAlso (B - R > 40) AndAlso (G - R > 40) Then Return "C"
 
        Return "N"
    End Function
上述代码过程中,按照颜色划分了6个色系,分别是 红R、绿G、蓝B、紫P、黄Y、普蓝C(我这边是这么称呼的,也又叫做天蓝色),其他N(也就是需要处理为灰度的颜色)。

说明一下,以下是个人一些不成熟的想法:

1、红绿蓝不说了,三原色;紫色对应的是(R=255;G=0;B=255)、黄色对应的是(R=255;G=255;B=0);普蓝色对应的是(R=0;G=255;B=255),然后就是白色(R=255;G=255;B=255)、黑色(R=0;G=0;B=0)以及灰色(按照均值计算,请参看《vb.net 教程 5-13 图像处理之像素处理 3》)

2、开始想的是只按照绝对的RGB颜色值来划分,例如单纯的取红色(R=255,G=0,B=0),那么和红色接近的颜色(R=236,G=0,B=0)人眼看到的也算是红色的。是不是也应该算?

3、颜色其实也是三原色交错分布的,如果单纯的将R、G、B值记录到数据库来作为划分的依据,工作量比较大。

4、尽量使用简单的方法来做。

以下是处理“红色”比较完整的代码:

   '红色按钮
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim pSourceColor As Color
        Dim pDestColor As Color
 
        Dim destImg As New Bitmap(sourceImg.Width, sourceImg.Height)
        For i As Integer = 0 To sourceImg.Width - 1
            For j As Integer = 0 To sourceImg.Height - 1
                pSourceColor = sourceImg.GetPixel(i, j)
                If getSingleColor(pSourceColor) = "R" Then
                    pDestColor = pSourceColor
                Else
                    pDestColor = getAverage(pSourceColor)
                End If
                destImg.SetPixel(i, j, pDestColor)
            Next
        Next
        picDest.Image = destImg
    End Sub
 
    '计算所属色系,并返回色系缩写字母
    Private Function getSingleColor(ByVal rgb As Color) As String
        Dim R, G, B As Integer
        R = rgb.R
        G = rgb.G
        B = rgb.B
        If (R > 128) AndAlso (R - G > 30) AndAlso (R - B > 30) Then Return "R"
        If (G > 80) AndAlso (G - R > 5) AndAlso ((G - B > 20) Or (B - G) < 10) Then Return "G"
        If (B > 80) AndAlso (B - R > 50) AndAlso (B - G > 30) Then Return "B"
        If (R > 128) AndAlso (B > 128) AndAlso (R - G > 30) AndAlso (B - G > 30) Then Return "P"
        If (R > 140) AndAlso (G > 120) AndAlso (Math.Abs(G - R) < 40) AndAlso (R - B > 80) AndAlso (G - B > 80) Then Return "Y"
        If (G > 180) AndAlso (B > 180) AndAlso ((B >= G) Or (G - B) < 10) AndAlso (B - R > 40) AndAlso (G - R > 40) Then Return "C"
 
        Return "N"
    End Function
 
    '计算灰度均值,返回灰度颜色
    Private Function getAverage(ByVal rgb As Color) As Color
        Dim R, G, B As Integer
        Dim gray As Integer
 
        R = rgb.R
        G = rgb.G
        B = rgb.B
        gray = (R + G + B) / 3
 
        Dim newColor As Color
        newColor = Color.FromArgb(gray, gray, gray)
        Return newColor
    End Function
 

    Dim sourceImg As Bitmap
    ‘载入图片
    Private Sub btnLoadimg_Click(sender As Object, e As EventArgs) Handles btnLoadimg.Click
        Dim filename As String
        If OpenFileDialog1.ShowDialog = DialogResult.OK Then
            filename = OpenFileDialog1.FileName
        Else
            Exit Sub
        End If
        sourceImg = Image.FromFile(filename)
        picSource.Image = sourceImg
    End Sub
 

其他几种颜色的代码:

    '绿色
    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Dim pSourceColor As Color
        Dim pDestColor As Color
        Dim destImg As New Bitmap(sourceImg.Width, sourceImg.Height)
        For i As Integer = 0 To sourceImg.Width - 1
            For j As Integer = 0 To sourceImg.Height - 1
                pSourceColor = sourceImg.GetPixel(i, j)
                If getSingleColor(pSourceColor) = "G" Then
                    pDestColor = pSourceColor
                Else
                    pDestColor = getAverage(pSourceColor)
                End If
 
                destImg.SetPixel(i, j, pDestColor)
            Next
        Next
        picDest.Image = destImg
    End Sub
    '蓝色
    Private Sub Button3_Click(sender As Object, e As EventArgs) Handles Button3.Click
        Dim pSourceColor As Color
        Dim pDestColor As Color
        Dim destImg As New Bitmap(sourceImg.Width, sourceImg.Height)
        For i As Integer = 0 To sourceImg.Width - 1
            For j As Integer = 0 To sourceImg.Height - 1
                pSourceColor = sourceImg.GetPixel(i, j)
                If getSingleColor(pSourceColor) = "B" Then
                    pDestColor = pSourceColor
                Else
                    pDestColor = getAverage(pSourceColor)
                End If
 
                destImg.SetPixel(i, j, pDestColor)
            Next
        Next
        picDest.Image = destImg
    End Sub
    '紫色
    Private Sub Button4_Click(sender As Object, e As EventArgs) Handles Button4.Click
        Dim pSourceColor As Color
        Dim pDestColor As Color
        Dim destImg As New Bitmap(sourceImg.Width, sourceImg.Height)
        For i As Integer = 0 To sourceImg.Width - 1
            For j As Integer = 0 To sourceImg.Height - 1
                pSourceColor = sourceImg.GetPixel(i, j)
                If getSingleColor(pSourceColor) = "P" Then
                    pDestColor = pSourceColor
                Else
                    pDestColor = getAverage(pSourceColor)
                End If
 
                destImg.SetPixel(i, j, pDestColor)
            Next
        Next
        picDest.Image = destImg
    End Sub
    '黄色
    Private Sub Button5_Click(sender As Object, e As EventArgs) Handles Button5.Click
        Dim pSourceColor As Color
        Dim pDestColor As Color
        Dim destImg As New Bitmap(sourceImg.Width, sourceImg.Height)
        For i As Integer = 0 To sourceImg.Width - 1
            For j As Integer = 0 To sourceImg.Height - 1
                pSourceColor = sourceImg.GetPixel(i, j)
                If getSingleColor(pSourceColor) = "Y" Then
                    pDestColor = pSourceColor
                Else
                    pDestColor = getAverage(pSourceColor)
                End If
 
                destImg.SetPixel(i, j, pDestColor)
            Next
        Next
        picDest.Image = destImg
    End Sub
    '普蓝色
    Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
        Dim pSourceColor As Color
        Dim pDestColor As Color
        Dim destImg As New Bitmap(sourceImg.Width, sourceImg.Height)
        For i As Integer = 0 To sourceImg.Width - 1
            For j As Integer = 0 To sourceImg.Height - 1
                pSourceColor = sourceImg.GetPixel(i, j)
                If getSingleColor(pSourceColor) = "C" Then
                    pDestColor = pSourceColor
                Else
                    pDestColor = getAverage(pSourceColor)
                End If
 
                destImg.SetPixel(i, j, pDestColor)
            Next
        Next
        picDest.Image = destImg
    End Sub
 

由于.net平台下C#和vb.NET很相似,本文也可以为C#爱好者提供参考。

学习更多vb.net知识,请参看vb.net教程目录
————————————————
版权声明:本文为CSDN博主「VB.Net」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

上一篇:Linux常用命令学习


下一篇:vb.net 教程 5-13 图像处理之像素处理 8-2