mirror of
https://github.com/LdDl/go-darknet.git
synced 2025-10-04 23:32:48 +08:00
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:
15
image.c
15
image.c
@@ -11,3 +11,18 @@ void set_data_f32_val(float* data, int index, float value) {
|
|||||||
data[index] = 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++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
40
image.go
40
image.go
@@ -14,61 +14,33 @@ import (
|
|||||||
type DarknetImage struct {
|
type DarknetImage struct {
|
||||||
Width int
|
Width int
|
||||||
Height int
|
Height int
|
||||||
ans []float32
|
|
||||||
image C.image
|
image C.image
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close and release resources.
|
// Close and release resources.
|
||||||
func (img *DarknetImage) Close() error {
|
func (img *DarknetImage) Close() error {
|
||||||
C.free_image(img.image)
|
C.free_image(img.image)
|
||||||
img.ans = nil
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/33186783/get-a-pixel-array-from-from-golang-image-image/59747737#59747737
|
func Image2Float32(src image.Image) (*DarknetImage, error) {
|
||||||
func imgTofloat32(src image.Image) []float32 {
|
|
||||||
bounds := src.Bounds()
|
bounds := src.Bounds()
|
||||||
width, height := bounds.Max.X, bounds.Max.Y
|
srcRGBA := image.NewRGBA(bounds)
|
||||||
srcRGBA := image.NewRGBA(src.Bounds())
|
draw.Copy(srcRGBA, image.Point{}, src, bounds, draw.Src, nil)
|
||||||
draw.Copy(srcRGBA, image.Point{}, src, src.Bounds(), draw.Src, nil)
|
|
||||||
|
|
||||||
red := make([]float32, 0, width*height)
|
return ImageRGBA2Float32(srcRGBA)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image2Float32 Returns []float32 representation of image.Image
|
// Image2Float32 Returns []float32 representation of image.Image
|
||||||
func Image2Float32(img image.Image) (*DarknetImage, error) {
|
func ImageRGBA2Float32(img *image.RGBA) (*DarknetImage, error) {
|
||||||
// ans := imgTofloat32(img)
|
|
||||||
width := img.Bounds().Dx()
|
width := img.Bounds().Dx()
|
||||||
height := img.Bounds().Dy()
|
height := img.Bounds().Dy()
|
||||||
imgDarknet := &DarknetImage{
|
imgDarknet := &DarknetImage{
|
||||||
Width: width,
|
Width: width,
|
||||||
Height: height,
|
Height: height,
|
||||||
ans: imgTofloat32(img),
|
|
||||||
image: C.make_image(C.int(width), C.int(height), 3),
|
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
|
return imgDarknet, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
image.h
1
image.h
@@ -4,3 +4,4 @@
|
|||||||
|
|
||||||
extern void fill_image_f32(image *im, int w, int h, int c, float* data);
|
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);
|
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);
|
||||||
|
Reference in New Issue
Block a user