I'm trying to compare 2 histograms in python.
But it give me an error "sc= cv.CompareHist(hist_item1, hist_item2, cv.CV_COMP_CORREL)
TypeError: Expected CvHistogram for argument 'hist1'"
here is the code:
import cv2
import cv
import numpy as np
import time
img1 = cv2.imread('C:/ICP/buterfly_1.jpg')
img1= cv2.cvtColor(img1,cv.CV_BGR2HSV)
img2 = cv2.imread('C:/ICP/buterfly_0.jpg')
img2= cv2.cvtColor(img2,cv.CV_BGR2HSV)
h = np.zeros((300,256,3))
bins = np.arange(256).reshape(256,1)
color = [ (255,0,0),(0,255,0),(0,0,255) ]
for ch, col in enumerate(color):
hist_item1 = cv2.calcHist([img1],[ch],None,[256],[0,255])
hist_item2 = cv2.calcHist([img2],[ch],None,[256],[0,255])
cv2.normalize(hist_item1,hist_item1,0,255,cv2.NORM_MINMAX)
cv2.normalize(hist_item2,hist_item2,0,255,cv2.NORM_MINMAX)
sc= cv.CompareHist(hist_item1, hist_item2, cv.CV_COMP_CORREL)
printsc
hist=np.int32(np.around(hist_item))
pts = np.column_stack((bins,hist))
cv2.polylines(h,[pts],False,col)
h=np.flipud(h)
cv2.imwrite('C:/hist.png',h)
UPDATE:i found this code and it seems work, but I think it's not opencv-style, maybe better way exist?
import numpy
from PIL import Image
import cv2
def similarness(image1,image2):
"""
Return the correlation distance be1tween the histograms. This is 'normalized' so that
1 is a perfect match while -1 is a complete mismatch and 0 is no match.
"""
# Open and resize images to 200x200
i1 = Image.open(image1).resize((200,200))
i2 = Image.open(image2).resize((200,200))
# Get histogram and seperate into RGB channels
i1hist = numpy.array(i1.histogram()).astype('float32')
i1r, i1b, i1g = i1hist[0:256], i1hist[256:256*2], i1hist[256*2:]
# Re bin the histogram from 256 bins to 48 for each channel
i1rh = numpy.array([sum(i1r[i*16:16*(i+1)]) for i in range(16)]).astype('float32')
i1bh = numpy.array([sum(i1b[i*16:16*(i+1)]) for i in range(16)]).astype('float32')
i1gh = numpy.array([sum(i1g[i*16:16*(i+1)]) for i in range(16)]).astype('float32')
# Combine all the channels back into one array
i1histbin = numpy.ravel([i1rh, i1bh, i1gh]).astype('float32')
# Same steps for the second image
i2hist = numpy.array(i2.histogram()).astype('float32')
i2r, i2b, i2g = i2hist[0:256], i2hist[256:256*2], i2hist[256*2:]
i2rh = numpy.array([sum(i2r[i*16:16*(i+1)]) for i in range(16)]).astype('float32')
i2bh = numpy.array([sum(i2b[i*16:16*(i+1)]) for i in range(16)]).astype('float32')
i2gh = numpy.array([sum(i2g[i*16:16*(i+1)]) for i in range(16)]).astype('float32')
i2histbin = numpy.ravel([i2rh, i2bh, i2gh]).astype('float32')
return cv2.compareHist(i1histbin, i2histbin, 0)
and I find another method with old cv namespace
import cv
def compute_histogram(src, h_bins = 30, s_bins = 32, scale = 10):
#create images
hsv = cv.CreateImage(cv.GetSize(src), 8, 3)
hplane = cv.CreateImage(cv.GetSize(src), 8, 1)
splane = cv.CreateImage(cv.GetSize(src), 8, 1)
vplane = cv.CreateImage(cv.GetSize(src), 8, 1)
planes = [hplane, splane]
cv.CvtColor(src, hsv, cv.CV_BGR2HSV)
cv.CvtPixToPlane(hsv, hplane, splane, vplane, None)
#compute histogram
hist = cv.CreateHist((h_bins, s_bins), cv.CV_HIST_ARRAY,
ranges = ((0, 180),(0, 255)), uniform = True)
cv.CalcHist(planes, hist) #compute histogram
cv.NormalizeHist(hist, 1.0) #normalize histo
return hist
src1 = cv.LoadImage("C:/ICP/buterfly_0.jpg", cv.CV_LOAD_IMAGE_COLOR)
src2 = cv.LoadImage("C:/ICP/buterfly_1.jpg", cv.CV_LOAD_IMAGE_COLOR)
hist1= compute_histogram(src1)
hist2= compute_histogram(src2)
sc= cv.CompareHist(hist1, hist2, cv.CV_COMP_BHATTACHARYYA)
print sc
And I want to know if I have a lot of images and have precomputed histograms for them stored in db, how to fast find best k nearest matches?