Displaying a color gamut surface
Today I'll show you one way to visualize the sRGB color gamut in L*a*b* space with assistance with a couple of new functions introduced last fall in the R2014b release. (I originally planned to post this a few months ago, but I got sidetracked writing about colormaps.)
The first new function is called boundary, and it is in MATLAB. Given a set of 2-D or 3-D points, boundary computes, well, the boundary.
Here's an example to illustrate.
x = gallery('uniformdata',30,1,1); y = gallery('uniformdata',30,1,10); plot(x,y,'.') axis([-0.2 1.2 -0.2 1.2]) axis equal
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_01.png)
Now compute and plot the boundary around the points.
k = boundary(x,y); hold on plot(x(k),y(k)) hold off
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_02.png)
"But, Steve," some of you are saying, "that's not the only possible boundary around these points, right?"
Right. The function boundary has an optional shrink factor that you can specify. A shrink factor of 0 corresponds to the convex hull. A shrink factor of 1 gives a compact boundary that envelops all the points.
k0 = boundary(x,y,0); k1 = boundary(x,y,1); hold on plot(x(k0),y(k0)) plot(x(k1),y(k1)) hold off legend('Original points','Shrink factor: 0.5 (default)',... 'Shrink factor: 0','Shrink factor: 1')
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_03.png)
Here's a 3-D example using boundary. First, the points:
P = gallery('uniformdata',30,3,5); plot3(P(:,1),P(:,2),P(:,3),'.','MarkerSize',10) grid on
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_04.png)
Now the boundary, plotted using trisurf:
k = boundary(P); hold on trisurf(k,P(:,1),P(:,2),P(:,3),'Facecolor','red','FaceAlpha',0.1) hold off
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_05.png)
The second new function I wanted to mention is rgb2lab. This function is in the Image Processing Toolbox. The toolbox could convert from sRGB to L*a*b* before, but this function makes it a bit easier. (And, if you're interested, it supports not only sRGB but also Adobe RGB 1998).
Just for grins, let's reverse the a* and b* color coordinates for an image.
rgb = imread('peppers.png');
imshow(rgb)
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_06.png)
lab = rgb2lab(rgb); labp = lab(:,:,[1 3 2]); rgbp = lab2rgb(labp); imshow(rgbp)
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_07.png)
Now let's get to work on visualizing the sRGB gamut surface. The basic strategy is to make a grid of points in RGB space, transform them to L*a*b* space, and find the boundary. (We'll use the default shrink factor.)
[r,g,b] = meshgrid(linspace(0,1,50)); rgb = [r(:), g(:), b(:)]; lab = rgb2lab(rgb); a = lab(:,2); b = lab(:,3); L = lab(:,1); k = boundary(a,b,L); trisurf(k,a,b,L,'FaceColor','interp',... 'FaceVertexCData',rgb,'EdgeColor','none') xlabel('a*') ylabel('b*') zlabel('L*') axis([-110 110 -110 110 0 100]) view(-10,35) axis equal title('sRGB gamut surface in L*a*b* space')
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_08.png)
Here are another couple of view angles.
view(75,20)
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_09.png)
view(185,15)
![](https://blogs.mathworks.com/images/steve/2015/srgb_gamut_surface_10.png)
That's it for this week. Have fun with color-space surfaces!
Comments
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.