Can I convert shades of red (Pink, Red, Maroon) in this RGB image to one single color, lets say blue?

11 views (last 30 days)
Hi,Consider this first image,
What I need to do is detect the pixels that have all the shades of red (not pure red), and replace the value in each of those pixels to another color, let's say pure blue.
Can I achieve this using MATLAB?
P.S - The images are drawn on paintbrush so please pardon me for the bad quality, they are meant to be zoomed in pixel data.

Answers (1)

DGM
DGM on 19 May 2022
Edited: DGM on 7 Jul 2022
Greetings from the distant future. Since the question leaves some details unknown and OP likely no longer needs the answer, I'm going to be a bit general in the response. I'm going to interpret this as roughly "how do I change one color to another". There are other answers that cover similar tasks, but I figured I'd point out a few things here first.
First should be obvious. The image has been horribly damaged by JPG compression. Depending on your goals, this may have already made the task impractical.
inpict = imread('popsquares.jpg');
[R G B] = imsplit(inpict);
% mask of pixels which are predominantly red
mostlyred = (R > G) & (R > B);
imshow(mostlyred)
Trying to do any sort of masking on an image that's this heavily damaged will be difficult, as features like the thin lines between the blocks are comparable in distinctness to the artifacts. While not all interpretations of the problem require masking, it's good to avoid unnecessary and conspicuous damage to your images.
So let's assume we have better control over our working images, and have avoided said damage. I'm going to include a couple quick examples. First, we need to construct a test image.
% tiling parameters
tiling = [6 5]; % [tilesdown tilesacross]
tilesz = [50 75]; % size of each tile (px)
padsz = 1; % border width around each tile (px)
ncolored = 25; % number of tiles to be colorized
% make constrained random HSV color table
hswing = 0.1; % range of hue variation
mins = 0.6; % minimum saturation
H = mod(hswing*rand(ncolored,1) - hswing/2,1);
S = (1-mins)*rand(ncolored,1) + mins;
V = rand(ncolored,1);
ct = im2uint8(hsv2rgb([H S V]));
% create tiled image with borders between tiles
redpict = [ct; zeros(prod(tiling)-ncolored,3,'uint8')]; % add black elements
redpict = redpict(randperm(prod(tiling)),:); % shuffle rows
redpict = permute(redpict,[4 3 2 1]); % permute to a 4D array
redpict = repmat(redpict,[tilesz 1 1]); % expand to MxNx3xnumtiles
redpict = padarray(redpict,[1 1 0 0]*padsz,0,'both'); % pad tiles
redpict = imtile(redpict,tiling); % this is MIMT imtile(), not IPT imtile()
imshow(redpict)
The simple thing to do would be to simply rotate the hue of the image. This preserves the hue variation within the image and requires no masking, so the artifacts aren't a showstopper. The color model you use can make a significant difference, and note that hue angles between the primary-secondary corners aren't always 60 degrees. Operaing in HSV/HSL works, but apparent brightness is poorly preserved. Operating in CIELAB has good brightness preservation, but it tends to exaggerate hue swings near the blue corner, making things unexpectedly purple. OKLAB and SRLAB are attempts (in part) to reduce the issue.
% adjust hue across entire image (angle from red to blue corner)
%adjustedpict = imtweak(redpict,'hsl',[0.66 1 1]); % 240deg in HSL
%adjustedpict = imtweak(redpict,'lchab',[1 1 0.74]); % 266deg in CIELAB
adjustedpict = imtweak(redpict,'lchok',[1 1 0.65]); % 234deg in OKLAB
imshow(adjustedpict)
Alternatively, you might not even want to preserve the hue variation. You could simply replace the hue entirely. This would still preserve the brightness and saturation variation.
% replace hue while preserving brightness and saturation
cpict = colorpict(imsize(redpict,3),[0 135 240],'uint8');
blendpict = imblend(cpict,redpict,1,'hue'); % replace hue in CIELAB
imshow(blendpict)
But if what you really want is replacement with a solid color fill, then you'll have to come up with a means of creating a mask that describes the regions you want to fill.
% simply replace red-dominant pixels with a fixed color
[R G B] = imsplit(redpict);
mostlyred = (R > G) & (R > B); % mask like before
filledpict = replacepixels([0 135 240]/255,redpict,mostlyred);
imshow(filledpict)
For brevity in these examples, I've used several functions (imtile, imtweak, colorpict, replacepixels) which are from MIMT (on the File Exchange). There are generally ways to avoid them, but they are convenient and succinct.
For another example of changing colors in an image, try the reference answer in this thread. The answer there links to other references that may help depending on your specific needs. Some of the links also cover ways of doing similar sub-tasks (hue adjustment, composition, colorization) without the associated MIMT tools.

Community Treasure Hunt

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

Start Hunting!