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=imread('ori.jpg');
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);
imshow(Im);%show the mask
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);
%--------------------------------------------------------------------------
%Modified the masked pixels
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
//MIT License (https://opensource.org/licenses/MIT)
//Copyright (c) 2017 Yan Naing Aye

#include 
#include 
using namespace cv;
int main(int argc, char** argv)
{
 Mat image;
 image = imread("C:/opencv/lane.jpg", 1);
 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);
 namedWindow("Mask", WINDOW_AUTOSIZE);
 imshow("Mask", 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;
}

No comments:

Post a Comment

Comments are moderated and don't be surprised if your comment does not appear promptly.