6

我想在文本和图像部分中分割图像(来自杂志)。我的图片中有几个 ROI 的几个直方图。我将opencv与python(cv2)一起使用。

我想识别看起来像这样的直方图

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

因为它是文本区域的典型形状。我怎样才能做到这一点?

编辑:感谢您到目前为止的帮助。

我将我从 ROI 中获得的直方图与我提供的示例直方图进行了比较:

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)

假设 ROI 0、1、4 和 5 是文本区域,而 ROI 是图像区域,我得到如下输出:

  • 投资回报率:0,比较值:1.0
  • ROI: 1, compareValue: -0.000195522081574 <--- 分类错误
  • 投资回报率:2,比较值:0.0612670248952
  • 投资回报率:3,比较值:-0.000517370176887
  • 投资回报率:4,比较值:1.0
  • 投资回报率:5,比较值:1.0

我能做些什么来避免错误的分类?对于某些图像,错误分类率约为 30%,这太高了。

(我也尝试使用 CV_COMP_CHISQR、CV_COMP_INTERSECT、CV_COMP_BHATTACHARYY 和 (hist*samplehist).sum() 但它们也提供了错误的 compareValues)

4

2 回答 2

9

(如果我误解了这个问题,请参阅最后的编辑):

如果你想绘制直方图,我已经向 OpenCV 提交了一个 python 样本,你可以从这里获得它:

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

它用于绘制两种直方图。第一个适用于彩色和灰度图像,如下所示:http: //opencvpython.blogspot.in/2012/04/drawing-histogram-in-opencv-python.html

第二个专用于灰度图像,与您在问题中的图像相同。

我将展示第二个及其修改。

考虑如下完整图像:

在此处输入图像描述

如您所示,我们需要绘制直方图。检查以下代码:

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)

下面是我们得到的直方图。请记住,它是完整图像的直方图。为此,我们提供None了面具。

在此处输入图像描述

现在我想找到图像某些部分的直方图。OpenCV 直方图函数为此提供了掩码工具。对于正常的直方图,你应该设置它None。否则,您必须指定掩码。

掩码是一个 8 位图像,其中白色表示该区域应该用于直方图计算,黑色表示不应该。

所以我使用了一个像下面这样的蒙版(使用油漆创建,你必须为你的目的创建自己的蒙版)。

在此处输入图像描述

我将最后一行代码更改如下:

histogram = hist_lines(img,mask)

现在看看下面的区别:

在此处输入图像描述

(请记住,值是标准化的,因此显示的值不是实际的像素数,标准化为 255。根据需要更改它。)

编辑 :

我想我误解了你的问题。您需要比较直方图,对吗?

如果这是你想要的,你可以使用cv2.compareHist函数。

在 C++ 中有一个关于这个的官方教程。你可以在这里找到它对应的Python 代码。

于 2012-06-22T20:52:16.310 回答
3

您可以使用简单的相关性指标。

  • 确保您计算的直方图和您的参考是标准化的(即表示概率)

  • 对于每个直方图计算(假设 myRef 和 myHist 是 numpy 数组):

    metric = (myRef * myHist).sum()

  • 该指标衡量直方图与您的参考值的相似程度。

于 2012-06-22T16:29:46.390 回答