## Saturday, August 16, 2014

### Selective Color Modification

I wanted to change the blue color of the road in the following picture to a green color. I wrote a MatLab program and run it in Octave. Although I can simply use rgb color model to swap blue and green, I feel like it is too specific. That is why, I used hsv color model to change a hue of a color in a more flexible manner.
Matlab program is shown below and the explanation is written as comments.
%enter 'pkg load image' in the octave command windows
%to load the required image processing package.
%----------------------------------------------------------------------
%get images
I=im2double(I);
%----------------------------------------------------------------------
%convert to HSV
Ihsv=rgb2hsv(I);
Ih=Ihsv(:,:,1);
Is=Ihsv(:,:,2);
Iv=Ihsv(:,:,3);
%----------------------------------------------------------------------
%get the mask for blue primary which is at 240 degree in hsv
bdeg=240/360;
Im=abs(Ih-bdeg);
%since the distance cannot be larger then 180 degree,
%the values greater than 0.5 should be subtracted from 1
Ii=Im>0.5;
Im=abs(Ii-Im);
%--------------------------------------------------------------------------
%get the global image threshold using Otsu's method
Ith=graythresh(Im);
%--------------------------------------------------------------------------
%make it binary (black and white)
Im=im2bw(Im,Ith);
Im=cat(3,Im,Im,Im);
%--------------------------------------------------------------------------
%define an angle to rotate H in degree
a=240;
%convert to fraction, add to H, and find modulus
Ih=mod(Ih+a./360,1);
%--------------------------------------------------------------------------
%convert to RGB
Ihsv=cat(3,Ih,Is,Iv);
Ic=hsv2rgb(Ihsv);
%--------------------------------------------------------------------------
Ic2=I.*Im+Ic.*(1-Im);
%----------------------------------------------------------------------
%Display results
scrsz = get(0,'ScreenSize');
scrLeft=scrsz(1);
scrBottom=scrsz(2);
scrWidth=scrsz(3);
scrHeight=scrsz(4);

handle1=figure;
set(handle1,'Position',[(100) (100) (scrWidth-200) (scrHeight-200)]);
% Position: Left Bottom Width Height

subplot(1,3,1);
imshow(I);
title('Original');

subplot(1,3,2);
imshow(Ic);
title('Color modification');

subplot(1,3,3);
imshow(Ic2);
title('Selective color modification');
%----------------------------------------------------------------------
imwrite(Ic2,'scc.jpg');

To run the program, Octave and its packages must have been installed. I have discussed about Octave here. To load the package for image processing, the command 'pkg load image' should be entered in the Octave command windows. Then, use 'chdir' command to go to the desired workspace and enter the program filename to run it. The Octave command windows showing all these commands is as follows.
The result of the program and the output image are shown in the following figures.
The MatLab pragram can be found at Selective_Color_Modification on GitHub. An OpenCV version is also added there.
//File: color.cpp
//Description: Selective Color Modification
//WebSite: http://cool-emerald.blogspot.com
//Copyright (c) 2017 Yan Naing Aye

#include
#include
using namespace cv;
int main(int argc, char** argv)
{
Mat image;
if (!image.data) {
printf("No image data \n");
return -1;
}
namedWindow("Display Image", WINDOW_AUTOSIZE);
imshow("Display Image", image);

//Convert to hsv
Mat hsv;
cvtColor(image, hsv, COLOR_BGR2HSV);

//select pixels
//the range of H channel is 0-179.
//blue at 240 deg corresponds to 120 in H channel
Mat bw;
inRange(hsv, Scalar(80, 0, 0), Scalar(140, 255,255), bw);

//Manipulate pixels
for (int i = 0; i < image.rows; i++)
for (int j = 0; j < image.cols; j++)
if (bw.at < uchar > (i, j) > 128)
hsv.at < Vec3b > (i, j)[0] = (hsv.at < Vec3b > (i, j)[0] + 120) % 180;

//Convert to bgr
Mat im2;
cvtColor(hsv, im2, COLOR_HSV2BGR);

namedWindow("Modified Image", WINDOW_AUTOSIZE);
imshow("Modified Image", im2);

waitKey(0);
return 0;
}