当前位置: 首页> 教育> 高考 > 百度seo快速_泰安房产价格最新_网络推广的方式和途径有哪些_网站seo价格

百度seo快速_泰安房产价格最新_网络推广的方式和途径有哪些_网站seo价格

时间:2025/7/10 3:22:29来源:https://blog.csdn.net/yuxing55555/article/details/143303033 浏览次数:0次
百度seo快速_泰安房产价格最新_网络推广的方式和途径有哪些_网站seo价格

文章目录

  • OpenCV 中的直方图
  • 直方图 - 1:查找、绘制、分析
    • 目标
    • 理论
    • 查找直方图
      • 1. OpenCV 中的直方图计算
      • 2. Numpy 中的直方图计算
    • 绘制直方图
      • 1. 使用 Matplotlib
      • 2. 使用 OpenCV
    • 掩码的应用
    • 其他资源
  • 直方图 - 2:直方图均衡化
    • 目标
    • 理论
    • OpenCV 中的直方图均衡
    • CLAHE(对比度限制自适应直方图均衡)
    • 其他资源
  • 直方图 - 3:2D 直方图
    • 目标
    • 简介
    • OpenCV 中的 2D 直方图
    • Numpy 中的 2D 直方图
    • 绘制 2D 直方图
      • 方法 - 1:使用 cv.imshow()
      • 方法 - 2:使用 Matplotlib
      • 方法 - 3:OpenCV 示例样式!!
  • 直方图 - 4:直方图反向投影
    • 目标
    • 理论
    • Numpy 中的算法
    • OpenCV 中的反向投影
    • 附加资源

OpenCV 中的直方图

  • @subpage tutorial_py_histogram_begins

了解直方图的基础知识

  • @subpage tutorial_py_histogram_equalization

学习均衡直方图以获得更好的图像对比度

  • @subpage tutorial_py_2d_histogram

学习查找和绘制 2D 直方图

  • @subpage tutorial_py_histogram_backprojection

学习直方图反向投影以分割彩色对象

直方图 - 1:查找、绘制、分析

目标

学习

  • 使用 OpenCV 和 Numpy 函数查找直方图
  • 使用 OpenCV 和 Matplotlib 函数绘制直方图
  • 您将看到这些函数:cv.calcHist()np.histogram() 等。

理论

那么什么是直方图?您可以将直方图视为图形或绘图,它可以让您对图像的强度分布有一个整体的了解。它是一个绘图,X 轴上有像素值(范围从 0 到 255,并非总是如此),Y 轴上有图像中相应的像素数。

这只是理解图像的另一种方式。通过查看图像的直方图,您可以直观地了解该图像的对比度、亮度、强度分布等。如今,几乎所有图像处理工具都提供直方图功能。下面是来自 Cambridge in Color 网站 的图像,我建议您访问该网站了解更多详细信息。

在这里插入图片描述

您可以看到图像及其直方图。(请记住,此直方图是为灰度图像绘制的,而不是彩色图像)。直方图的左侧区域显示图像中较暗像素的数量,右侧区域显示较亮像素的数量。从直方图中,您可以看到暗区比亮区多,中间色调(中间范围内的像素值,例如 127 左右)的数量非常少。

查找直方图

现在我们对直方图有了一定了解,我们可以研究如何找到它。OpenCV 和 Numpy都带有内置函数。在使用这些函数之前,我们需要了解一些与直方图相关的术语。

BINS:上面的直方图显示每个像素值的像素数,即从 0 到 255。即您需要 256 个值来显示上面的直方图。但是请考虑一下,如果您不需要单独查找所有像素值的像素数,而是需要查找像素值间隔内的像素数,该怎么办?例如,您需要查找介于 0 到 15、16 到 31、…、240 到 255 之间的像素数。您只需要 16 个值来表示直方图。这就是 @ref tutorial_histogram_calculation“OpenCV 直方图教程”中给出的示例所示。因此,您要做的只是将整个直方图拆分为 16 个子部分,每个子部分的值是其中所有像素数的总和。每个子部分称为“BIN”。在第一种情况下,bin 数为 256(每个像素一个),而在第二种情况下,只有 16 个。BINS 在 OpenCV 文档中用术语 histSize 表示。

DIMS :这是我们收集数据的参数数量。在这种情况下,我们只收集一项数据,即强度值。所以这里是 1。

RANGE :这是您要测量的强度值的范围。通常,它是 [0,256],即所有强度值。

1. OpenCV 中的直方图计算

现在我们使用 cv.calcHist() 函数来查找直方图。让我们熟悉一下该函数及其参数:

cv.calcHist(images, channels, mask, histSize, ranges[, hist[, accumulate]])

  • images :它是 uint8 或 float32 类型的源图像。它应该放在方括号中,即“[img]”。
  • channels :它也放在方括号中。它是我们为其计算直方图的通道的索引。例如,如果输入是灰度图像,则其值为 [0]。对于彩色图像,您可以传递 [0]、[1] 或 [2] 来分别计算蓝色、绿色或红色通道的直方图。
  • mask :掩码图像。要查找完整图像的直方图,它被指定为“无”。但是,如果您想要找到图像特定区域的直方图,则必须为其创建一个掩码图像并将其作为掩码。(稍后我将展示一个例子。)
  • histSize:这表示我们的 BIN 计数。需要在方括号中给出。对于全尺寸,我们传递 [256]。
  • ranges:这是我们的范围。通常,它是 [0,256]。

让我们从示例图像开始。只需以灰度模式加载图像并找到其完整直方图。

img = cv.imread('home.jpg',0)
hist = cv.calcHist([img],[0],None,[256],[0,256])

hist 是一个 256x1 数组,每个值对应于该图像中的像素数及其对应的像素值。

2. Numpy 中的直方图计算

Numpy 还为您提供了一个函数 np.histogram()。因此,除了 calcHist() 函数,您还可以尝试以下代码:

hist,bins = np.histogram(img.ravel(),256,[0,256])

hist 与我们之前计算的相同。但是 bins 将有 257 个元素,因为 Numpy 将 bins 计算为 0-0.99、1-1.99、2-2.99 等。因此最终范围将是 255-255.99。为了表示这一点,他们还在 bins 末尾添加了 256。但我们不需要 256。最多 255 就足够了。

@note Numpy 还有另一个函数 np.bincount(),它比 np.histogram() 快得多(大约 10 倍)。因此对于一维直方图,您最好尝试一下。不要忘记在 np.bincount 中设置 minlength = 256。例如,hist = np.bincount(img.ravel(),minlength=256)

@note OpenCV 函数比 np.histogram() 快(大约 40 倍)。因此,请继续使用 OpenCV函数。

现在我们应该绘制直方图,但如何绘制呢?

绘制直方图

有两种方法,

  • 捷径方式:使用 Matplotlib 绘图函数
  • 一般方式:使用 OpenCV 绘图函数

1. 使用 Matplotlib

Matplotlib 附带一个直方图绘图函数:matplotlib.pyplot.hist()

它直接查找直方图并绘制它。您无需使用 calcHist() 或 np.histogram() 函数来查找直方图。请参阅以下代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread('home.jpg',0)
plt.hist(img.ravel(),256,[0,256]); plt.show()

您将获得如下图所示的图表:

在这里插入图片描述

或者您可以使用 matplotlib 的普通图,这对于 BGR 图来说很合适。为此,您需要先找到直方图数据。尝试以下代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread('home.jpg')
color = ('b','g','r')
for i,col in enumerate(color):histr = cv.calcHist([img],[i],None,[256],[0,256])plt.plot(histr,color = col)plt.xlim([0,256])
plt.show()

结果:

在这里插入图片描述

您可以从上图中推断出,蓝色在图像中有一些高值区域(显然应该是天空造成的)

2. 使用 OpenCV

好吧,在这里您可以调整直方图的值及其 bin 值,使其看起来像 x,y 坐标,以便您可以使用 cv.line() 或 cv.polyline() 函数绘制它以生成与上图相同的图像。这在 OpenCV-Python2 官方示例中已经可用。查看 samples/python/hist.py 上的代码。

掩码的应用

我们使用 cv.calcHist() 来查找整个图像的直方图。如果您想查找图像某些区域的直方图怎么办?只需创建一个掩码图像,在要查找直方图的区域上使用白色,否则使用黑色。然后将其作为掩码传递。

img = cv.imread('home.jpg',0)# create a mask
mask = np.zeros(img.shape[:2], np.uint8)
mask[100:300, 100:400] = 255
masked_img = cv.bitwise_and(img,img,mask = mask)# Calculate histogram with mask and without mask
# Check third argument for mask
hist_full = cv.calcHist([img],[0],None,[256],[0,256])
hist_mask = cv.calcHist([img],[0],mask,[256],[0,256])plt.subplot(221), plt.imshow(img, 'gray')
plt.subplot(222), plt.imshow(mask,'gray')
plt.subplot(223), plt.imshow(masked_img, 'gray')
plt.subplot(224), plt.plot(hist_full), plt.plot(hist_mask)
plt.xlim([0,256])plt.show()

查看结果。在直方图中,蓝线显示整个图像的直方图,而绿线显示掩蔽区域的直方图。

在这里插入图片描述

其他资源

  • Cambridge in Color 网站

直方图 - 2:直方图均衡化

目标

在本节中,

  • 我们将学习直方图均衡化的概念并使用它来改善图像的对比度。

理论

考虑一个像素值仅限于某个特定值范围的图像。例如,更亮的图像会将所有像素限制在高值。但好图像将具有来自图像所有区域的像素。因此,您需要将此直方图拉伸到任一端(如下图所示,来自维基百科),这就是直方图均衡化所做的(简单来说)。这通常会改善图像的对比度。

在这里插入图片描述

我建议你阅读维基百科上关于直方图均衡化的更多详细信息。它有非常好的解释和示例,所以你读完后几乎可以理解所有内容。相反,在这里我们将看到它的 Numpy 实现。之后,我们将看到 OpenCV 函数。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread('wiki.jpg',0)hist,bins = np.histogram(img.flatten(),256,[0,256])cdf = hist.cumsum()
cdf_normalized = cdf * float(hist.max()) / cdf.max()plt.plot(cdf_normalized, color = 'b')
plt.hist(img.flatten(),256,[0,256], color = 'r')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
plt.show()

在这里插入图片描述

您可以看到直方图位于较亮的区域。我们需要全光谱。为此,我们需要一个转换函数,将较亮区域中的输入像素映射到全区域中的输出像素。这就是直方图均衡化的作用。

现在我们找到最小直方图值(不包括 0)并应用 wiki 页面中给出的直方图均衡方程。但我在这里使用了 Numpy 中的掩码数组概念数组。对于掩码数组,所有操作都在非掩码元素上执行。您可以从Numpy 文档的掩码数组中相关信息。

cdf_m = np.ma.masked_equal(cdf,0)
cdf_m = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_m,0).astype('uint8')

现在我们有了查找表,它为我们提供了每个输入像素值的输出像素值的信息。所以我们只需应用变换即可。

img2 = cdf[img]

现在我们像以前一样计算它的直方图和 cdf(你这样做)并且结果如下所示:

在这里插入图片描述

另一个重要特征是,即使图像是较暗的图像(而不是我们使用的较亮的图像),均衡后我们也会得到几乎相同的图像。因此,这被用作“参考工具”,以使所有图像具有相同的光照条件。这在许多情况下都很有用。例如,在人脸识别中,在训练人脸数据之前,对人脸图像进行直方图均衡,使它们都具有相同的光照条件。

OpenCV 中的直方图均衡

OpenCV 有一个函数可以做到这一点,cv.equalizeHist()。它的输入只是灰度图像,输出是我们的直方图均衡图像。

下面是一个简单的代码片段,展示了它对我们使用的相同图像的用法:

img = cv.imread('wiki.jpg',0)
equ = cv.equalizeHist(img)
res = np.hstack((img,equ)) #stacking images side-by-side
cv.imwrite('res.png',res)

在这里插入图片描述

因此,现在您可以拍摄不同光线条件下的不同图像,对其进行均衡并检查结果。

当图像的直方图局限于特定区域时,直方图均衡效果很好。当直方图覆盖大面积强度变化的地方,即同时存在亮像素和暗像素时,直方图均衡效果不佳。请查看其他资源中的 SOF 链接。

CLAHE(对比度限制自适应直方图均衡)

我们刚刚看到的第一个直方图均衡考虑了图像的全局对比度。在许多情况下,这不是一个好主意。例如,下图显示了输入图像及其全局直方图均衡后的结果。

在这里插入图片描述

直方图均衡化后,背景对比度确实有所改善。但比较一下两幅图像中的雕像面部。由于亮度过高,我们丢失了大部分信息。这是因为它的直方图并不局限于我们在前面的案例中看到的特定区域(尝试绘制输入图像的直方图,您将获得更多直观感受)。

因此,为了解决这个问题,使用了自适应直方图均衡化。在此,图像被分成称为“图块”的小块(OpenCV 中默认的图块大小为 8x8)。然后,每个块都像往常一样进行直方图均衡化。因此,在小区域中,直方图将局限于小区域(除非有噪音)。如果有噪音,它将被放大。为了避免这种情况,应用了对比度限制。如果任何直方图箱高于指定的对比度限制(OpenCV 中的默认值为 40),则在应用直方图均衡化之前,这些像素将被剪切并均匀分布到其他箱中。均衡化后,为了消除图块边界中的伪影,将应用双线性插值。

以下代码片段显示了如何在 OpenCV 中应用 CLAHE:

import numpy as np
import cv2 as cvimg = cv.imread('tsukuba_l.png',0)# create a CLAHE object (Arguments are optional).
clahe = cv.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
cl1 = clahe.apply(img)cv.imwrite('clahe_2.jpg',cl1)

参见下面的结果并将其与上面的结果进行比较,特别是雕像区域:

在这里插入图片描述

其他资源

  1. Wikipedia 页面关于 直方图均衡化

  2. Numpy 中的掩码数组

另请查看这些有关对比度调整的 SOF 问题:

  1. 如何在 C 语言中调整 OpenCV 中的对比度?

  2. 如何使用 opencv 均衡图像的对比度和亮度?

直方图 - 3:2D 直方图

目标

在本章中,我们将学习查找和绘制 2D 直方图。这将对后续章节有所帮助。

简介

在第一篇文章中,我们计算并绘制了一维直方图。之所以称为一维,是因​​为我们只考虑一个特征,即像素的灰度强度值。但在二维直方图中,您要考虑两个特征。通常,它用于查找颜色直方图,其中两个特征是每个像素的色调和饱和度值。

已经有一个用于查找颜色直方图的 Python 示例 (samples/python/color_histogram.py)。我们将尝试了解如何创建这样的颜色直方图,这将有助于理解直方图反投影等其他主题。

OpenCV 中的 2D 直方图

它非常简单,使用相同的函数 cv.calcHist() 进行计算。对于颜色直方图,我们需要将图像从 BGR 转换为 HSV。(请记住,对于 1D 直方图,我们从 BGR 转换为灰度)。对于 2D 直方图,其参数将进行如下修改:

  • channels = [0,1] 因为我们需要处理 H 平面和 S 平面。
  • bins = [180,256] H 平面为 180,S 平面为 256。
  • range = [0,180,0,256] 色调值介于 0 和 180 之间,饱和度介于 0 和
    256 之间。

现在检查下面的代码:

import numpy as np
import cv2 as cvimg = cv.imread('home.jpg')
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)hist = cv.calcHist([hsv], [0, 1], None, [180, 256], [0, 180, 0, 256])

就是这样。

Numpy 中的 2D 直方图

Numpy 还为此提供了一个特定函数:np.histogram2d()。(请记住,对于 1D 直方图我们使用了 np.histogram())。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread('home.jpg')
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)hist, xbins, ybins = np.histogram2d(h.ravel(),s.ravel(),[180,256],[[0,180],[0,256]])

第一个参数是 H 平面,第二个参数是 S 平面,第三个参数是每个 bin 的数量,第四个参数是它们的范围。

现在我们可以检查如何绘制此颜色直方图。

绘制 2D 直方图

方法 - 1:使用 cv.imshow()

我们得到的结果是一个大小为 180x256 的二维数组。因此,我们可以像平常一样使用 cv.imshow() 函数显示它们。它将是一张灰度图像,除非您知道不同颜色的色调值,否则它不会给出太多颜色的概念。

方法 - 2:使用 Matplotlib

我们可以使用 matplotlib.pyplot.imshow() 函数绘制具有不同颜色图的 2D 直方图。它让我们对不同的像素密度有了更好的了解。但这也不能让我们第一眼就知道那里是什么颜色,除非您知道不同颜色的色调值。不过我还是喜欢这种方法。它简单而且更好。

@note 使用此函数时,请记住,插值标志应最接近以获得更好的结果。

考虑代码:

import numpy as np
import cv2 as cv
from matplotlib import pyplot as pltimg = cv.imread('home.jpg')
hsv = cv.cvtColor(img,cv.COLOR_BGR2HSV)
hist = cv.calcHist( [hsv], [0, 1], None, [180, 256], [0, 180, 0, 256] )plt.imshow(hist,interpolation = 'nearest')
plt.show()

下面是输入图像及其颜色直方图。X 轴表示 S 值,Y 轴表示色调。

在这里插入图片描述

在直方图中,您可以在 H = 100 和 S = 200 附近看到一些高值。它对应于天空的蓝色。同样,在 H = 25 和 S = 100 附近可以看到另一个峰值。它对应于宫殿的黄色。您可以使用任何图像编辑工具(如 GIMP)进行验证。

方法 - 3:OpenCV 示例样式!!

OpenCV-Python2 示例中有一个颜色直方图的示例代码(samples/python/color_histogram.py)。
如果运行代码,您可以看到直方图也显示了相应的颜色。或者简单地输出一个颜色编码的直方图。
其结果非常好(尽管您需要添加额外的线条)。

在该代码中,作者在 HSV 中创建了一个颜色图。然后将其转换为 BGR。将生成的直方图图像与此颜色图相乘。他还使用了一些预处理步骤来删除小的孤立像素,从而得到一个好的直方图。我把运行代码、分析代码并进行自己的修改留给读者。以下是该代码针对与上图相同的图像的输出:

在这里插入图片描述

您可以在直方图中清楚地看到存在哪些颜色,蓝色在那里,黄色在那里,还有一些棋盘上的白色。很好!!!

直方图 - 4:直方图反向投影

目标

在本章中,我们将学习直方图反向投影。

理论

它是由 Michael J. Swain 和 Dana H. Ballard 在他们的论文 通过颜色直方图建立索引 中提出的。

简单来说,它到底是什么? 它用于图像分割或在图像中查找感兴趣的对象。简单来说,它会创建一个与输入图像大小相同(但单通道)的图像,其中每个像素对应于该像素属于我们对象的概率。更简单地说,输出图像中我们感兴趣的对象与其余部分相比,会更白。嗯,这是一个直观的解释。 (我无法让它更简单)。直方图反向投影与 camshift 算法等一起使用。

我们怎么做? 我们创建一个包含我们感兴趣的对象(在我们的例子中是地面、离开的玩家和其他东西)的图像的直方图。为了获得更好的结果,对象应该尽可能地填充图像。颜色直方图比灰度直方图更受欢迎,因为对象的颜色比其灰度强度更能定义对象。然后,我们将这个直方图“反向投影”到我们需要找到对象的测试图像上,换句话说,我们计算每个像素属于地面的概率并显示它。在适当的阈值下,结果输出只给我们地面。

Numpy 中的算法

    1. 首先,我们需要计算我们需要找到的对象(让它为“M”)和我们要搜索的图像(让它为“I”)的颜色直方图。
import numpy as np
import cv2 as cvfrom matplotlib import pyplot as plt#roi is the object or region of object we need to find
roi = cv.imread('rose_red.png')
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)#target is the image we search in
target = cv.imread('rose.png')
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)# Find the histograms using calcHist. Can be done with np.histogram2d also
M = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )
I = cv.calcHist([hsvt],[0, 1], None, [180, 256], [0, 180, 0, 256] )
    1. 找到比率 R = M I R = \frac{M}{I} R=IM。然后反向投影 R,即使用 R 作为调色板并创建一个新图像
      ,每个像素作为其对应的目标概率。即 B(x,y) = R[h(x,y),s(x,y)] 其中 h 是色调,s 是 (x,y) 处像素的饱和度。之后应用条件 B ( x , y ) = m i n [ B ( x , y ) , 1 ] B(x,y) = min[B(x,y), 1] B(x,y)=min[B(x,y),1]
h,s,v = cv.split(hsvt)
B = R[h.ravel(),s.ravel()]
B = np.minimum(B,1)
B = B.reshape(hsvt.shape[:2])
    1. 现在应用一个圆形盘的卷积, B = D ∗ B B = D \ast B B=DB,其中 D 是圆盘核。
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5))
cv.filter2D(B,-1,disc,B)
B = np.uint8(B)
cv.normalize(B,B,0,255,cv.NORM_MINMAX)
    1. 现在,最大强度的位置就是物体的位置。如果我们要查找图像中的某个区域,则对合适的值进行阈值化可以得到不错的结果。
ret,thresh = cv.threshold(B,50,255,0)

就是这样!!

OpenCV 中的反向投影

OpenCV 提供了一个内置函数 cv.calcBackProject()。它的参数与 cv.calcHist() 函数几乎相同。它的一个参数是直方图,即对象的直方图,我们必须找到它。此外,在传递给backproject 函数之前,应该对对象直方图进行归一化。它返回概率图像。然后我们用圆盘核对图像进行卷积并应用阈值。以下是我的代码和输出:

import numpy as np
import cv2 as cvroi = cv.imread('rose_red.png')
hsv = cv.cvtColor(roi,cv.COLOR_BGR2HSV)target = cv.imread('rose.png')
hsvt = cv.cvtColor(target,cv.COLOR_BGR2HSV)# calculating object histogram
roihist = cv.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )# normalize histogram and apply backprojection
cv.normalize(roihist,roihist,0,255,cv.NORM_MINMAX)
dst = cv.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)# Now convolute with circular disc
disc = cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5))
cv.filter2D(dst,-1,disc,dst)# threshold and binary AND
ret,thresh = cv.threshold(dst,50,255,0)
thresh = cv.merge((thresh,thresh,thresh))
res = cv.bitwise_and(target,thresh)res = np.vstack((target,thresh,res))
cv.imwrite('res.jpg',res)

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

在这里插入图片描述

附加资源

  • “通过颜色直方图进行索引”,Swain,Michael J.,第三届计算机视觉国际会议,1990 年。
关键字:百度seo快速_泰安房产价格最新_网络推广的方式和途径有哪些_网站seo价格

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: