Golang图片操作:学习如何进行图片的直方图均衡化和全局阈值化

1. 简介

Golang是一种非常流行和实际的编程语言,尤其在处理图片方面,Golang的高性能和简易性已经获得了广泛的关注。本文将介绍如何使用Golang进行图片的直方图均衡化和全局阈值化操作,对于需要处理图片的开发者们来说会非常有用。

2. 直方图均衡化

2.1 算法简介

直方图均衡化是一种常见的图像增强方法,其基本思想是对一幅图像中出现频率比较集中的像素进行拉伸,使灰度级分布更加均匀。直方图均衡化可以显著地增强图像的对比度,提高图像质量。

在进行直方图均衡化时,需要计算图像的直方图,即各个灰度级出现的频率,然后进行归一化处理,使其范围在0~1之间。随后再将每个像素的灰度值替换为其归一化频率值累加得到的直方图均衡化值。

2.2 代码实现

我们可以使用image库提供的函数加载和保存图片,使用math库中的函数完成直方图均衡化的算法。

import (

"image"

"image/color"

"image/jpeg"

"math"

"os"

)

func EqualizeHistogram(imagePath string) error {

// 读取图片

file, err := os.Open(imagePath)

if err != nil {

return err

}

defer file.Close()

img, _, err := image.Decode(file)

if err != nil {

return err

}

// 计算直方图

widths, heights := img.Bounds().Max.X, img.Bounds().Max.Y

var hist [256]float64

for y := 0; y < heights; y++ {

for x := 0; x < widths; x++ {

gray := color.GrayModel.Convert(img.At(x, y)).(color.Gray)

hist[gray.Y]++

}

}

// 归一化处理

for i := 0; i < 256; i++ {

hist[i] /= float64(widths * heights)

}

// 计算累积直方图

var cdf [256]float64

cdf[0] = hist[0]

for i := 1; i < 256; i++ {

cdf[i] = cdf[i - 1] + hist[i]

}

// 计算映射关系

var mp [256]int

for i := 0; i < 256; i++ {

mp[i] = int(math.Round(cdf[i] * 255))

}

// 修改像素值

for y := 0; y < heights; y++ {

for x := 0; x < widths; x++ {

gray := color.GrayModel.Convert(img.At(x, y)).(color.Gray)

img.Set(x, y, color.Gray{uint8(mp[gray.Y])})

}

}

// 保存图片

out, err := os.Create("equalized_" + imagePath)

if err != nil {

return err

}

defer out.Close()

jpeg.Encode(out, img, &jpeg.Options{Quality: 100})

return nil

}

2.3 测试结果

我们使用一张测试图片进行直方图均衡化操作,并进行比较,可以明显地看到图像亮度和对比度的差异。

原始图片 直方图均衡化图片

3. 全局阈值化

3.1 算法简介

全局阈值化是将一幅图像分为多个不同的区域,使得每个区域内的像素灰度级相同或相近,从而使图像更加清晰。在进行全局阈值化时,需要先选择一个合适的阈值T,然后统计图像中所有像素的灰度值的平均值作为初始阈值T0。接着不断迭代计算新的阈值T,并重复以上操作,直到阈值不再变化为止。

可以使用二分法或Kittler-Threshhold算法等优化算法,使得计算速度更快,结果更准确。

3.2 代码实现

我们将使用goocv库中的函数完成全局阈值化操作,可直接在代码中通过go get命令进行goocv库的下载。

import (

"fmt"

"gocv.io/x/gocv"

)

func Threshold(imagePath string) error {

// 读取图片

img := gocv.IMRead(imagePath, gocv.IMReadGrayScale)

if img.Empty() {

return fmt.Errorf("cannot read image file")

}

// 全局阈值化

_, threshImg := gocv.Threshold(img, 0, 255, gocv.ThresholdBinary|gocv.ThresholdOtsu)

// 保存图片

out := gocv.NewMat()

defer out.Close()

gocv.Resize(threshImg, &out, image.Point{}, 0.5, 0.5, gocv.InterpolationLinear)

gocv.IMWrite("thresholded_" + imagePath, out)

return nil

}

3.3 测试结果

我们使用一张测试图片进行全局阈值化操作,并进行比较,可以注意到图像的锐度和清晰度得到了增强。

原始图片 全局阈值化图片

4. 总结

本文介绍了如何使用Golang进行图片的直方图均衡化和全局阈值化操作。我们可以看到,这些操作可以明显地提高图像的质量和清晰度,对于需要处理图片的应用场景来说是非常实用的。同时,本文的代码也可以作为日后处理图片的基础代码库,方便开发者们进行二次开发和优化。

后端开发标签