美文网首页
OpenCV-Python教程:26.Histogram 4 H

OpenCV-Python教程:26.Histogram 4 H

作者: xxxss | 来源:发表于2017-06-20 11:33 被阅读307次

    理论

    Michael J. Swain , Dana H. Ballard 发表的Indexing via color histograms

    用来在图片分割或者在图像里找感兴趣的目标,简单说来,它创建了一个和输入图像一样大小的图像,但是是单通道的。输出图像会有我们感兴趣的目标,但是它比其他部分更白。

    我们怎么做呢?我们创建一个图像的histogram,包含我们感兴趣的目标。彩色的histogram比灰度的要好,因为彩色目标更好被定义。然后我们“向后投影”这个histogram到我们的测试图像上,我们计算每个像素的可能性,并显示它。

    Numpy里的算法

    1.首先我们需要计算我们要找的目标(假设叫M)和我们要搜索的图像(假设叫I)的彩色histogram。

    import cv2
    import numpy as np
    from matplotlib import pyplot as plt

    #roi is the object or region of object we need to find
    roi = cv2.imread('rose_red.png')
    hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)

    #target is the image we search in
    target = cv2.imread('rose.png')
    hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)

    # Find the histograms using calcHist. Can be done with np.histogram2d also
    M = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
    I = cv2.calcHist([hsvt],[0, 1], None, [180, 256], [0, 180, 0, 256] )

    2.找到 R = M / I .然后向后投影R, 用R当调色板创建一个新图像,图像的每个像素和它的目标对应的像素点可能性。B(x, y) = R[h(x, y), s(x,y)], h 是色调,s是饱和度,然后B(x, y) = min[B(x, y), 1]

    h, s, v = cv2.split(hsvt)
    B = R[h.ravel(), s.ravel()]
    B = np.minimum(B, 1)
    B = B.reshape(hsvt.shape[:2])

    3.现在用卷积, B = D * B,D是核

    disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
    cv2.filter2D(B,-1,disc,B)
    B=np.uint8(B)
    cv2.normalize(B,B,0,255,cv2.NORM_MINMAX)

    4.现在最大强度的位置告诉我们目标的位置,我们如果想得到图像的一个区域,可以用合适的阈值得到:

    ret,thresh=cv2.threshold(B,50,255,0)

    OpenCV里的向后映射

    OpenCV提供了内置函数cv2.calcBackProject()。它的参数和calcHist()一样,一个参数是histogram,目标的histogram应该标准化,然后再传给向后投影函数。它返回可能性图片。然后我们用disc 核卷积,接着用阈值。

    import cv2
    import numpy as np

    roi = cv2.imread('rose_red.png')
    hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)

    target = cv2.imread('rose.png')
    hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)

    # calculating object histogram
    roihist = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )

    # normalize histogram and apply backprojection
    cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
    dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)

    # Now convolute with circular disc
    disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
    cv2.filter2D(dst,-1,disc,dst)

    # threshold and binary AND
    ret,thresh = cv2.threshold(dst,50,255,0)
    thresh = cv2.merge((thresh,thresh,thresh))
    res = cv2.bitwise_and(target,thresh)

    res = np.vstack((target,thresh,res))
    cv2.imwrite('res.jpg',res)

    下面是一个例子,我使用了蓝色矩形的区域作为样本对象,我想提取整个草皮

    END

    相关文章

      网友评论

          本文标题:OpenCV-Python教程:26.Histogram 4 H

          本文链接:https://www.haomeiwen.com/subject/gbnfsttx.html