问题
I'm trying to color only a segment of an image in Matlab. For example, I load an RGB image, then I obtain a mask with Otsu's method (graythresh
). I want to keep the color only in the pixels that have value of 1
after applying im2bw
with graythresh
as the threshold. For example:
image = imread('peppers.png');
thr = graythresh(image);
bw = im2bw(image, thr);
With this code I obtain the following binary image:

My goal is to keep the color in the white pixels.
Thanks!
回答1:
I have another suggestion on how to replace the pixels we don't care about. This works by creating linear indices for each of the slices where black pixels exist in the bw
image. The summation with the result of find
is done because bw
is the size of just one "slice" of image
and this is how we get the indices for the other 2 slices.
Starting MATLAB 2016b:
image(find(~bw)+[0 numel(bw)*[1 2]]) = NaN;
In older versions:
image(bsxfun(@plus,find(~bw),[0 numel(bw)*[1 2]])) = NaN;
Then imshow(image)
gives:
Note that NaN
gets converted to 0
for integer classes.
Following the clarification that the other pixels should be kept in their gray version, see the below code:
% Load image:
img = imread('peppers.png');
% Create a grayscale version:
grayimg = rgb2gray(img);
% Segment image:
if ~verLessThan('matlab','9.0') && exist('imbinarize.m','file') == 2
% R2016a onward:
bw = imbinarize(grayimg);
% Alternatively, work on just one of the color channels, e.g. red:
% bw = imbinarize(img(:,:,1));
else
% Before R2016a:
thr = graythresh(grayimg);
bw = im2bw(grayimg, thr);
end
output_img = repmat(grayimg,[1 1 3]);
colorpix = bsxfun(@plus,find(bw),[0 numel(bw)*[1 2]]);
output_img(colorpix) = img(colorpix);
figure; imshow(output_img);
The result when binarizing using only the red channel:
回答2:
Your question misses "and replace the rest with black". here are two ways:
A compact solution: use bsxfun:
newImage = bsxfun(@times, Image, cast(bw, 'like', Image));
Although I am glad with the previous one, you can also take a look at this step-by-step approach:
% separate the RGB layers:
R = image(:,:,1);
G = image(:,:,2);
B = image(:,:,3);
% change the values to zero or your desired color wherever bw is false:
R(~bw) = 0;
G(~bw) = 0;
B(~bw) = 0;
% concatenate the results:
newImage = cat(3, R, G, B);
Which can give you different replacements for the black region:
UPDATE:
According to the comments, the false
area of bw
should be replaced with grayscale image of the same input. This is how to achieve it:
image = imread('peppers.png');
thr = graythresh(image);
bw = im2bw(image, thr);
gr = rgb2gray(image); % generate grayscale image from RGB
newImage(repmat(~bw, 1, 1, 3)) = repmat(gr(~bw), 1, 1, 3); % substitude values
% figure; imshow(newImage)
With this result:
来源:https://stackoverflow.com/questions/40056713/color-only-a-segment-of-an-image-in-matlab