gpt4 book ai didi

opencv - OpenCV 3d直方图是3轴直方图吗?

转载 作者:太空宇宙 更新时间:2023-11-03 22:23:05 27 4
gpt4 key购买 nike

OpenCV的calcHist()返回的3d直方图到底是什么?

对于一维直方图,我知道:
-x轴代表我想要的bin(为简单起见,请说0-255-灰度颜色值)。
-y轴表示具有该bin /颜色值的像素数。

对于3d直方图...我纠正了:
-有3个x轴阵列?每个颜色通道一个(在我的情况下为b,g,r)?
-有3个y轴阵列?以上各一项?

要么

  • 仍然只有1个x和y轴。但是x轴表示b * g * r的级联(?),而y轴告诉我多少个像素的颜色为b * g * r?

  • 如果是第一种情况,OpenCV是否可以:
    -产生一个代表颜色的唯一数字(十六进制?或组合b * g * r)?
    -生成3通道图像的直方图,其中x轴仓代表上方唯一的颜色数,y轴告诉我该颜色有多少像素?
    -假设这比具有255个bin的3d直方图在计算效率上要高得多?

    最佳答案

    OpenCV的calcHist()可以计算任意数量的图像/通道的直方图。返回的直方图的轴数与输入图像中通道的数目相同,并且每个轴的值与为该通道指定的仓数一样多。例如,假设您有一个RGBD图像;也就是说,有四个通道:一个用于红色,蓝色,绿色,另一个用于深度。如果出于任何原因想要计算此类图像的直方图,则OpenCV可让您:

    import cv2
    import numpy as np

    img = cv2.imread('lane.jpg')
    img = np.dstack([img, img[:, :, 0]])
    print('Input image shape:', img.shape)
    n_channels = img.shape[2]
    channels = list(range(n_channels))
    sizes = [8,]*n_channels
    ranges = [0, 255]*n_channels
    hist = cv2.calcHist(img, channels, None, sizes, ranges)
    print('Output histogram shape: ', hist.shape)

    Input image shape: (540, 960, 4)

    Output histogram shape: (8, 8, 8, 8)



    注意,在 np.dstack([img, img[:, :, 0]])行中,我只是将第一个通道添加到图像的末尾,作为第四个通道。您可以修改程序以在通道深度为9的图像上运行,并获得输出9D直方图:
    img = cv2.imread('lane.jpg')
    img = np.dstack([img, img, img])
    print('Input image shape:', img.shape)
    n_channels = img.shape[2]
    channels = list(range(n_channels))
    sizes = [8,]*n_channels
    ranges = [0, 255]*n_channels
    hist = cv2.calcHist(img, channels, None, sizes, ranges)
    print('Output histogram shape: ', hist.shape)

    Input image shape: (540, 960, 9)

    Output histogram shape: (8, 8, 8, 8, 8, 8, 8, 8, 8)



    在这里,唯一的修改还是对 dstack行,在那里我简单地将图像堆叠了3次以创建具有9个通道的图像。

    对于多通道阵列,您会错误地考虑轴。与其将它们称为 xy等,您不应该将它们视为每个通道中的 bins,即 ch1bins, ch2bins, ...等。如果您拍摄单通道图像的直方图,那么请确保;当我绘制它们时, x -axis具有您的容器,而 y -axis具有您的计数,但这只是绘制它们的一种方法。确实,您有一个垃圾箱数组和一个计数数组。如果绘制两通道图像的直方图并使用3D条形图将其可视化,则 x-轴具有bin,但是 y-轴也具有bin,在这种情况下 z轴具有计数。 x轴将具有第一个通道的仓位, y轴将具有第二个通道的仓位。如果您有一个三通道图像,则要在绘图中可视化,所有三个轴都是对应于每个通道的仓,因此您必须用其他方式可视化每个仓中的数量,例如标记的大小该垃圾箱,否则您将不得不根据标记的强度或某些东西为标记着色。

    OpenCV docs for calcHist() 提供了一个2D直方图(即两通道)的示例,您可以在其中分析色相和饱和度值的直方图。这意味着对于给定的色相和饱和度值范围(例如,色相介于0到32之间,饱和度介于144和176之间),您可以看到属于该范围的像素数。

    对于带有3D直方图的示例,您可以 check out some I've plotted。我没有将OpenCV用于直方图,因为...我实际上不知道它可以做3D直方图,直到您问了这个问题。但是 numpy可以像OpenCV一样处理D维直方图。在这些图中,标记的颜色与bin代表的实际颜色相对应,并且标记的大小在某种程度上与每个bin中的值数量相对应。

    如果我拍摄了3D直方图,可以说我们想知道每个通道的深色和浅色计数。因此,我只对每个通道有2个bin的直方图。然后我的垃圾箱将是:
  • channel 0:[0, 127], [128, 255]
  • channel 1:[0, 127], [128, 255]
  • channel 2:[0, 127], [128, 255]

  • 取一个像素值为 [0, 255, 0]的像素。这对应于在通道0的bin 0,通道1的bin 1和通道3的bin 0中。总共有多少种可能性?一个像素可能在垃圾箱中:
  • 0,0,0
  • 0,0,1
  • 0,1,0
  • 0,1,1
  • 1,0,0
  • 1,0,1
  • 1,1,0
  • 1,1,1

  • 因此,有8种可能性。如果我将所有RGB值绘制在3个空间中,则将这些轴中的每一个均分成两个,则将得到8个不同的直方图块。然后,我简单地数出这8个容器中每个容器的数量,这就是直方图。因此,从上面的列表中可以看出,这个简单的直方图将告诉我有多少个暗像素(对应于bin 0、0、0),有多少个亮像素(对应于1,1,1),有多少主要是绿色像素有(0,1,0)等。实际上,这就是OpenCV所提供的:
    img = cv2.imread('lane.jpg')
    print('Input image shape:', img.shape)
    n_channels = img.shape[2]
    channels = list(range(n_channels))
    sizes = [2, 2, 2]
    ranges = [0, 255]*n_channels
    hist = cv2.calcHist(img, channels, None, sizes, ranges)
    print('Output histogram shape: ', hist.shape)

    Input image shape: (540, 960, 3)

    Output histogram shape: (2, 2, 2)



    多通道直方图的重点是要找出每个通道独立地在某个值范围内有多少个像素。希望这篇文章能解决一些问题!

    **注意:请勿使用带有大量通道的小容量存储盒...您会很快用完内存。

    关于opencv - OpenCV 3d直方图是3轴直方图吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46498041/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com