how to change pixel with the same RGB values

I'm writing a white balance algorithm in matlab. I have to change the RGB values of a pixel in (1,1,1) if it has the same RGB values as my RGB vector. I copied the RGB values of my vector in a matrix with the same size like my picture( x * y * 3(RGB)), because i think it's easier to compare. Now i compare the values with this statement:
input = picture;
tmp = ... % RGB value matrix
input( input(1:end,1:end,1) == tmp(1:end,1:end,1) & input(1:end,1:end,2) == tmp(1:end,1:end,2) & input(1:end,1:end,3) == tmp(1:end,1:end,3) ) = 1;
I think my comparison is wrong, because it's just comparing the Red value with the Red value, the green with the green.... and doesn't test R = R and G = G and B = B then --> R = 1, G = 1, B = 1
Sry for my bad english but some help would be awesome!

 Accepted Answer

I'm not sure what that code attempts to do. Whatever it does, it's not doing white balancing. Why don't you just identify the region of the image that you want to be white, for example by imfreehand or some other method. Then find the actual mean color for that region. Then use imadjust() to linearly scale the actual color values to the desired color values. Do it for each color channel and then recombine. There are more sophisticated methods but I'm sure that will be fine for you.

7 Comments

It's a project for my study. we have to build a simple version of a camera firmware. i'm working on a manual white balance, the user can select a pixel and the color will be replaced by (1,1,1) RGB. The selected pixel refers as a reference point. After that i'm scaling all color values with 1/valueof(x), x... R,G,B of the Pixel. I'm not allowed to use builtin matlab functions. At the moment i'm trying to solve the scaling.
OK, that's fine. That pixel goes to 1,1,1 and for all other pixels in the image, you scale proportionally. Do you want us to review the code that you use to scale all the pixels in the image? Show us what you have so far.
@John: It is impossible to write any meaningful program without using built-in functions. Any assignment or indexing calls built-in functions. So please explain, what you are allowed or not allowed to use more specifically.
For now i have:
function [result] = evc_white_balance(input, white)
%EVC_WHITE_BALANCE
% INPUT
% input ... picture
% white ... RGB vector with replacement color
% OUTPUT
% result... result after white balance
in = input;
in(in(:,:,1) == white(1) & in(:,:,2) == white(2) & in(:,:,3) == white(3)) = 1;
in(:,:,1)= in(:,:,1)*1/white(1);
in(:,:,2)= in(:,:,2)*1/white(2);
in(:,:,3)= in(:,:,3)*1/white(3);
result = in;
end
I think that should be right. Next step will be gamma correction. I actually don't know which functions I'm allowed to use, i have to ask my tutors every time. The demosaic function was one of the functions, i wasn't allowed, only to determine the right bayer pattern of my raw file.
That does color replacement for only one single color. It does not scale the values like I showed you, and thus, it does not do white balancing. Maybe I can write you a demo later this afternoon. I have to go somewhere now.
John, try this demo:
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
imtool close all; % Close all imtool figures if you have the Image Processing Toolbox.
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
% Read in a standard MATLAB color demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'peppers.png';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
if ~exist(fullFileName, 'file')
% Didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
rgbImage = imread(fullFileName);
% Get the dimensions of the image. numberOfColorBands should be = 3.
[rows columns numberOfColorBands] = size(rgbImage);
% Display the original color image.
subplot(2, 4, 1);
imshow(rgbImage);
title('Original Color Image', 'FontSize', fontSize);
% Enlarge figure to full screen.
set(gcf, 'units','normalized','outerposition',[0 0 1 1]);
% Extract the individual red, green, and blue color channels.
redChannel = rgbImage(:, :, 1);
greenChannel = rgbImage(:, :, 2);
blueChannel = rgbImage(:, :, 3);
% Ask user to click a point
message = sprintf('Click on a point that you would like to make white');
button = questdlg(message, 'Continue?', 'OK', 'Cancel', 'OK');
drawnow; % Refresh screen to get rid of dialog box remnants.
if strcmpi(button, 'Cancel')
close all;
return;
end
[column row] = ginput(1);
hold on;
plot(column, row, 'r+', 'MarkerSize', 50, 'LineWidth', 2);
% Convert to integer
row = int32(floor(row));
column = int32(floor(column));
for colorChannel = 1 : 3
% Extract just this color channel.
thisColorChannel = rgbImage(:, :, colorChannel);
% Display the color channel image.
subplot(2, 4, 1+colorChannel);
imshow(thisColorChannel);
caption = sprintf('Original Color Channel #%d', colorChannel);
title(caption, 'FontSize', fontSize);
originalMinValue = 0.0;
originalMaxValue = double(thisColorChannel(row, column)) % Whatever pixel value you clicked on.
originalRange = originalMaxValue - originalMinValue;
% Get a double image in the range 0 to +1
desiredMin = 0;
desiredMax = 255.0;
desiredRange = desiredMax - desiredMin;
dblImage = desiredRange * (double(thisColorChannel) - originalMinValue) / originalRange + desiredMin;
% Display the corrected color channel image.
subplot(2, 4, 5+colorChannel);
imshow(dblImage, []);
caption = sprintf('Corrected Color Channel #%d', colorChannel);
title(caption, 'FontSize', fontSize);
% Build up RGB image
if colorChannel == 1
whiteBalancedImage = dblImage;
else
whiteBalancedImage = cat(3, whiteBalancedImage, dblImage);
end
end
% Convert to uint8
whiteBalancedImage = uint8(whiteBalancedImage);
% Display the White Balanced color image.
subplot(2, 4, 5);
imshow(whiteBalancedImage);
title('White Balanced Image', 'FontSize', fontSize);
Thank you Image Analyst, nice piece of code! This will help me definitely.

Sign in to comment.

More Answers (1)

Currently your code is equivalent to:
in = picture; % avoid to use builtin function name "input" as variable
in(in == tmp) = 1;
When tmp is a [1x3] RGB vector, this would be the code:
in(in(:, :, 1) = tmp(1) & in(:, :, 2) = tmp(2) & in(:, :, 3) = tmp(3)) = 1;
Now all pixels of in, whose color equals the value of tmp, gets white. Why do yout think, that this is not the wanted result?

5 Comments

Then he's doing color replacement, not "white balancing" by the usual definition: White Balancing. Further explanation from John could help us figure out what he really wants to do.
Exactly, Image Analyst. My code is only a simplified version of the original code.
yes a part of that is color replacement, explained in previous post.
I'm new to matlab and I don't know the exact behaviour of the logical operator. I thought it would only replace one value, the red,green or blue value, when i'm not specifying the range of the matrix:
in(...) = 1; %one value
in(:,:,1:3)(logical operations) = 1; %thought such a solution would be right
Thank you for helping me!
You can use code like this:
originalMinValue = 0
originalMaxValue = % Whatever pixel value you clicked on.
originalRange = originalMaxValue - originalMinValue;
% Get a double image in the range 0 to +1
desiredMin = 0;
desiredMax = 1.0;
desiredRange = desiredMax - desiredMin;
dblImage = desiredRange * (double(grayImage) - originalMinValue) / originalRange + desiredMin;
Do that for every color channel image. So grayImage would be redChannel, greenChannel, and blueChannel, each in turn.
thank you! very nice.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!