# -*- coding:utf-8 -*-
"""
Copyright Left (c) justin.seeley.cn@gmail.com
Any usage of this code sniplet is not allowed without author 's permission
"""
import cv
def single_channel_hist( channel ):
""" calculate cumulative histgram of single image channel
return as a list of length 256
"""
hist = cv.CreateHist([256],cv.CV_HIST_ARRAY,[[0,256]],1)
cv.CalcHist([cv.GetImage(channel)],hist)
refHist = [cv.QueryHistValue_1D(hist,i) for i in range(0,256)]
def add(x,y):return x+y
sum = reduce(add,refHist[:])
pdf = [v/sum for v in refHist]
for i in range(1,256):
pdf[i] = pdf[i-1] + pdf[i]
return pdf
def get_channels(img):
"""split jpg image file into 3 seperate channels
return as a list of length 3
"""
channels = []
for i in range(0,3):
_refCh = cv.CreateMat(img.rows, img.cols, cv.CV_8UC1)
channels.append(_refCh)
cv.Split(img,channels[0],channels[1],channels[2],None)
return channels
def cal_hist(channels):
"""
cal cumulative hist for channel list
"""
return [single_channel_hist(channel) for channel in channels]
def cal_trans(ref,adj):
"""
calculate transfer function
algorithm refering to wiki item: Histogram matching
"""
i =0
j = 0;
table = range(0,256)
for i in range( 1,256):
for j in range(1,256):
if ref[i] >= adj[j-1] and ref[i] <= adj[j]:
table[i] = j
break
table[255] = 255
return table
if __name__ == '__main__':
cv.NamedWindow('reference')
cv.NamedWindow('before')
cv.NamedWindow('after')
refImg = cv.LoadImageM('airplane.jpg')
dstImg = cv.LoadImageM('lena.jpg')
refChannels = get_channels(refImg)
dstChannels = get_channels(dstImg)
cv.ShowImage('reference',refImg);
cv.ShowImage('before',dstImg);
hist_ref = cal_hist(refChannels)
hist_dst = cal_hist(dstChannels)
tables = [cal_trans(hist_dst[i],hist_ref[i]) for i in range(0,3)]
for i in range(0,3):
for j in range(0,dstChannels[i].rows):
for k in range(0,dstChannels[i].cols):
v = dstChannels[i][j,k]
dstChannels[i][j,k] = tables[i][int(v)]
cv.Merge(dstChannels[0],dstChannels[1],dstChannels[2],None,dstImg)
cv.ShowImage('after',dstImg)
cv.WaitKey(0)