gocv
gocv copied to clipboard
image.YCbCr to Mat
What is the best way to convert a image.YCbCr to gocv.Mat?
Hello @cedricve you would need to add another wrapper function to GoCV such as ImageToMatYCbCr()
that is similar to the existing ImageToMatRGBA()
function:
https://github.com/hybridgroup/gocv/blob/master/core.go#L801
Hello! I am using this code in my project.
func ImageToMatRGB(img image.Image) (gocv.Mat, error) {
bounds := img.Bounds()
x := bounds.Dx()
y := bounds.Dy()
var data []uint8
switch img.ColorModel() {
case color.RGBAModel:
m, res := img.(*image.RGBA)
if true != res {
return gocv.NewMat(), errors.New("Image color format error")
}
data = m.Pix
case color.NRGBAModel:
m, res := img.(*image.NRGBA)
if !res {
return gocv.NewMat(), errors.New("Image color format error")
}
data = m.Pix
case color.YCbCrModel:
im := img.(*image.YCbCr)
data := make([]byte, 0, x*y*3)
for j := bounds.Min.Y; j < bounds.Max.Y; j++ {
for i := bounds.Min.X; i < bounds.Max.X; i++ {
r, g, b, _ := im.YCbCrAt(i, j).RGBA()
data = append(data, byte(b>>8), byte(g>>8), byte(r>>8))
}
}
return gocv.NewMatFromBytes(y, x, gocv.MatTypeCV8UC3, data)
default:
data := make([]byte, 0, x*y*3)
for j := bounds.Min.Y; j < bounds.Max.Y; j++ {
for i := bounds.Min.X; i < bounds.Max.X; i++ {
r, g, b, _ := img.At(i, j).RGBA()
data = append(data, byte(b>>8), byte(g>>8), byte(r>>8))
}
}
return gocv.NewMatFromBytes(y, x, gocv.MatTypeCV8UC3, data)
}
// speed up the conversion process of RGBA format
src, err := gocv.NewMatFromBytes(y, x, gocv.MatTypeCV8UC4, data)
if err != nil {
return gocv.NewMat(), err
}
defer src.Close()
dst := gocv.NewMat()
gocv.CvtColor(src, &dst, gocv.ColorRGBAToBGR)
return dst, nil
}
Method At in case img.At(i, j).RGBA() is very slow and creates too many allocs, so i replaced it with im.YCbCrAt(i, j).RGBA() and this is my benchmark:
Benchmark_ImageToMatRGB/standart-8 1035 1155578 ns/op 415998 B/op 65963 allocs/op
Benchmark_ImageToMatRGB/my_func-8 2788 432530 ns/op 204927 B/op 3 allocs/op