首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >opencv / python中如何识别特定形状的直方图

opencv / python中如何识别特定形状的直方图
EN

Stack Overflow用户
提问于 2012-06-22 15:38:46
回答 2查看 6.4K关注 0票数 6

我想把图片(从杂志上)分割成文字和图像部分。我的图片中有几个ROIs的直方图。我在python (cv2)中使用opencv。

我想识别出像这样的直方图

tutorial-6.png

因为它是文本区域的典型形状。我怎么能这么做?

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

我把我从ROIs中得到的直方图与我提供的样本直方图进行了比较:

代码语言:javascript
运行
复制
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是图像区域,则输出如下:

  • ROI: 0,compareValue: 1.0
  • ROI: 1,compareValue:-0.000195522081574 <--错误分类
  • ROI: 2,compareValue: 0.0612670248952
  • ROI: 3,compareValue:-0.000517370176887
  • ROI: 4,compareValue: 1.0
  • ROI: 5,compareValue: 1.0

怎样才能避免错误的分类?对于一些图像,误判率约为30%,这是太高的。

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

EN

回答 2

Stack Overflow用户

发布于 2012-06-22 20:52:16

(请参阅结尾处的编辑,以防我误解了问题):

如果您想要绘制直方图,我已经向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

第二种是专门针对灰度图像的,它与问题中的图像相同。

我将展示第二个和它的修改。

考虑完整的图像如下:

如你所示,我们需要画一个直方图。检查以下代码:

代码语言:javascript
运行
复制
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位的图像,白色表示应该用于直方图计算,而黑色表示不应该使用。

因此,我使用了如下所示的面罩(使用油漆创建,您必须为您的目的创建自己的面具)。

我修改了最后一行代码如下:

代码语言:javascript
运行
复制
histogram = hist_lines(img,mask)

现在请看下面的区别:

(请记住,值是标准化的,因此所显示的值不是实际的像素计数,标准化为255。如你所愿改变它。)

编辑:

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

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

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

票数 9
EN

Stack Overflow用户

发布于 2012-06-22 16:29:46

您可以使用一个简单的相关性度量。

  • 确保你计算的直方图和你的参考值是标准化的(表示概率)。
  • 对于每个直方图计算(假定myRef和myHist是numpy数组): metric = (myRef * myHist).sum()
  • 这个度量是衡量直方图看起来有多像你的参考。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11159493

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档