You are on page 1of 10

Color Balance Algorithm

Pi19404
December 16, 2012

Contents

Contents
Contrast Stretching
0.1 0.2 Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4
5 5

3 | 10

Contrast Stretching

Contrast Stretching
A constrast stretching is a method to improve the contrast of the image so that values of channel occupy the maximal range of [0,255] for 8 Bit image.This can be performed by applying a afne transformation ax+b to each channel,we need to chose a,b such that maximal value becomes 255 and minimal value 0. But this method has the drawback that it may introduce artifacts in some cases . consider the situation that Red channel occupies values in the range 0-10 . Contrast stretching stretches the range to take values in the range 0-255 ,initiallly pixels near zero values will begin to take large values. The same is the case if bright pixels dominate the channel,it will lead to some of values becoming dark after stretching ,this would not provide a visually appealing output. To avoid the above cases ,the contrast stretching is performed for only on a subset of range occupied by the channel.The present algorithm based on the predened critera determine the range [vmin , vmax ].The values below vmin are saturated to take value 0 ,value above vmax are saturated to take value 255 and contrast stretching is perfomed for the pixels in the range [vmin , vmax ] The input to algorithm is the % of pixels to saturate above and below. Let parameters be s1 % and s2 % for higher and lower saturation thresholds. Let N be the total number of pixels in the image.s1 N% of pixels in lower range and s2 N% of pixels in higher range are pixels to be saturaged. The algorithm can be implemented as follows : 1. Compute Histogram of image 2. Compute the Cumulative distribution function of image 3. Find pixel index i1 and i2 such that CDF = s1 N%,and pixel index such that CDF = (1 s2 ) N% 4. Set all pixels less than i1 to 0 and all pixel greater than i2 to 255. 5. For all pixels in the range [i1 , i2 ] apply afne transformation to perform contrast stretching. ( pi i1 ) 255 pi = ( i2 i1 ) For color images the above algorithm is applied on each of channels of the image.

4 | 10

0.1 Examples

Attached are output of standard contrast stretching and present algorithm

(a) contrast stretching

(b) present algorithm


Figure 1: Example 1

(a) contrast stretching

(b) present algorithm


Figure 2: Example 2

0.2 Code

The code in included in the document however le can opened/saved by clicking on the icon

11

13

15

/ This i s a sample program t o demonstrate a simple c o l o r b a l a n c e a l g o r i t h m a t h t t p ://www. i p o l . im/pub/ a r t /2011/ llmps scb using opencv Copyright (C) 2012 by p i 1 9 4 0 4 This program i s f r e e s o f t w a r e : you can r e d i s t r i b u t e i t and/or modify i t under t h e terms o f t h e GNU General P u b l i c L i c e n s e as published by t h e Free Software Foundation , e i t h e r v e r s i o n 3 o f t h e License , or ( a t your o p t i o n ) any l a t e r v e r s i o n . This program i s d i s t r i b u t e d i n t h e hope t h a t i t w i l l be u s e f u l , but WITHOUT ANY WARRANTY; without even t h e implied warranty o f MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See t h e GNU General P u b l i c L i c e n s e f o r more d e t a i l s .

5 | 10

Contrast Stretching
You should have r e c e i v e d a copy o f t h e GNU General P u b l i c L i c e n s e along with t h i s program . I f not , s e e < h t t p ://www. gnu . org/ l i c e n s e s / >. / / @ f i l e c o l o r _ b a l a n c e 1 . cpp @ b r i e f sample program t o demonstrate simple c o l o r b a l a n c e a l g o r i t h m h t t p ://www. i p o l . im/pub/ a r t /2011/ llmps scb/ using opencv @author p i 1 9 4 0 4 <pi19404@gmail . com> / # include # include # include # include " opencv2/highgui/highgui . hpp " " opencv2/imgproc/imgproc . hpp " <iostream > < s t d i o . h>

17

19

21

23

25

27

29

31

using namespace s t d ;
33

using namespace cv ;
35

37

39

41

43

void c o n t r a s t _ s t r e t c h i n g ( Mat s r c , Mat dst , i n t min , i n t max , i n t index ) { i n t norm [ 2 5 6 ] ; i f ( max<=min ) { cv : : Mat_<cv : : Vec3b > : : c o n s t _ i t e r a t o r i t = s r c . begin <cv : : Vec3b > ( ) ; cv : : Mat_<cv : : Vec3b > : : c o n s t _ i t e r a t o r i t e n d = s r c . end<cv : : Vec3b > ( ) ; cv : : Mat_<cv : : Vec3b > : : i t e r a t o r i t o u t = d s t . begin <cv : : Vec3b > ( ) ; f o r ( ; i t ! = i t e n d ; ++ i t , ++ i t o u t ) {

45

47

49

51

cv : : Vec3b c o l o r 1 = i t ; c o l o r 1 [ index ] = 2 5 5 / 2 ; itout=color1 ;

53

55

}
57

59

} else {

61

63

65

i n t i =0; f o r ( i = 0 ; i < min ; i ++) norm [ i ] = 0 ; f o r ( i =min ; i < max ; i ++) {

67

6 | 10

69

norm [ i ] = ( ( i min ) 2 5 5 / ( (max min ) + 0 . 5 ) ) ; // c e r r << i << " : " << norm [ i ] << endl ; } f o r ( i = max ; i < 255 + 1 ; i ++) norm [ i ] = 2 5 5 ; cv : : Mat_<cv : : Vec3b > : : c o n s t _ i t e r a t o r i t = s r c . begin <cv : : Vec3b > ( ) ; cv : : Mat_<cv : : Vec3b > : : c o n s t _ i t e r a t o r i t e n d = s r c . end<cv : : Vec3b > ( ) ; cv : : Mat_<cv : : Vec3b > : : i t e r a t o r i t o u t = d s t . begin <cv : : Vec3b > ( ) ; f o r ( ; i t ! = i t e n d ; ++ i t , ++ i t o u t ) { cv : : Vec3b c o l o r = i t ; cv : : Vec3b c o l o r 1 = i t o u t ; // c e r r << ( i n t ) c o l o r [ 2 ] < <" ," <<norm [ c o l o r [ 2 ] ] << " : " ; c o l o r 1 [ index ]=norm [ c o l o r [ index ] ] ; itout=color1 ;

71

73

75

77

79

81

83

85

87

89

91

} } } i n t main ( i n t argc , char argv [ ] ) {

93

95

97

99

101

103

105

i f ( a r g c <2 ) { c e r r << " Usage : c o l o r _ b a l a n c e 1 { i n p u t _ f i l e n a m e } " << endl ; return 1; } namedWindow ( "AAA" , CV_WINDOW_AUTOSIZE ) ; s t r i n g f i l e =argv [ 1 ] ; //"/ media/LINUX/machine/ t e s t / 0 . j p g " ;

107

109

111

//IplImage o=cvLoadImage ( f i l e . c _ s t r ( ) , 1 ) ; Mat s r c ; //Mat ( o ) ; s r c =cv : : imread ( f i l e . c _ s t r ( ) , 1 ) ;

113

115

117

119

121

Mat d s t ; i f ( s r c . empty ( ) ) { c e r r << " Cannot load image " << " " << f i l e . c _ s t r ( ) << endl ; return 1; } else

7 | 10

Contrast Stretching
123

c e r r << s r c . c o l s << " " << s r c . rows << " " ;

125

s r c . copyTo ( d s t ) ;
127

129

Mat s r c 1 ; s r c . copyTo ( s r c 1 ) ;

131

133

i n t N= s r c . rows s r c . c o l s ; f l o a t s1 = 1 . 5 , s2 = 1 . 5 ;

135

137

139

141

v e c t o r <Mat> b g r _ p l a n e s ; s p l i t ( src , bgr_planes ) ;

143

145

/// E s t a b l i s h t h e number o f b i n s int histSize = 256; /// S e t t h e ranges ( f o r B , G, R) ) f l o a t range [ ] = { 0 , 2 5 6 } ; c o n s t f l o a t histRange = { range } ; bool uniform = t r u e ; bool accumulate = f a l s e ;

147

149

151

153

155

157

159

Mat b _ h i s t , g _ h i s t , r _ h i s t ; float cbhist [ histSize ] , cghist [ histSize ] , crhist [ histSize ] ; i n t vmin1 =0 , vmin2 =0 , vmin3 = 0 ; i n t vmax1 = h i s t S i z e 1 , vmax2= h i s t S i z e 1,vmax3= h i s t S i z e 1; vmax2=vmax1 ; vmax3=vmax1 ;

161

163

165

/// Compute t h e histograms : c a l c H i s t ( &b g r _ p l a n e s [ 0 ] , 1 , 0 , Mat ( ) , b _ h i s t , 1 , &h i s t S i z e , &histRange , uniform , accumulate ) ; c a l c H i s t ( &b g r _ p l a n e s [ 1 ] , 1 , 0 , Mat ( ) , g _ h i s t , 1 , &h i s t S i z e , &histRange , uniform , accumulate ) ; c a l c H i s t ( &b g r _ p l a n e s [ 2 ] , 1 , 0 , Mat ( ) , r _ h i s t , 1 , &h i s t S i z e , &histRange , uniform , accumulate ) ;

167

169

171

173

//compute t h e CDF f o r ( i n t i = 0 ; i < h i s t S i z e ; i ++) { i f ( i ==0) {

8 | 10

175

c b h i s t [ i ]= b _ h i s t . at < f l o a t >( i ) ; c g h i s t [ i ]= g _ h i s t . at < f l o a t >( i ) ; c r h i s t [ i ]= r _ h i s t . at < f l o a t >( i ) ; } else { c b h i s t [ i ] = ( c b h i s t [ i 1]+ b _ h i s t . at < f l o a t >( i ) ) ; c g h i s t [ i ] = ( c g h i s t [ i 1]+ g _ h i s t . at < f l o a t >( i ) ) ; c r h i s t [ i ] = ( c r h i s t [ i 1]+ r _ h i s t . at < f l o a t >( i ) ) ; } }

177

179

181

183

185

187

// f i n d t h e lower and uppder s a t u r a t i o n t h r e s h o l d s f o r a l l t h e t h r e e channels


189

191

while ( vmin1< h i s t S i z e 1 && c b h i s t [ vmin1 ] <= ( f l o a t )N s1 / 1 0 0 ) { vmin1 = vmin1 + 1 ; }

193

195

197

while ( vmax1 < h i s t S i z e vmax1 = vmax1 1 ; i f ( vmax1 < h i s t S i z e 1) vmax1 =vmax1 + 1 ;

&& c b h i s t [ vmax1 ] > ( f l o a t )N ( 1 s2 / 1 0 0 ) )

199

201

203

while ( vmin2< h i s t S i z e 1 && c g h i s t [ vmin2 ] <= ( f l o a t )N s1 / 1 0 0 ) vmin2 = vmin2 + 1 ; while ( vmax2 < h i s t S i z e && c g h i s t [ vmax2 ] >( f l o a t ) N ( 1 s2 / 1 0 0 ) ) vmax2 = vmax2 1 ;

205

207

209

211

while ( vmin3< h i s t S i z e 1 && c r h i s t [ vmin3 ] <= ( f l o a t )N s1 / 1 0 0 ) vmin3 = vmin3 + 1 ; while ( vmax3 < h i s t S i z e && vmax3 = vmax3 1 ; c r h i s t [ vmax3 ] > ( f l o a t )N ( 1 s2 / 1 0 0 ) )

213

215

217

219

i f ( vmax2 < h i s t S i z e 1) vmax2 =vmax2 + 1 ; i f ( vmax3 < h i s t S i z e 1) vmax3 =vmax3 + 1 ;

221

223

225

i n t norm [ 2 5 6 ] ;

9 | 10

Contrast Stretching
227

229

c e r r << " : " << vmin1 c e r r << " : " << vmin2 c e r r << " : " << vmin3

<< " : " << vmax1 << endl ; << " : " << vmax2 << endl ; << " : " << vmax3 << endl ;

231

233

//perform c o n t r a s t s t r e t c h i n g c o n t r a s t _ s t r e t c h i n g ( s r c 1 , dst , vmin1 , vmax1 , 0 ) ; c o n t r a s t _ s t r e t c h i n g ( s r c 1 , dst , vmin2 , vmax2 , 1 ) ; c o n t r a s t _ s t r e t c h i n g ( s r c 1 , dst , vmin3 , vmax3 , 2 ) ; bgr_planes ; s p l i t ( src1 , bgr_planes ) ; cv : : normalize ( b g r _ p l a n e s [ 0 ] , b g r _ p l a n e s [ 0 ] , 0 , 2 5 5 ,NORM_MINMAX) ; cv : : normalize ( b g r _ p l a n e s [ 1 ] , b g r _ p l a n e s [ 1 ] , 0 , 2 5 5 ,NORM_MINMAX) ; cv : : normalize ( b g r _ p l a n e s [ 2 ] , b g r _ p l a n e s [ 2 ] , 0 , 2 5 5 ,NORM_MINMAX) ; cv : : merge ( bgr_planes , s r c 1 ) ; imwrite ( " /media/SOFTWARES/Dropbox/Dropbox/ r e p o s i t o r y /im/documents/o2 . png " , dst ) ; imwrite ( " /media/SOFTWARES/Dropbox/Dropbox/ r e p o s i t o r y /im/documents/s2 . png " , src1 ) ; cv : : imshow ( "AAA" , s r c 1 ) ; cv : : imshow ( " BBB " , d s t ) ; waitKey ( 0 ) ; return 0;

235

237

239

241

243

245

247

249

251

253

} Listing 1: A Simple Color Balance algorithm in opencv

0.3 References

1. http://www.ipol.im/pub/art/2011/llmps-scb/ 2. Limare, Nicolas, Jose-Luis Lisani, Jean-Michel Morel, Ana Beln Petro, and Catalina Sbert. Simplest Color Balance. Image Processing On Line 2011 (2011). 3. Wikipedia contributors, "Color balance", Wikipedia, The Free Encyclopedia

10 | 10