How could I display a "circle at the bottom of the figure? And color it along the way? To show Hue angles?

조회 수: 5(최근 30일)
Crazy idea. I know Matlab is calling OpenGL under the hood but I would not know how to go about adding these two pieces of geometric elements to my chart. What follows is a "mock-up", to show what I'm trying to achieve :
You have my 3D figure, showing a custom datatip. What I would like to add is a "3D plot" (I guess?) that sits at the bottom of the chart, I get using some kind of colormap, to simulate a continuous drawing? The idea is to represent "Hue angle" on this chart, To show it through a "color wheel" and some kind of "black line" drawn along the hue angle, to show the students how to interpret visually the notion that color can have an "angle".

채택된 답변

DGM
DGM 2022년 3월 5일
편집: DGM 2022년 3월 5일
The problem that I'm seeing with the answers so far is that they're not going to be projected correctly into the color space in use.
If you do something using a plain HSV sweep, you'll get something that aligns like this. I stacked the ring on top so it's easy to tell that it's misaligned.
Obviously, the projection of the corners of the RGB cube are no longer spaced by equal angles in LAB. You need to actually project that color sweep into the space you're using.
This is an example
% parameters
npoints = 1000;
radius = 100;
% get a cyclic rgb color map
CTrgb = hsv(npoints);
% project it into the desired space, set radius to a constant
CTlab = rgb2lab(CTrgb);
[th,~] = cart2pol(CTlab(:,2),CTlab(:,3));
[CTa CTb] = pol2cart(th,radius);
% put something relevant in the axes
% just to show that the alignment is correct
csview('lab'); % THIS IS MIMT
xlim([-150 150])
ylim([-150 150])
hold on;
% plot a dense scatter to make the hue ring
scatter(CTa,CTb,30,CTrgb,'filled');
Note that I used MIMT csview() for the example, but it's not at all necessary for your task. If that's something you want to use, for anything, let me know. The version that's current in MIMT is kind of janky garbage. I rewrote it last week but haven't uploaded it yet.
  댓글 수: 7
Roger Breton
Roger Breton 2022년 3월 7일
For now, I think I'll experiment with your latest code, in a scatter3 form, along these lines :
% parameters
npoints = 1000;
radius = 100;
% get a cyclic rgb color map
CTrgb = hsv(npoints); % 1000 x 3 double
% project it into the desired space, set radius to a constant
CTlab = rgb2lab(CTrgb);
[th,~] = cart2pol(CTlab(:,2),CTlab(:,3));
[CTa CTb] = pol2cart(th,radius); % CTa et CTb = 1000 x 1 double
z = zeros(size(CTa));
scatter3(CTa,CTb,z, 30,CTrgb,'filled');
axis([-128 128 -128 128 0 100]);grid on;hold on;
I created a zeroes vector for the Z coordinate and this is what the above code gets me :
I think this is perfect. The only thing I'll have to come with next is a line radiating from the center representing the hue angle... I'll look into "slice boundaries"? I'll have to refresh my memory as to what I was looking for... But I'll report on the integration of this object in my existing 3D graph, which shouldn't be too hard. This is so rewarding and uses functions I had no idea existed.... I have no excuse not to learn Matlab better :( ...

댓글을 달려면 로그인하십시오.

추가 답변(5개)

Image Analyst
Image Analyst 2022년 3월 3일
Perhaps you can adapt my attached demo.
  댓글 수: 6
Les Beckham
Les Beckham 2022년 3월 4일
@Image Analyst provided a comment here that shows what you can achieve using the surface command. I see no reason that this approach wouldn't at least get you close to what you want to do. Just define the x/y/z coordinates of your circle and make the color vary with the angle as you go around the circle.

댓글을 달려면 로그인하십시오.


Les Beckham
Les Beckham 2022년 3월 4일
As I mentioned in my comment to @Image Analyst's answer, surface may be what you want.
I decided to experiment with it and came up with this based on his example.
See if it is close to what you want.
r = 50;
rho = linspace(0, 2*pi, 1920); % HDTV resolution.
x = cos(rho) * r;
y = sin(rho) * r;
z = zeros(size(x));
lineColor = rho(1:2:end); % This is the color, it varies with rho in this case.
lineColor = [lineColor flip(lineColor)];
% Plot the line with width 8 so we can see the colors well.
surface([x;x], [y;y], [z;z], [lineColor;lineColor],...
'FaceColor', 'no',...
'EdgeColor', 'interp',...
'LineWidth', 8);
grid on;
axis equal
view(16.5, 25)
  댓글 수: 1
Roger Breton
Roger Breton 2022년 3월 5일
편집: Roger Breton 2022년 3월 5일
Wow!!!!!!!!!!!!!!!!!! Thank you!!!!!!!!!!
Can't wait to try your code out!!!
One of the thing I albsolutely LOVE about Matlab is its "interactivity"!
Stepping through each line of your script, to see the role of each variable...
I owe you a beer :-)

댓글을 달려면 로그인하십시오.


Image Analyst
Image Analyst 2022년 3월 4일
편집: Image Analyst 2022년 3월 4일
You can make a colored circle by plotting markers:
numPoints = 1000;
angle = linspace(0, 360, numPoints);
x = sind(angle);
y = cosd(angle);
colors = hsv(numPoints);
for k = 1 : numPoints
plot(x(k), y(k), '.', 'MarkerSize', 20, 'Color', colors(k,:));
hold on;
end
grid on;
xlabel('x');
ylabel('y');
axis equal
  댓글 수: 3
Image Analyst
Image Analyst 2022년 3월 5일
Yes, essentially colors is an N b y 2 array (colormap) and you can put whatever color you want into each row to get the colors to be in the proper order.

댓글을 달려면 로그인하십시오.


Roger Breton
Roger Breton 2022년 3월 7일
I integrated the function into my script and it works like a charm. I may reduce the number of points from 1000 to 500 to speed up performance but otherwise, this is perfect. Now I just have to figure how to control that "blue" line, which should stand for the selected color hue angle :
  댓글 수: 3
DGM
DGM 2022년 3월 9일
For what it's worth, the hue ring part can probably be reduced to a literal CT and point list if you want simplicity and speed. Attached is a .mat file containing a uniform 200-point ring. My assumption about how much the interpolation would cost for a uniform ring was wrong. The reduction in point count is significant enough that that it's actually faster. Using the precalculated result is faster yet, and it's concise:
S = load('huering.mat');
% put something relevant in the axes
% just to show that the alignment is correct
csview('lab');
xlim([-150 150])
ylim([-150 150])
hold on;
% plot a scatter to make the hue ring
scatter(S.CTa,S.CTb,30,S.newCTrgb,'filled'); hold on
That makes for a relatively solid ring with only 200 points.
This is how I calculated the points and new CT:
% parameters
npoints = 200;
radius = 100;
% get a cyclic rgb color map
CTrgb = hsv(npoints);
CTlch = rgb2lch(ct2im(CTrgb),'lab');
H = rad2deg(unwrap(deg2rad(CTlch(:,:,3))));
newH = linspace(H(1),H(end),npoints).';
newCTrgb = interp1(H,CTrgb,newH);
% get A,B coordinates
CTa = radius*cosd(newH);
CTb = radius*sind(newH);
%save('huering.mat','newCTrgb','CTa','CTb');
I cheated and used MIMT rgb2lch(), but that can be done with rgb2lab() and polar conversions.

댓글을 달려면 로그인하십시오.


Roger Breton
Roger Breton 2022년 3월 9일
A final note. This project is far from over. It's getting all kinds of suggestions and usecases (by me).
I enclose the code, if that could help someone. Here's a screen capture of the current interface:
There's a ton of work, still, needed to be done. But it starts to take shape. You see, on the right, is a page frome the Munsell Book of Colors. This is the hue slice = 10P, a shade of purple. When I click the mouse on the chart, it shows the CIE Lab color location iin 3D on the left. With this kind of image, since there aren't too many "data points", representing discrete colors, it's easy to recognize the 3D structure underlying the Munsell chips. I think that's going to be a good eye opener for students coming into my humble Photoshop classes. Forgot to say, for those of you who are interested, I created an extra graphic function to show the location and orientation of the "Hue angle". Once the user clicks on the "plot2D" button, after clicking a data point with the data cursor tool, there is a black dotted line that appears at the bottom, in the correct orientation of the selected hue color (sorry, I'm always tempted to capitalize the H in the word hue). At first, its length was equal to its a*/b* coordinates but that was not ideal, so I switched to a fixed value. First, same as the Lch circle radius, 100, but then I thought it would be best to expand it, to 128, the maximum a* and b* values I use (8 bit). I think it's doing a terrific job of helping to visualize a color.

제품


릴리스

R2020b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by