I am teaching myself Go. I decided to try some computer vision stuff. First things first I was going to make an image histogram. I'm trying to get the color model so I know the intensity range of the pixels. When I print image.ColorModel() it gives me a cryptic hexidecimal output:
color model: &{0x492f70}
I couldn't find any explanation in the docs. I was expecting some sort of enum type thing that would map to a color model like, NRGBA, RGBA, etc.
What does that hexidecimal mean? What does the ampersand curly braces &{...} mean? Also what is the "N" in NRGBA I can't find anything about it.
To extend putu's answer, comparing the returned color model to the "prepared" models of the image package only works if one of those models is used, else all comparison will result in false. Also it is quite inconvenient to list and compare to all possible models.
Instead to find out a talkative form of the color model, we may use this little trick: try to convert any color using the color model of the image. A concrete color model converts all color values (implementations) to the color type / implementation used by the image. Printing the type of the resulting color will tell you what you are looking for.
Example:
col := color.RGBA{} // This is the "any" color we convert
var img image.Image
img = &image.NRGBA{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))
img = &image.Gray16{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))
img = &image.NYCbCrA{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))
img = &image.Paletted{}
fmt.Printf("%T\n", img.ColorModel().Convert(col))
Output (try it on the Go Playground):
color.NRGBA
color.Gray16
color.NYCbCrA
<nil>
As can be seen, an image of type *image.NRGBA models colors using color.NRGBA, an image of type *image.Gray16 models colors using color.Gray16 etc. As a last example I used *image.Paletted, where the result was nil, because the image's palette was empty.
To quickly fix the nil palette, let's provide an initial palette:
img = &image.Paletted{Palette: []color.Color{color.Gray16{}}}
fmt.Printf("%T\n", img.ColorModel().Convert(col))
Now the output will be (try this on the Go Playground):
color.Gray16
An Image is declared as an interface having the following method sets:
type Image interface {
ColorModel() color.Model
Bounds() Rectangle
At(x, y int) color.Color
}
Method ColorModel() returns an interface named color.Model which is declared as:
type Model interface {
Convert(c Color) Color
}
Since the ColorModel returns an interface, you can't dereference it using *. What you see as &{0x492f70} is the underlying data structure which implements color.Model interface, and in this case, it is a pointer which points to address 0x492f70. Usually, it doesn't matter how ColorModel's underlying data is implemented (any type is valid as long as it has Convert(c Color) Color method), but if you're curious, the models for several standard color types are implemented as a pointer to unexported struct declared as:
type modelFunc struct {
f func(Color) Color
}
What you got when you print the ColorModel is a pointer to this struct. Try print it using fmt.Printf("%+v\n", img.ColorModel()), you will see an output likes &{f:0x492f70}, in which f denotes the field name in the above struct.
In the documentation, there are several models for the standard color types, e.g. color.NRGBAModel, color.GrayModel, etc. If you want to detect the image's color model, you can compare it to these standard models, e.g.
if img.ColorModel() == color.RGBAModel {
//32-bit RGBA color, each R,G,B, A component requires 8-bits
} else if img.ColorModel() == color.GrayModel {
//8-bit grayscale
}
//...
What does that hexidecimal mean?
Memory pointer address of the variable you're printing.
What does the ampersand curly braces &{...} mean?
Refer to this SO Post
what is the "N" in NRGBA
NRGBA represents a non-alpha-premultiplied 32-bit color. Refer to doc.
Related
In processing, lets say I have an array:
int[] rgb = {floor(random(0,255)), floor(random(0,255)), floor(random(0,255)};
So this will create an array with [0], [1], and [2] being corresponding red, green. and blue values.
Now let's say that I want to pass the fill() function, which needs 3 integers--red, green, and blue. I could just put fill(rgb[0], rgb[1], rgb[2]);, but that does not seem like the most efficient way of doing this. What I want is to be able to pass something like this to fill():
fill(rgb[0,1,2]); which will do the same thing as fill(rgb[0], rgb[1], rgb[2]);, but will be much less writing. Help is appreciated.
I've never used processing, but you can probably overload the fill method to take an array.
void fill(int[] rgb)
{
fill(rgb[0], rgb[1], rgb[2]);
};
Which you could then easily call like...
int[] rgb = {floor(random(0,255)), floor(random(0,255)), floor(random(0,255)};
fill(rgb);
There is a section in this article called "Too Many Parameters", I think it will help more.
Instead of storing your fields in an array, store them in an object.
Processing has a color datatype that you could use. The color() function takes three arguments, and you can then pass the single color value to the fill() function. Like this:
color myColor = color(random(256), random(256), random(256));
fill(myColor);
You could also create your own class and use that instead.
I read the image with:
W=double(imread('rose32.bmp'));
Then:
imshow(W,[]);
or
imshow(W);
But the shown image seems to be inverted with respect to the original image. How can I solve this problem ? Is it a MATLAB problem?
The problem is probably caused by the formatting the the imagefile!
When you use imread what it returns depends of the formatting of the image in the image file. imread returns tree values [A,map,transparency] = imread(___), where A might be hxw-matrix or a hxwx3-matrix (h and w are short for height and width) of several different possible classes (eg. double or uint8).
In the case of the hxwx3-matrix the output-variable map will be empty, and you can show the image directly using imshow(A). This is called an RGB-image.
The other possibility (called an indexed image) is the hxw-matrix. In this case map is a colormap, and you can show the image by imshow(A,map).
You can easily convert between these two types of images by ind2rgb(A,map) and rgb2ind(A).
The other thing you need to be careful with is the class of the image.
If you have an rgb-image of class uint8, then the values of image will be integers between 0 and 255, whereas rgb-images of type double have values between 0 and 1. You should never convert an image to double-class by the double-function like you do; in stead use im2double.
So to solve your problem try the following code:
[img,map] = imread('rose32.bmp');
if ~isempty(map)
img = ind2rgb(img,map);
end
img = im2double(img);
Now imshow(img) should show the image correctly. Or you can simply use the following code:
[W,map] = imread('rose32.bmp');
imshow(W,map);
The Question:
Is there a SASS function/technique that transforms a HEX value to a simple RGB string.
Simple here meaning just a string without it being enclosed in rgb() ?
E.g: #D50000 --> "213,0,0"
Why I need this:
I'm using Material Design Lite as my UI 'framework'. More specifically I'm using the SASS version so I can tweak the color variables according to my app's style-guide.
For some reason the color variables in _variables.scss of MDL take this format for color definitions:
$color-primary: "0,0,0" !default; // supposed to be black
which is really, really odd. I expected, at most, something along the lines of
$color-primary: rgba(0,0,0,1) !default;
My color variables are stored in another file called _globals.scss in which I store my variables in regular HEX format so I can easily reuse them in other places:
$brand-primary: #FA3166;
$brand-primary-dark: #E02C59;
I don't want to define 2 times my colours (1 HEX & 1 MDL-compatible RGB string), hence the reason I need to transform HEX to RGB-string.
#nicholas-kyriakides's answer works perfectly fine, but here is a more concise function using Sass interpolation.
#function hexToRGBString($hexColor) {
#return "#{red($hexColor)},#{green($hexColor)},#{blue($hexColor)}";
}
You can pass in either a hex either explicity or from rgb() or rgba() with opacity as 1.
For example:
$color-white: hexToRGBString(#fff) => "255,255,255"
$color-white: hexToRGBString(rgb(255,255,255)) => "255,255,255"
$color-white: hexToRGBString(rgba(#fff,1)) => "255,255,255"
I've hacked around it with a SASS function:
#function hexToString($hexColor) {
// 0.999999 val in alpha actually compiles to 1.0
$rgbaVal: inspect(rgba($hexColor,0.9999999));
// slice substring between 'rgba(' and '1.0)'
#return str-slice($rgbaVal, 6, str-length($rgbaVal)-6);
}
Usage:
$brand-primary: #333;
$color-primary: hexToString($brand-primary);
I think the MDL team intended to have a different way to customise the palette and I'm missing it, so if someone knows a better way to customise MDL's palette I'm open to suggestions. Either way this solves the original question.
I recently asked how to convert Float32 or Uint8 arrays into images in the Images package. I got an answer for the Float32 case, but am still having trouble figuring out how to save a Uint8 array.
As an example, let's create a random Uint8 array using the traditional Matlab scheme where the dimensions are (m,n,3):
array = rand(Uint8, 50, 50, 3);
img = convert(Image, array);
Using the same approach as works for the Float32 case,
imwrite(img, "out.png")
fails with message
ERROR: method 'mapinfo' has no method matching mapinfo(::Type{ImageMagick}, ::Image{Uint8, 3, Image{Uint8, 3, Array{Uint8, 3}}}).
I checked the documentation, and it says
If data encodes color information along one of the dimensions of the array (as opposed to using a ColorValue array, from the Color.jl package), be sure to specify the "colordim" and "colorspace" in properties.
However, inspecting the img object previously created shows that it has colordim = 3 and colorspace = RGB already set up, so this can't be the problem.
I then searched the documentation for all instances of MapInfo. In core.md there is one occurrence:
scalei: a property that controls default contrast scaling upon display. This should be a MapInfo value, to be used for setting the contrast upon display. In the absence of this property, the range 0 to 1 will be used.
But there was no information on what exactly a MapInfo object is, so I looked further, and in function_reference.md it says:
Here is how to directly construct the major concrete MapInfo types:
MapNone(T), indicating that the only form of scaling is conversion to type T. This is not very safe, as values "wrap around": for example, converting 258 to a Uint8 results in 0x02, which would look dimmer than 255 = 0xff.
...
and some other examples. So I tried to specify scalei = MapNone(Uint8) as follows:
img2 = Image(img, colordim = 3, colorspace = "RGB", scalei = MapNone(Uint8));
imwrite(img, "out.png")
but got the same error again.
How do you encode Uint8 image data using Images in Julia?
You can convert back and forth between arrays of primitive types such as UInt8 and arrays of color types. These conversions are achieved in a unified way via two functions: colorview and channelview.
Example
Convert array of UInt8 to array of RGB:
arr = rand(UInt8, 3, 50, 50)
img = colorview(RGB, arr / 255)
Convert back to channel view:
channelview(img)
Notes
In this example the RGB color type requires that the entries of the array live in [0,1] as floating point. I manually converted UInt8 to Float64 using an explicit division by 255. There is probably a more generic way of achieving this result with reinterpret or some other function in Images.jl
The colorview and channelview functions assume that the channel dimension is the first dimension of the array. You can use permutedims in case your channels live in a different dimension, or use some function in Images.jl (maybe reinterpretc?) to do it efficiently without memory copies.
I am trying to overlay an activation map over a baseline vasculature image but I keep getting the same error below:
X and Y must have the same size and class or Y must be a scalar double.
I resized each to 400x400 so I thought it would work but no dice. Is there something I am missing? It is fairly straight forward for a GUI I am working on. Any help would be appreciated.
a=imread ('Vasculature.tif');
b = imresize (a, [400,400]);
c=imread ('activation.tif');
d= imresize (c, [400,400]);
e=imadd (b,d);
Could it be the bit depth or dpi?
I think one of your images is RGB (size(...,3)==3) and the other is grayscale (size(...,3)==1). Say the vasculature image a is grayscale and the activation image c is RGB. To convert a to RGB to match c, use ind2rgb, then add.
aRGB = ind2rgb(a,gray(256)); % assuming uint8
Alternatively, you could do aRGB = repmat(a,[1 1 3]);.
Or to put the activation image into grayscale:
cGray = rgb2gray(c);
Also, according to the documentation for imadd the two images must be:
nonsparse numeric arrays with the same size and class
To get the uint8 and uint16 images to match use the im2uint8 or im2uint16 functions to convert. Alternatively, just rescale and cast (e.g. b_uint8 = uint8(double(b)*255/65535);).
Note that in some versions of MATLAB there is a bug with displaying 16-bit images. The fix depends on whether the image is RGB or gray scale, and the platform (Windows vs. Linux). If you run into problems displaying 16-bit images, use imshow, which has the fix, or use the following code for integer data type images following image or imagesc:
function fixint16disp(img)
if any(strcmp(class(img),{'int16','uint16'}))
if size(img,3)==1,
colormap(gray(65535)); end
if ispc,
set(gcf,'Renderer','zbuffer'); end
end
chappjc's answers is just fine, I want to add a more general answer to the question how to solve the error message
X and Y must have the same size and class or Y must be a scalar double
General solving strategy
At which line does the error occur
Try to understand the error message
a. "... must have the same size ...":
Check the sizes of the input.
Try to understand the meaning of your code for the given (type of) input parameters. Is the error message reasonable?
What do you want to achieve?
Useful command: size A: returns the size of A
b. "... must have the same class ...":
Check the data types of the input arguments.
Which common data type is reasonable?
Convert it to the chosen data type.
Usefull command: whos A: returns all the meta information of A, i.e. size, data type, ...
Implement the solution: your favorite search engine and the matlab documentation are your best friend.
Be happy: you solved your problem and learned something new.
A simple code :
a=imread ('image1.jpg');
b=imresize (a, [400,400]);
subplot(3,1,1), imshow(b), title('image 1');
c=imread ('image2.jpg');
d= imresize (c, [400,400]);
subplot(3,1,2), imshow(d), title('image 2');
[x1, y1] = size(b) %height and wedth of 1st image
[x2, y2] = size(d) %height and wedth of 2nd image
for i = 1: x1
for j = 1: y1
im3(i, j)= b(i, j)+d(i, j);
end
end
subplot(3,1,3), imshow (im3), title('Resultant Image');