Home > Software engineering >  Convert []float64 pixel slice to an Image
Convert []float64 pixel slice to an Image

Time:08-24

I'm attempting to resize and convert an image into a grayscale slice of float64 (so I can do some transformations on the floats) and then back into an image, but I'm not sure how to convert a []float64 back to RGB or something I can turn into an image.

So far I have:

// colorToGrayScaleFloat64 reduces rgb
// to a grayscale approximation.
func colorToGrayScaleFloat64(c color.Color) float64 {
    r, g, b, _ := c.RGBA()
    return 0.299*float64(r)  
        0.587*float64(g)  
        0.114*float64(b)
}

func getFloatPixels(filePath string) {
    size := 32
    f, err := os.Open(filePath)
    if err != nil {
    log.Fatalf("FAILED TO OPEN FILE: %s", err.Error())
    }
    defer f.Close()

    image, _, err := image.Decode(f)
    if err != nil {
        log.Fatalf("FAILED TO DECODE FILE: %s", err.Error())
    }

    // Resize image to 32X32
    im := imaging.Resize(image, size, size, imaging.Lanczos)

    // Convert image to grayscale float array
    vals := make([]float64, size*size)
    for i := 0; i < size; i   {
        for j := 0; j < size; j   {
            vals[size*i j] = colorToGrayScaleFloat64(im.At(i, j))
        }
    }

    fmt.Printf("pixel vals % v\n", vals)
}

Which produces the output:

pixel vals [40315.076 48372.797 48812.780999999995 47005.557 ... 25129.973999999995 24719.287999999997]

How can I convert this pixel []float64 back to an image?

CodePudding user response:

So basically you have the luminosity of the gray pixel, and you want to have a color.Color value representing it.

This is quite simple: there is a color.Gray type, and a higher precision color.Gray16 which model the color with its luminosity, so simply create a value of those. They implement color.Color, so you can use them to set pixels of an image.

col := color.Gray{uint8(lum / 256)}

Also note that your colorToGrayScaleFloat64() function is already present in the standard lib. There are several converters in the image/color package as implementations of color.Model. Use the color.GrayModel or color.Gray16Model to convert a color.Color to a value of type color.Gray or color.Gray16 which directly store the luminosity of the gray color.

For example:

gray := color.Gray16Model.Convert(img.At(x, y))
lum := float64(gray.(color.Gray16).Y)

Testing it:

c := color.RGBA{111, 111, 111, 255}
fmt.Println("original:", c)

gray := color.Gray16Model.Convert(c)
lum := float64(gray.(color.Gray16).Y)
fmt.Println("lum:", lum)

col := color.Gray{uint8(lum / 256)}

r, g, b, a := col.RGBA()
a >>= 8
fmt.Println("lum to col:", r/a, g/a, b/a, a)
fmt.Println()

This will output (try it on the Go Playground):

original: {111 111 111 255}
lum: 28527
lum to col: 111 111 111 255

Also note that if you want to create an image full of gray pixels, you may use the image.Gray and image.Gray16 types so when drawing these colors on them, no color conversion will be needed. They also have designated Gray.SetGray() and Gray16.SetGray16() methods that directly take colors of these types.

See related:

Converting RGBA image to Grayscale Golang

  • Related