Golang图像ColorModel()

5
我正在自学Go语言。我决定尝试一些计算机视觉方面的东西。首先,我想制作一个图像直方图。我试图获取颜色模型,以便知道像素的强度范围。当我打印image.ColorModel()时,它给了我一个加密的十六进制输出:color model: &{0x492f70}。我在文档中找不到任何解释。我期望得到一种枚举类型,可以映射到像NRGBA、RGBA等颜色模型。那个十六进制是什么意思?&{}代表什么?还有,NRGBA中的“N”是什么意思?我找不到任何相关信息。
3个回答

9
为了扩展putu的回答,将返回的颜色模型与image包的“准备好”的模型进行比较,仅在使用其中一个模型时才有效,否则所有比较结果都将为false。而且列出并比较所有可能的模型非常不方便。
相反,要找到一种健谈的颜色模型形式,我们可以使用这个小技巧:尝试使用图像的颜色模型转换任何颜色。具体的颜色模型将所有颜色值(实现)转换为图像使用的颜色类型/实现。打印结果颜色的类型将告诉您正在寻找什么。
例如:
col := color.RGBA{} // This is the "any" color we convert
var img image.Image

img = &image.NRGBA{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

img = &image.Gray16{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

img = &image.NYCbCrA{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

img = &image.Paletted{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

输出(在Go Playground上尝试):

color.NRGBA
color.Gray16
color.NYCbCrA
<nil>

如上所示,类型为 *image.NRGBA 的图像使用 color.NRGBA 来模拟颜色,类型为 *image.Gray16 的图像使用 color.Gray16 等。最后一个例子中我使用了 *image.Paletted,结果是 nil,因为该图像的调色板为空。
为了快速修复 nil 调色板,让我们提供一个初始调色板:
img = &image.Paletted{Palette: []color.Color{color.Gray16{}}}
fmt.Printf("%T\n", img.ColorModel().Convert(col))

现在的输出结果是(请在Go Playground上尝试):
color.Gray16

谢谢,有趣的方法,是的它更加健壮。 - putu

6

Image是一个接口,它包含以下方法集:

type Image interface {
    ColorModel() color.Model
    Bounds() Rectangle
    At(x, y int) color.Color
}

ColorModel() 方法返回一个名为 color.Model 的接口,该接口声明如下:

type Model interface {
    Convert(c Color) Color
}

由于ColorModel返回的是接口,因此您无法使用*对其进行解引用。您看到的&{0x492f70}是实现color.Model接口的底层数据结构,在这种情况下,它是一个指针,指向地址0x492f70。通常,ColorModel的底层数据实现方式并不重要(只要它具有Convert(c Color) Color方法即可),但如果您好奇,几个标准颜色类型的模型都被实现为指向未导出结构体的指针,该结构体声明如下:
type modelFunc struct {
    f func(Color) Color
}

当您打印 ColorModel 时,得到的是指向该结构体的指针。尝试使用 fmt.Printf("%+v\n", img.ColorModel()) 打印它,您将会看到一个输出结果像 &{f:0x492f70},其中 f 表示上述结构体中的字段名。
文档中,有几种标准颜色类型的模型,例如 color.NRGBAModelcolor.GrayModel 等。如果想检测图像的颜色模型,则可以将其与这些标准模型进行比较,例如:
if img.ColorModel() == color.RGBAModel {
    //32-bit RGBA color, each R,G,B, A component requires 8-bits
} else if img.ColorModel() == color.GrayModel {
    //8-bit grayscale
}
//...

0
这个十六进制数是什么意思?
你正在打印的变量的内存指针地址。
&{...} 这个符号是什么意思?
请参考SO Post
NRGBA 中的“N”是什么意思?
NRGBA 表示非预乘 alpha 的 32 位颜色。请参考doc

我想这是一个内存地址,但是我该如何获取它所代表的颜色模型呢?我尝试使用 * 解引用,但是那给了我一个错误。 - noel
你可以使用 * 来解引用它。你可以分享一下错误信息吗? - jeevatkm
当我使用*(src.color.Model())时,我得到了以下错误信息:src/github/see/histogram/histogram.go:13: invalid indirect of src.ColorModel() (type color.Model) - noel
只需要执行 *src.color.Model() 或者 (*src.color.Model()) - jeevatkm

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接