Can someone help me with changing colors on insertShape function??
4 ビュー (過去 30 日間)
古いコメントを表示
I know there are certain colors avaible within the function, but I want to change them to my own using color vectors. Whenever I use the vector, my shape just turn black. Does anyone have any suggestions?
3 件のコメント
Greg
2018 年 3 月 23 日
Don't "believe" what your data types are - check! Also, a single variable cannot be both double and uint8.
Post your relevant code, and put in breakpoints to check the class of your color vector input and confirm it.
回答 (2 件)
sierra knighten
2018 年 3 月 24 日
1 件のコメント
Walter Roberson
2018 年 3 月 24 日
We encounter a fair number of programs in which the data type turns out to be different than the person expected, and the reason is often not obvious. We especially tend to encounter programs in which the person had a uint8 image array, applies an operation that leads to floating point values with the same general magnitude, and then has trouble displaying the results. Using the debugger to check what is really there is an important step in tracking down display problems.
DGM
2023 年 9 月 11 日
編集済み: DGM
2023 年 9 月 12 日
Both CVT insertShape() and insertText() differ from most other IPT/base MATLAB tools, in that the color tuples/tables they accept are not unit-scale floats. They are expected to be scaled appropriately for the class of the accompanying image, while the class of the tuple or table itself is ignored.
So if your input image is uint8, then the color does not need to be uint8 class, but it does need to be uint8-scale.
color = lines(1); % a very familiar blue (unit-scale double)
img = imread('peppers.png'); % double
% uint8 image and unit-scale float tuple (doesn't work)
thiscolor = color;
img = insertShape(img, 'Line', [50 20 200 500],'Color',thiscolor,'LineWidth',15);
img = insertText (img,[400 100],'banana','TextColor',thiscolor,'boxcolor','y','FontSize',18);
% uint8 image and uint8-scale float tuple (ridiculous, but works)
thiscolor = color*255; % improperly-scaled
img = insertShape(img, 'Line', [150 20 300 500],'Color',thiscolor,'LineWidth',15);
img = insertText (img,[400 200],'banana','TextColor',thiscolor,'boxcolor','y','FontSize',18);
% uint8 image and uint8 tuple (works)
thiscolor = im2uint8(color); % properly-scaled, but breaks existing conventions
img = insertShape(img, 'Line', [250 20 400 500],'Color',thiscolor,'LineWidth',15);
img = insertText (img,[400 300],'banana','TextColor',thiscolor,'boxcolor','y','FontSize',18);
imshow(img,'border','tight')
If you ask me, this is a terrible design choice that can only complicate the workflow and cause confusion. If the class of the incoming image is subject to change, then there is no convenient method to programmatically prepare a correctly-scaled or cast color tuple within the scope of what's available in IPT/MATLAB. This goes doubly so if we're encouraging a workflow where the color tuple/table can't be trusted to be scaled consistently or at least scaled according to its own class. At that point, we're left to guess what the color scale is.
% some inputs
inpict = imread('peppers.png');
color = lines(1); % unit-scale float
position = [50 20 200 500];
% but let's say they might vary
inpict = im2uint16(inpict); % assume image class may vary, but is always correctly-scaled
color = double(im2int16(color)); % assume color class may vary and is not correctly-scaled
% fix the color scale to match the image! so easy!
color = fixthestupidcolor(inpict,color);
% now we can use insertShape() like normal!
outpict = insertShape(inpict, 'Line', position, 'Color', color, 'LineWidth',15);
% look at that! it just works!
imshow(outpict,'border','tight')
% it only takes all of this horrible fragile garbage to make it work.
function newcolor = fixthestupidcolor(inpict,color)
inrg = getrange(guessclass(color)); % guess the input scale
outrg = getrange(class(inpict)); % get the output scale
newcolor = (outrg(2)-outrg(1))*(double(color)-inrg(1))/(inrg(2)-inrg(1))+outrg(1); % rescale the color
end
function thisrange = getrange(classname)
% IPT getrangefromclass() doesn't take a simple class name
% it takes the whole array, so we have to make a dummy
x = ones(1,classname);
thisrange = getrangefromclass(x);
end
function thisclass = guessclass(color)
% this is a complete garbage workaround and will undoubtedly fail
% to correctly guess certain inputs.
% assume that if the color is integer-class, that it is correctly-scaled
% we can't actually be certain this assumption is correct, but oh well
if isinteger(color)
thisclass = class(color);
return;
end
% but if it is float class, its scale can't be trusted, so we have to guess
tol = 0.25; % allow some margin for OOG colors
extrema = [min(color(:)) max(color(:))];
if extrema(1)>=-tol && extrema(2)<=(1+tol)
thisclass = 'double';
elseif extrema(1)>=-tol*255 && extrema(2)<=(1+tol)*255
thisclass = 'uint8';
elseif extrema(1)>=-tol*65535 && extrema(2)<=(1+tol)*65535
thisclass = 'uint16';
elseif extrema(1)>=-(1+tol)*32768 && extrema(2)<=(1+tol)*32767
thisclass = 'int16';
else
error('this is what happens when you are forced to guess')
end
end
1 件のコメント
DGM
2024 年 4 月 27 日
If I were using insertShape()/insertText(), how would I deal with the routinely problematic interpretation of color tuples?
% cast and rescale any properly-scaled image or color value
thiscolor = imcast(color,class(img));
So long as you keep all your images and color tables properly-scaled with respect to their class, then you don't have to play stupid guessing games.
Of course, base MATLAB/IPT have no convenient way to cast and rescale data based on a variable class specification, since all of the tools to do that have the primary parameter baked into their function names like some kind of eval()-bait.
MIMT imcast() will do that, and it will work for a broader range of numeric classes than the IPT tools will.
参考
カテゴリ
Help Center および File Exchange で Feature Detection and Extraction についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!

