如何使用Golang对图片进行背景去除和色彩转换

背景

在处理图像时,有时需要将图片的背景去除或者进行色彩转换。本文将介绍如何使用Golang对图片进行背景去除和色彩转换。

背景去除

算法原理

常用的图像背景去除算法有GrabCut、深度图像、色彩空间分离等方法。本文采用的是GrabCut算法,该算法由Carsten Rother、Vladimir Kolmogorov 和 Andrew Blake提出,是一种基于能量最小化求解的图像置换方法。

首先,通过手动或者自动的方式指定前景和背景矩形,计算前景的值和背景的值。然后,将图像分割成两部分:前景和背景。接着,根据前景和背景的差距进一步分割图像,使得前景部分与背景部分的差距最小。

实现步骤

下面我们将演示如何使用Go语言对图片进行背景去除。具体实现过程如下:

读取图片

package main

import (

"fmt"

"image"

"os"

"github.com/disintegration/imaging"

)

func main() {

img, err := imaging.Open("input.jpg")

if err != nil {

fmt.Println("Open failed:", err)

os.Exit(1)

}

//...

}

    指定前景和背景矩形

    我们可以通过手动绘制矩形框指定前景和背景。下面的代码演示了如何在图片上绘制矩形框:

    // 设置前景矩形框

    fgRect := image.Rect(100, 100, 300, 300)

    // 设置背景矩形框

    bgRect := image.Rect(0, 0, 150, 150)

    // 给图片绘制矩形框

    img = imaging.DrawRect(img, fgRect, color.NRGBA{0, 255, 0, 255})

    img = imaging.DrawRect(img, bgRect, color.NRGBA{255, 0, 0, 255})

      计算前景和背景的值

      接下来,我们需要计算前景矩形框的值和背景矩形框的值。

      // 计算前景的值

      fg := imaging.Crop(img, fgRect)

      fgMean, fgStddev := calcMeanAndStddev(fg)

      // 计算背景的值

      bg := imaging.Crop(img, bgRect)

      bgMean, bgStddev := calcMeanAndStddev(bg)

      通过imaging包提供的Crop方法,我们可以将图像裁剪成任意大小的矩形。然后,我们可以使用自定义的方法calcMeanAndStddev计算矩形框的均值和标准差:

      func calcMeanAndStddev(img image.Image) (mean float64, stddev float64) {

      rgbaImg := imaging.Clone(img)

      var r, g, b, a float64

      var i int

      for y := 0; y < rgbaImg.Bounds().Dy(); y++ {

      for x := 0; x < rgbaImg.Bounds().Dx(); x++ {

      i++

      r, g, b, a = rgbaImg.At(x, y).RGBA()

      mean += float64(r + g + b) / 3.0

      }

      }

      if i != 0 {

      mean /= float64(i)

      }

      i = 0

      for y := 0; y < rgbaImg.Bounds().Dy(); y++ {

      for x := 0; x < rgbaImg.Bounds().Dx(); x++ {

      i++

      r, g, b, a = rgbaImg.At(x, y).RGBA()

      stddev += math.Pow((float64(r+g+b)/3.0)-mean, 2.0)

      }

      }

      if i != 0 {

      stddev = math.Sqrt(stddev / float64(i))

      }

      return mean, stddev

      }

      该函数的输出结果包括均值和标准差。

        分割图像

        将图片分割成前景部分和背景部分:

        // 根据前景和背景的值分割图像

        mask := imaging.Grayscale(imaging.Difference(img, fgMean))

        mask = imaging.AdjustBrightness(mask, -fgStddev*temperature)

        mask = imaging.Threshold(mask, 30)

        // 生成前景和背景图

        foreground := imaging.Blur(img, 10)

        background := imaging.Blur(img, 100)

        foreground = imaging.Overlay(background, foreground, mask, image.Pt(0, 0))

        以上代码使用imaging包提供的Difference方法,求得图像和前景值的差异。然后使用Grayscale方法,将图像转换为灰度图。使用AdjustBrightness方法,将差异值降低,最后使用Threshold方法,将低于阈值的像素点设置为黑色,高于阈值的像素点设置为白色。根据这个阈值,我们分割出了图像的前景部分和背景部分。

        接着,我们使用Blur方法,对前景和背景进行模糊处理。然后使用Overlay方法,将前景图像覆盖到背景图像的上方,生成最终的图像。

          保存图片

          最后,我们使用imaging.Save方法保存最终的图片。

          err = imaging.Save(foreground, "output.jpg")

          if err != nil {

          fmt.Println("Save failed:", err)

          os.Exit(1)

          }

          色彩转换

          算法原理

          图像色彩转换是指将一个颜色空间的图像转换到另一个颜色空间。在颜色空间转换时,需要进行像素值的变换。通过变换后的像素值,将图像中的每个像素点转换到另一个颜色空间中,实现图像转换。

          Golang中提供了color包,可以实现图像的色彩转换。

          实现步骤

          下面我们将演示如何使用Go语言对图片进行色彩转换。具体实现过程如下:

          读取图片

          img, err := imaging.Open("input.jpg")

          if err != nil {

          fmt.Println("Open failed:", err)

          os.Exit(1)

          }

            进行色彩转换

            下面的代码演示了如何将图像从RGBA颜色模式转换为灰度颜色模式:

            newImg := imaging.New(img.Bounds().Size(), color.Gray{0})

            for y := 0; y < img.Bounds().Dy(); y++ {

            for x := 0; x < img.Bounds().Dx(); x++ {

            col := img.At(x, y)

            grayCol := color.GrayModel.Convert(col).(color.Gray)

            newImg.Set(x, y, grayCol)

            }

            }

            其中,我们使用color.GrayModel,将图像中的每个像素点从RGBA颜色转换为灰度颜色。然后,使用Set方法,将新的像素点设置到新的图片中。

              保存图片

              最后,我们使用imaging.Save方法保存最终的图片。

              err = imaging.Save(newImg, "output.jpg")

              if err != nil {

              fmt.Println("Save failed:", err)

              os.Exit(1)

              }

              总结

              通过本文的演示,我们了解了如何使用Golang对图片进行背景去除和色彩转换这两个常见的操作。在实际应用中,我们可以根据需要选择不同的方法进行处理。

后端开发标签