Ask Your Question

Revision history [back]

click to hide/show revision 1
initial version

python opencv compare histograms

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)

python opencv compare histograms

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.

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)

python opencv compare histograms

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.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)

python opencv compare histograms

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?