【问题标题】:Contours and convex hull in opencv2 for a thresholded 32 uint imageopencv2 中用于阈值化 32 uint 图像的轮廓和凸包
【发布时间】:2015-07-30 04:59:58
【问题描述】:

我有以下代码:

    import cv2
    import numpy as np
    import matplotlib
    import matplotlib.pyplot as plt
    from skimage import data
    from skimage import filter
    from skimage.filter import threshold_otsu

    matplotlib.rcParams['font.size'] = 9

    nomeimg = 'frame1_depth.png'

    i = cv2.imread(nomeimg, -1)
    #conversione da 16 a 32 uint
    img = np.array(i, dtype=np.uint32)
    img *= 65536
    print img.dtype

    #thresholding con il metodo Otsu 
    thresh = threshold_otsu(img)
    binary = img > thresh
    print thresh

    plt.figure(1)
    fig, (ax1, ax2, ax3) = plt.subplots(1, 3, figsize=(8, 2.5))
    ax1.imshow(img)
    ax1.set_title('Original')
    ax1.axis('off')

    ax2.hist(img)
    ax2.set_title('Histogram')
    ax2.axvline(x=thresh, color='r', linestyle='dashed', linewidth=2)

    ax3.imshow(binary, cmap=plt.cm.gray)
    ax3.set_title('Thresholded')
    ax3.axis('off')

    plt.figure(2)
    f, ax = plt.subplots(figsize=(8, 2.5))
    ax.imshow(binary, cmap=plt.cm.gray)
    ax.set_title('Thresholded')
    ax.axis('off')

    plt.show()

我有一组来自 XBOX kinect 的深度图像,因此在进行数据类型转换之后,我可以使用一些仅适用于 8 位或 32 位图像的 opencv 函数,我已使用Otsu算法并展示了结果。

我获得了一个子图,其中有我的原始图像、直方图和阈值黑白图像。现在我只想处理这张黑白图像,我想保存它并计算轮廓、凸包和其他几何特征。但是,它只是阈值,但使用otsu

如何计算?

【问题讨论】:

    标签: python opencv image-processing contour


    【解决方案1】:

    如果您想在 OpenCV 中使用findContours 和其他图像处理分析功能处理您的二进制图像,您只需将binary 转换为uint8。此外,请确保缩放图像以使非零值变为 255。uint32 仅在某些模式下有效,并且为了避免在记住哪些模式允许您执行此操作时出现任何不必要的麻烦,只需坚持uint8

    因此,这样做:

    binary = 255*(binary.astype('uint8'))
    

    完成此转换后,您可以致电findContours

    contours, hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE)
    

    以上只是一种调用方式。我建议您查看文档以了解更多详细信息,我已在上面链接。


    作为另一个例子,如果你想找到你的阈值图像的凸包,它有一堆通过convexHull 的形状,你需要一组代表你的轮廓的点,这正是由 @ 给出的987654334@cv2.findContours 的输出。但是,convexHull 函数假定只有一个 single 对象代表一个轮廓。如果您有多个对象,因此有多个contors,您将不得不遍历每个contours 并存储结果。

    因此,请执行以下操作:

    hull = [cv2.convexHull(cnt) for cnt in contours]
    

    hull 中的每个元素将返回组成每个轮廓的凸包的坐标。因此,要访问轮廓 i 的凸包坐标,您可以:

    points = hull[i]
    

    顺便说一句,这里有几个很好的链接可以帮助您开始使用 OpenCV 的形状分析功能。这是一个关于如何在更一般的上下文中使用 cv2.findContours 的链接:

    http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_contours/py_contours_begin/py_contours_begin.html

    这里是另一个链接,讨论 OpenCV 的其他形状分析功能,例如凸包、图像矩等:

    http://opencv-python-tutroals.readthedocs.org/en/latest/py_tutorials/py_imgproc/py_contours/py_contour_features/py_contour_features.html

    玩得开心!

    【讨论】:

    • 非常感谢你!事实上,在 otsu 之后,我有一个布尔值作为 dtype,现在我再次将 dtype 转换为 32uint。我已经在我的代码中将查找轮廓函数放在 plt.figure(2) 下,因为我想在该图上跟踪轮廓,但在终端中我有这个:uint32 uint32 0 Traceback(最近一次调用最后):文件“ ",第 1 行,在 文件中 "convert.py",第 41 行,在 轮廓中,hierarchy = cv2.findContours(binary,cv2.RETR_LIST,cv2.CHAIN_APPROX_NONE) TypeError: image data type = 6 is not支持是什么意思???我怎么可能是 0 作为 Otsu?
    • @Giulio - 奇怪...尝试转换为 uint8。看起来它不喜欢 uint32 数据类型。
    • @Giulio - 我的错误。它必须是uint8。在某些情况下只能是uint32。我会更新我的帖子。
    • @Giulio - 我解决的问题有帮助吗?
    • 是的!你给我一只大手!即使我没有很好的结果,也许我必须在找到轮廓之前应用一些过滤器......让我有些怀疑的另一件事是 0 作为阈值......它看起来很奇怪,也许这就是事实的原因我没有在直方图上看到我用 axvline 命令调用的红线..??
    猜你喜欢
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 1970-01-01
    • 2020-08-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-08
    相关资源
    最近更新 更多