How to recognize histograms with a specific shape in opencv / python

前端 未结 2 553
星月不相逢
星月不相逢 2021-02-04 18:20

I want to segment images (from magazines) in text and image parts. I have several histograms for several ROIs in my picture. I use opencv with python (cv2).

I want to re

相关标签:
2条回答
  • 2021-02-04 18:57

    You can use a simple correlation metric.

    • make sure that the histogram you compute and your reference are normalized (ie represent probapilities)

    • for each histogram compute (given that myRef and myHist are numpy arrays):

      metric = (myRef * myHist).sum()

    • this metric is a measure of how much the histogram looks like your reference.

    0 讨论(0)
  • 2021-02-04 19:04

    (See the EDIT at the end in case i misunderstood the question) :

    If you are looking to draw the histograms, I had submitted one python sample to OpenCV, and you can get it from here :

    http://code.opencv.org/projects/opencv/repository/entry/trunk/opencv/samples/python2/hist.py

    It is used to draw two kinds of histograms. First one applicable to both color and grayscale images as shown here : http://opencvpython.blogspot.in/2012/04/drawing-histogram-in-opencv-python.html

    Second one is exclusive for grayscale image which is same as your image in the question.

    I will show the second and its modification.

    Consider a full image as below :

    enter image description here

    We need to draw a histogram as you have shown. Check the below code:

    import cv2
    import numpy as np
    
    img = cv2.imread('messi5.jpg')
    mask = cv2.imread('mask.png',0)
    ret,mask = cv2.threshold(mask,127,255,0)
    
    def hist_lines(im,mask):
        h = np.zeros((300,256,3))
        if len(im.shape)!=2:
            print "hist_lines applicable only for grayscale images"
            #print "so converting image to grayscale for representation"
            im = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
        hist_item = cv2.calcHist([im],[0],mask,[256],[0,255])
        cv2.normalize(hist_item,hist_item,0,255,cv2.NORM_MINMAX)
        hist=np.int32(np.around(hist_item))
        for x,y in enumerate(hist):
            cv2.line(h,(x,0),(x,y),(255,255,255))
        y = np.flipud(h)
        return y
    
    histogram = hist_lines(img,None)
    

    And below is the histogram we got. Remember it is histogram of full image. For that,we have given None for mask.

    enter image description here

    Now I want to find the histogram of some part of the image. OpenCV histogram function has got a mask facility for that. For normal histogram, you should set it None. Otherwise you have to specify the mask.

    Mask is a 8-bit image, where white denotes that region should be used for histogram calculations, and black means it should not.

    So I used a mask like below ( created using paint, you have to create your own mask for your purposes).

    enter image description here

    I changed the last line of code as below :

    histogram = hist_lines(img,mask)
    

    Now see the difference below :

    enter image description here

    (Remember, values are normalized, so values shown are not actual pixel count, normalized to 255. Change it as you like.)

    EDIT :

    I think i misunderstood your question. You need to compare histograms, right ?

    If that is what you wanted, you can use cv2.compareHist function.

    There is an official tutorial about this in C++. You can find its corresponding Python code here.

    0 讨论(0)
提交回复
热议问题