【问题标题】:How to recognize histograms with a specific shape in opencv / python如何在opencv / python中识别具有特定形状的直方图
【发布时间】:2012-06-24 22:43:42
【问题描述】:

我想在文本和图像部分分割图像(来自杂志)。我的图片中有几个 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
  • ROI:2,比较值:0.0612670248952
  • ROI:3,比较值:-0.000517370176887
  • ROI:4,比较值:1.0
  • 投资回报率:5,比较值:1.0

如何避免分类错误?对于某些图像,错误分类率约为 30%,这太高了。

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

【问题讨论】:

    标签: python opencv histogram


    【解决方案1】:

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

    如果您想绘制直方图,我已经向 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。否则,您必须指定掩码。

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

    所以我使用了如下所示的蒙版(使用绘画创建,您必须根据自己的目的创建自己的蒙版)。

    我把最后一行代码改成如下:

    histogram = hist_lines(img,mask)
    

    现在看看下面的区别:

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

    编辑:

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

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

    有一个关于this in C++的官方教程。你可以找到它对应的Python code here.

    【讨论】:

    • @Abid Rahman K. 面具到底有什么用?我看到了一些功能说明掩码。是否可以设置图像的 ROI?
    • 是的,通常 roi 是矩形区域,但是使用蒙版,您可以采用任何形状。查看我博客中的轮廓部分以获取更多详细信息。 Opencvpython.blogspot.com
    【解决方案2】:

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

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

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

      metric = (myRef * myHist).sum()

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

    【讨论】:

    • 这是一个非常有趣的想法。但是myRef 到底是什么意思?它是另一个直方图还是与myHist 相同大小?还是任意的 numpy 数组?
    • @samkhan13 是的,myRef 是我们要比较的直方图。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-22
    • 1970-01-01
    • 2019-01-07
    • 2017-03-08
    • 2019-07-13
    相关资源
    最近更新 更多