From 7e34b459e624e6e858b4bc92a267dac3adf5804b Mon Sep 17 00:00:00 2001 From: Julian Langschaedel Date: Wed, 2 Mar 2022 19:03:17 +0100 Subject: [PATCH] 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. --- image.c | 15 +++++++++++++++ image.go | 40 ++++++---------------------------------- image.h | 3 ++- 3 files changed, 23 insertions(+), 35 deletions(-) diff --git a/image.c b/image.c index 80fd782..525a577 100644 --- a/image.c +++ b/image.c @@ -11,3 +11,18 @@ void set_data_f32_val(float* data, int index, float value) { data[index] = value; } +void to_float_and_fill_image(image* im, int w, int h, uint8_t* data) { + int x, y, idx_source; + int pixel_count = w * h; + int idx = 0; + + for (y = 0; y < h; y++) { + for (x = 0; x < w; x++) { + idx_source = (y*w + x) * 4; + im->data[(pixel_count*0) + idx] = (float)data[idx_source] / 255; + im->data[(pixel_count*1) + idx] = (float)data[idx_source+1] / 255; + im->data[(pixel_count*2) + idx] = (float)data[idx_source+2] / 255; + idx++; + } + } +} diff --git a/image.go b/image.go index 63524fd..022bc51 100644 --- a/image.go +++ b/image.go @@ -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 } diff --git a/image.h b/image.h index ce165ab..92fb48c 100644 --- a/image.h +++ b/image.h @@ -3,4 +3,5 @@ #include extern void fill_image_f32(image *im, int w, int h, int c, float* data); -extern void set_data_f32_val(float* data, int index, float value); \ No newline at end of file +extern void set_data_f32_val(float* data, int index, float value); +extern void to_float_and_fill_image(image *im, int w, int h, uint8_t* data);