Matrix Library && colour uint32's vs uint8's

215 views
Skip to first unread message

simran

unread,
Jul 3, 2016, 12:07:34 PM7/3/16
to golang-nuts
Hi All, 

Could someone please point me to a good matrix library for Go (i'm sure something exists, although i can't seem to find it!). 

Am hoping to do some image manipulation for which being able to work with matrices would be great.  

Have written simple helper stuff for images (i used to find myself doing the same a few time, so just put it in a library) ( https://github.com/simran91/monkeysee ). 

On another note, if you do look at the library above, you'll notice that my source image at (https://github.com/simran91/monkeysee/blob/master/samples/rgb.png) and destination image at (https://github.com/simran91/monkeysee/blob/master/samples/rgb-png-to-png-mod-SwapRGBtoGBR-autogenerated.png) have colours messed up. 

The colours were meant to have swapped, but the Red has gone into being an Pink. 

This i suspect is because when we call colour.RGBA() we get uint32's, but when we set the colour using color.RGBA{r, g, b, a} they r,g,b,a have to be uint8's 

Has anyone else come across this? I suspect there is a way to load up color.RGBA and give it uint32's? Would appreciate any pointers in that regard as well. 

thanks,

simran.

Constantin Konstantinidis

unread,
Jul 3, 2016, 12:30:01 PM7/3/16
to golang-nuts
I cannot answer about the matrix library but the package is consistently talking about int and not uint8
If you look at the specification https://golang.org/pkg/image/#RGBA.SetRGBA
You can impose 64bit which is not your pupose but apparently truncating int is not mandatory.
Can you indicate where you found it ?

Thanks

simran

unread,
Jul 3, 2016, 7:40:32 PM7/3/16
to Constantin Konstantinidis, golang-nuts
Hi Constantin, 

Where i seen the uint8 being defined is at: https://golang.org/pkg/image/color/#RGBA

Although the there is a method RGBA() which returns r,g,b,a in uint32 the struct is only uint8's and so i suspect has to be initialised as such. 

What i'm finding annoying is that the following fails:

package main

import "image"
import "image/color"

func main() {
m := image.NewRGBA(image.Rect(0, 0, 1, 1))
x, y := 0, 0
colour := m.At(x, y)
r, g, b, a := colour.RGBA()

newColour := color.RGBA{r, g, b, a}
m.SetRGBA(x, y, newColour)
}

prog.go:12: cannot use r (type uint32) as type uint8 in field value
prog.go:12: cannot use g (type uint32) as type uint8 in field value
prog.go:12: cannot use b (type uint32) as type uint8 in field value
prog.go:12: cannot use a (type uint32) as type uint8 in field value

Link to go playground for the above: https://play.golang.org/p/ToV1TH1NAr

Really want to this colour problem, any help appreciated :) 

cheers, 

simran.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Matt Harden

unread,
Jul 3, 2016, 7:58:49 PM7/3/16
to simran, Constantin Konstantinidis, golang-nuts
I can't tell exactly what the problem is from your example, but does this help?

Dan Kortschak

unread,
Jul 3, 2016, 8:00:41 PM7/3/16
to simran, golang-nuts
Are you looking for generalised matrices or simply image
rotation/translation?

Dan Kortschak

unread,
Jul 3, 2016, 8:00:58 PM7/3/16
to simran, golang-nuts
Are you looking for generalised matrices or simply image
rotation/translation/transformation?

On Mon, 2016-07-04 at 02:06 +1000, simran wrote:
>

simran

unread,
Jul 3, 2016, 8:07:46 PM7/3/16
to Matt Harden, Constantin Konstantinidis, golang-nuts
Hi Matt, 

What i want to do is get the r,g,b,a values individually, modify them and then set them. 

Your example was good, but is not extracting the r,g,b,a values individually (which come out as uint32's), and then say when i change them and set them again, it complains that it only wants uint8's. 

Essentially, i want to be able to tweak the r,g,b,a values without having to do converts from uint32's to uint8's as information is being lost there. 

cheers, 

simran.

 

simran

unread,
Jul 3, 2016, 8:09:00 PM7/3/16
to Dan Kortschak, golang-nuts
Hi Dan,

I am hoping to find a general matrix library as i want to write my own rotation, translation, reflection methods; however, if you do know a good image library doing these, i'd appreciate it as a reference anyway. 

cheers, 

simran.

Matt Harden

unread,
Jul 3, 2016, 8:12:19 PM7/3/16
to simran, Dan Kortschak, golang-nuts
If the source image is an image.RGBA, then the colors are already int8s; there's no additional information to lose. Here's an example that swaps the green and red channels of the pixel at (0,0): https://play.golang.org/p/i6F29OsdgD

Matt Harden

unread,
Jul 3, 2016, 8:14:03 PM7/3/16
to simran, Dan Kortschak, golang-nuts
This one avoids the type assertion: https://play.golang.org/p/vDB9RboNZj

Dan Kortschak

unread,
Jul 3, 2016, 8:23:05 PM7/3/16
to simran, golang-nuts
github.com/gonum/matrix/mat64 (soonish to be gonum.org/pkg/matrix/mat64)
is a general purpose matrix library.

A more specific image maths package is available at
github.com/go-gl/mathgl/mgl{32,64}.

simran

unread,
Jul 3, 2016, 10:07:33 PM7/3/16
to Matt Harden, Dan Kortschak, golang-nuts
I'm still getting the red's turning to pinks... 

You make an interesting point about the format of the source image... i was assuming that the image/{png,jpeg,gif} packages can read in a file and whatever the colour profiles were, i could get the equivalent RGBA values for them (this does appear to be the case given the available methods), and the values are given to me in uint32's (most of the images i have seem to have more than 8-bit colour in them). 

The issue seems to be that (even if it's internal to the package) that information is getting lost when i can get the values in uint32's (for any image read from file; rather than created inline) for the original colour depth, but when setting them, i have to cast them to a more basic uint8's and then write the images back to the filesystem.

Perhaps i need to dig into https://golang.org/src/image/png/{reader,writer}.go to understand what is going on and how the core image/png package decodes and encodes stuff... 

simran

unread,
Jul 3, 2016, 10:09:21 PM7/3/16
to Dan Kortschak, golang-nuts
Hi Dan, 

I get a "page not found" on all those four links... 

cheers, 

simran.

Matt Harden

unread,
Jul 3, 2016, 10:27:19 PM7/3/16
to simran, Dan Kortschak, golang-nuts
I think you're best off not taking the RGBA values and then building a color from them. Just take the color you're given and use m.Set(x, y, c) on the target image. If you need to modify the color, one way to do that would be to create your own object that implements the color.Color interface (the RGBA() method) and returns int32 values based on the source color's values. For example swapping red & green. Maybe this example will help: https://play.golang.org/p/vD1YBLR7nn

Dan Kortschak

unread,
Jul 3, 2016, 10:27:19 PM7/3/16
to simran, golang-nuts
They're packages, not links.

https://github.com/gonum/matrix
- docs: https://godoc.org/github.com/gonum/matrix/mat64

https://github.com/go-gl/mathgl
- docs: https://godoc.org/github.com/go-gl/mathgl/mgl64

On Mon, 2016-07-04 at 12:08 +1000, simran wrote:
> Hi Dan,
>

Matt Harden

unread,
Jul 3, 2016, 10:31:52 PM7/3/16
to Dan Kortschak, simran, golang-nuts
My previous example didn't compile because I made a change right before hitting share. Here's a working version. https://play.golang.org/p/E3dPLRjFvW

simran

unread,
Jul 4, 2016, 12:40:06 AM7/4/16
to Dan Kortschak, golang-nuts
:) Thanks Dan... my mental blank moment (which lasted an hour!) got me! :) i definitely look a giraffe staring at the headlights now! :)

 

simran

unread,
Jul 4, 2016, 12:51:22 AM7/4/16
to Matt Harden, Dan Kortschak, golang-nuts
Thanks  Matt. 

After your advice (and some reflection) - i decided to refactor all my code and keep the matrix in colour.Colour values rather than uint32's. 

Am actually happier i did it, as it provides for more neater / more concise code with better readability. 

Interestingly though, when i do a colour swap (without any type casting happening now) - the colour problem is still there. 

In the images below, the letter "RGB" in their respective colours should have purely swapped colours - but as you can see from the image below, just reading and writing the same colours produces a visibly different hue on the red (which has become a pink on the letter G now). There was absolutely no manipulation of the values that happened, only a swapping... i guess i'll try to dig into the source for Decode/Reader function (i think that's where it's happening as when i write the image as a jpg/gif/png - they all have the colour issue). 

 rgb.png


rgb-png-to-png-mod-SwapRGBtoGBR-autogenerated.png

thanks for your help though... have really appreciated it. 

cheers, 

simran.

Constantin Konstantinidis

unread,
Jul 4, 2016, 4:58:41 AM7/4/16
to golang-nuts
I noticed that you also use the image/color package. There uint8 are indeed mention for Color func. You fill in your matrix using uint8() but the type of the image might be lost between your routines as explained in https://blog.golang.org/go-image-package as you use src (generic) and not typed image.



On Sunday, July 3, 2016 at 6:07:34 PM UTC+2, simran g wrote:

Nigel Tao

unread,
Jul 6, 2016, 9:43:38 PM7/6/16
to simran, Matt Harden, Dan Kortschak, golang-nuts
On Mon, Jul 4, 2016 at 2:50 PM, simran <simran...@gmail.com> wrote:
> Interestingly though, when i do a colour swap (without any type casting happening now) - the colour problem is still there.

column[y] = color.RGBA{uint8(r), uint8(g), uint8(b), uint8(a)}

Don't do that. As https://blog.golang.org/go-image-package says,
"There are three important subtleties about the return values...
Second, the channels have a 16-bit effective range: 100% red is
represented by RGBA returning an r of 65535, not 255."

Thus, when creating an color.RGBA value, you want the high 8 bits, not
the low 8 bits. That second line should be:

column[y] = color.RGBA{uint8(r>>8), uint8(g>>8), uint8(b>>8), uint8(a>>8)}

simran

unread,
Jul 7, 2016, 12:19:49 AM7/7/16
to Nigel Tao, Matt Harden, Dan Kortschak, golang-nuts
Hi Nigel, 

Thankyou so very very much mate. This really fixed up the colour issues i was having - really can't thank you enough for pointing this out, it was eluding me for a long time (and probably would have continued to), but as soon as you mentioned it, it makes perfect sense of course :) 

I owe you a drink whenever you are in Sydney mate :) 

cheers, 

simran.
Reply all
Reply to author
Forward
0 new messages