DarknetImage move float conversion into c code

imgTofloat32 + fill_image_f32 took more than double the time since tofloat created needless allocations and iterate over each pixel, and fill_image in c then iterate over each pixel*3 again just to move it into the c image.
This commit is contained in:
Julian Langschaedel
2022-03-02 19:03:17 +01:00
parent a18a9cf3e0
commit 7e34b459e6
3 changed files with 23 additions and 35 deletions

View File

@@ -14,61 +14,33 @@ import (
type DarknetImage struct {
Width int
Height int
ans []float32
image C.image
}
// Close and release resources.
func (img *DarknetImage) Close() error {
C.free_image(img.image)
img.ans = nil
return nil
}
// https://stackoverflow.com/questions/33186783/get-a-pixel-array-from-from-golang-image-image/59747737#59747737
func imgTofloat32(src image.Image) []float32 {
func Image2Float32(src image.Image) (*DarknetImage, error) {
bounds := src.Bounds()
width, height := bounds.Max.X, bounds.Max.Y
srcRGBA := image.NewRGBA(src.Bounds())
draw.Copy(srcRGBA, image.Point{}, src, src.Bounds(), draw.Src, nil)
srcRGBA := image.NewRGBA(bounds)
draw.Copy(srcRGBA, image.Point{}, src, bounds, draw.Src, nil)
red := make([]float32, 0, width*height)
green := make([]float32, 0, width*height)
blue := make([]float32, 0, width*height)
for y := 0; y < height; y++ {
for x := 0; x < width; x++ {
idxSource := (y*width + x) * 4
pix := srcRGBA.Pix[idxSource : idxSource+4]
rpix, gpix, bpix := float32(pix[0])/257.0, float32(pix[1])/257.0, float32(pix[2])/257.0
red = append(red, rpix)
green = append(green, gpix)
blue = append(blue, bpix)
}
}
srcRGBA = nil
ans := make([]float32, len(red)+len(green)+len(blue))
copy(ans[:len(red)], red)
copy(ans[len(red):len(red)+len(green)], green)
copy(ans[len(red)+len(green):], blue)
red = nil
green = nil
blue = nil
return ans
return ImageRGBA2Float32(srcRGBA)
}
// Image2Float32 Returns []float32 representation of image.Image
func Image2Float32(img image.Image) (*DarknetImage, error) {
// ans := imgTofloat32(img)
func ImageRGBA2Float32(img *image.RGBA) (*DarknetImage, error) {
width := img.Bounds().Dx()
height := img.Bounds().Dy()
imgDarknet := &DarknetImage{
Width: width,
Height: height,
ans: imgTofloat32(img),
image: C.make_image(C.int(width), C.int(height), 3),
}
C.fill_image_f32(&imgDarknet.image, C.int(width), C.int(height), 3, (*C.float)(unsafe.Pointer(&imgDarknet.ans[0])))
C.to_float_and_fill_image(&imgDarknet.image, C.int(width), C.int(height), (*C.uint8_t)(unsafe.Pointer(&img.Pix[0])))
return imgDarknet, nil
}