Change specific color in an image to another one
57 次查看(过去 30 天)
显示 更早的评论
Hello,
I am trying to change colors in an image into another color. I have generated some code myself but something seems to be wrong. What I am trying to achieve on the attached file is to change every purple data point into a green data point, or whatever color I would prefer. Currently, the code that I have written is able to change purple to green but the edges of the marked points are still in purple, I believe this has something to do with the intensity at the edges being different or something...
[I,m] = imread('iteration31.png');
%image = imshow(I,'Colormap',m);
rgbImage = ind2rgb(I,m);
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
purplePixels = redChannel == 1 & greenChannel == 0 & blueChannel == 1;
% MAKE THEM GREEN
redChannel(purplePixels) = 0;
greenChannel(purplePixels) = 1;
blueChannel(purplePixels) = 0;
rgbImage = cat(3, redChannel, greenChannel, blueChannel);
imshow(rgbImage);
0 个评论
采纳的回答
Matthew Eicholtz
2017-5-5
This is a tough problem. Since you are using a raster image, objects that look purple are actually many small variations of purple. One thing you could try to do is compute which colors are purple-ish, and then modify those colors in the colormap.
Here is an example that may yield slightly better results than what you were experiencing, but still not perfect:
% Read image
[I,m] = imread('iteration31.png');
% Find purple-ish colors
mask1 = abs(m(:,3)-m(:,1))<0.8;
mask2 = abs(m(:,3)-m(:,2))>0.3;
mask3 = abs(m(:,2)-m(:,1))>0.3;
mask = mask1 & mask2 & mask3;
% Convert purple-ish colors to green-ish colors
m(mask,:) = 1-m(mask,:);
% Create and show newly colored image
rgb = ind2rgb(I,m);
imshow(rgb);
2 个评论
Trying To Learn
2022-9-4
Hi, I got "Index in position 2 exceeds array bounds." error for mask1 = abs(m(:,3)-m(:,1))<0.8;
Could I get the explanation for mask1, mask2, mask3 values? Or somewhere else that I can read for the theory. Thank you.
DGM
2022-9-4
编辑:DGM
2022-9-4
The code works for me without error.
% Read image
[I,m] = imread('iteration31.png');
% Find purple-ish colors
mask1 = abs(m(:,3)-m(:,1))<0.8;
mask2 = abs(m(:,3)-m(:,2))>0.3;
mask3 = abs(m(:,2)-m(:,1))>0.3;
mask = mask1 & mask2 & mask3;
% Convert purple-ish colors to green-ish colors
m(mask,:) = 1-m(mask,:);
% Create and show newly colored image
rgb = ind2rgb(I,m);
imshow(rgb(200:600,1100:1450,:)); % show a small area
As you can see, this still has the problem of leaving fringes at the edge of the target regions. Trying to change the color of a soft-edged region by either direct color replacement or value inversion is always going to give poor results when using a binary mask. The binary mask will always be either overselecting or underselecting the region, and inversion or direct replacement will make the imperfect mask extents conspicuous.
There are various ways to approach this depending on how perfect the results need to be. I may post an answer if my network connection stays up today.
更多回答(1 个)
DGM
2022-9-4
Consider the following example using the OP's original image and task.
% Load image
[idxpict,ct] = imread('iteration31.png');
rgbpict = im2uint8(ind2rgb(idxpict,ct));
% Play around with the thresholds until you get what you want.
thresholds = [0.82 0.85]; % [Hmin Hmax]
hsvpict = rgb2hsv(rgbpict);
isPurple = hsvpict(:,:,1)>0.82 & hsvpict(:,:,1)<0.85;
% clean up the mask
isPurple = imerode(isPurple,ones(2));
% dilate it to hopefully include the extremes of the region extent
isPurple = imdilate(isPurple,ones(3));
imshow(isPurple(250:450,1200:1350,:)) % show a closeup of the mask
% expand to simplify addressing later
isPurpleArray = repmat(isPurple,1,1,3);
% Once you're happy with your thresholds above, adjust the image content.
hsvpict(:,:,1) = mod(hsvpict(:,:,1)-0.5,1); % rotate hue by 180d
adjpict = hsv2rgb(hsvpict);
% combine the adjusted image and the original using logical composition
% images must be the same class and scale
outpict = rgbpict;
outpict(isPurpleArray) = im2uint8(adjpict(isPurpleArray));
% Compare the original and new image.
figure(3)
subplot(1,2,1)
imshow(rgbpict(250:450,1200:1350,:))
title('Original')
subplot(1,2,2)
imshow(outpict(250:450,1200:1350,:))
title('Modified')
This is a relatively simplified case since the colored dots are well separated by neutral colors. In this scenario, there's little harm in making the mask overselect the dots. If the background were not neutral, things would be different.
I've posted a number of answers to "change one color to another" problems. The above example uses no special tools, but some of the other examples use freely available third party tools.
Change the colors in a smoothly-graduated rainbow image (uses MIMT color2alpha())
Naive channel swap, hard masked filling/tweaking, lin masked colorization (color chips against table)
Color squares example (hue rotate, hue replace, solid fill; (mostly MIMT)
Pink strawberries (HSV segmentation & adjustment; no MIMT)
Change hair color (colorization of black objects and the challenges of realism)
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Purple 的更多信息
产品
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!