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

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

I want to recognize histograms that look like this:

http://matplotlib.sourceforge.net/users/image_tutorial-6.png

since this is a typical form for the text area. How can i do this?

Edit: Thank you for your help.

I compared the histograms obtained from my ROI with the provided histogram of the sample:

hist = cv2.calcHist(roi,[0,1], None, [180,256],ranges) compareValue = cv2.compareHist(hist, samplehist, cv.CV_COMP_CORREL) print "ROI: {0}, compareValue: {1}".format(i,compareValue) 

Assuming ROIs 0, 1, 4, and 5 are text areas, and ROI is an image area, I get the output as follows:

  • ROI: 0, compareValue: 1.0
  • ROI: 1, compareValue: -0.000195522081574 <--- incorrect classification
  • ROI: 2, compareValue: 0.0612670248952
  • ROI: 3, compareValue: -0.000517370176887
  • ROI: 4, compareValue: 1.0
  • ROI: 5, compareValue: 1.0

What can I do to avoid misclassification? For some images, the misclassification rate is about 30%, which is too high.

(I also tried using CV_COMP_CHISQR, CV_COMP_INTERSECT, CV_COMP_BHATTACHARYY and (hist * samplehist) .sum (), but they also provide invalid compareValues)

+6
source share
2 answers

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

If you want to draw histograms, I sent 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

Used to draw two kinds of histograms. The first, applicable to both color and grayscale images, as shown here: http://opencvpython.blogspot.in/2012/04/drawing-histogram-in-opencv-python.html

The second option is exclusive to the grayscale image that matches your image in question.

I will show the second and its modification.

Consider the full image as shown below:

enter image description here

We need to draw a histogram, as you showed. Check out the code below:

 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 a histogram. Remember, this is a full image histogram. For this, we provided None for the mask.

enter image description here

Now I want to find a histogram of some part of the image. The OpenCV histogram function has a masking tool for this. For a normal histogram, you must set it to None . Otherwise, you must specify a mask.

A mask is an 8-bit image where white means this area should be used for histogram calculations, and black means it should not.

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

enter image description here

I changed the last line of code as shown below:

 histogram = hist_lines(img,mask) 

Now see the difference below:

enter image description here

(Remember that the values ​​are normalized, so the values ​​shown are not the actual number of pixels, normalized to 255. Change it as you like.

EDIT:

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

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

There is an official C ++ tutorial. You can find the corresponding Python code here.

+9
source

You can use a simple correlation metric.

  • make sure the histogram you calculated and your link are normal (i.e. represent probabilities)

  • for each histogram calculation (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 link.

+3
source

Source: https://habr.com/ru/post/918771/


All Articles