2021-09-23 opencv学习笔记(图像变换,二值化,滤波器介绍及python实现)

2023-11-11

在这里插入图片描述

颜色空间

改变颜色空间(cv2.cvtColor())

在 OpenCV 中有超过 150 种颜色空间转换的方法。但我们仅需要研究两个最常使用的方法,他们是 BGR 到 GRAY,BGR 到 HSV。

我们使用 cv.cvtColor(input_image, flag)函数进行颜色转换,其中 flag 决定了转换的类型。

对于 BGR 到 Gray 转换我们令 flag 为 cv2.COLOR_BGR2GRAY。 同样,对于 BGR 到 HSV, 我们令 flag 为 cv2.COLOR_BGR2HSV

代码:

import cv2

BGR = cv2.imread("C:/Users/Zhang-Lei/Desktop/snack.png")
GRAY = cv2.cvtColor(BGR, cv2.COLOR_BGR2GRAY)
HSV = cv2.cvtColor(BGR, cv2.COLOR_BGR2HSV)

cv2.imshow('BGR', BGR)
cv2.imshow('GRAY', GRAY)
cv2.imshow('HSV', HSV)
cv2.resizeWindow('BGR', 500, 800)
cv2.resizeWindow('GRAY', 500, 800)
cv2.resizeWindow('HSV', 500, 800)
cv2.waitKey()
cv2.destroyAllWindows()

结果:
在这里插入图片描述
如想得到其他 flag 值,我们只需要输入代码查看:

代码:

flags = [i for i in dir(cv2) if i.startswith('COLOR_')]
print(flags)

种类过多,这里就不展示结果了。

注意: 对于 HSV, 色调(Hue)范围为 [0,179], 饱和度(Saturation)范围为 [0,255] ,明亮度(Value)为 [0,255]. 不同的软件使用不同的比例. 所以如果你想用 OpenCV 的值与别的软件的值作对比,你需要归一化这些范围。

目标追踪

现在我们知道了如何将 BGR 图片转化为 HSV 图片,我们可以使用它去提取彩色对象。HSV 比 BGR 在颜色空间上更容易表示颜色。在我们的应用中,我们会尝试提取一个蓝色的彩色对象,方法为:

  1. 提取每一视频帧。
  2. 将 BGR 转化为 HSV 颜色空间。
  3. 我们用蓝色像素的范围对该 HSV 图片做阈值。
  4. 现在提取出了蓝色对象,我们可以随意处理图片了 。

代码:

import cv2
import numpy as np

cap = cv2.VideoCapture(0)  # 读取摄像头影像
while 1:
    _, frame = cap.read()
    hsv = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)  # 转为HSV图
    lower_blue = np.array([110, 50, 50])  # 限定蓝色范围下限
    upper_blue = np.array([130, 255, 255])  # 限定蓝色范围上限
    mask = cv2.inRange(hsv, lower_blue, upper_blue)  # 限定HSV图像范围
    res = cv2.bitwise_and(frame, frame, mask=mask)  # 按位与
    cv2.imshow('frame', frame)
    cv2.imshow('mask', mask)
    cv2.imshow('res', res)
    k = cv2.waitKey(5) & 0xFF  # 检测是否按下Esc 引用&0xff,
    # 正是为了只取按键对应的ASCII值后8位来排除不同按键的干扰进行判断按键是什么。
    if k == 27:
        break
cv2.destroyAllWindows()

结果:
在这里插入图片描述

可以看到这本书的蓝色对象被我们提取了出来。

如何查找某个颜色的HSV值

你可以使用相同的函数:cv2.cvtColor()。 不需要输入图片,你只需要输入你需要的 BGR 值即可. 例如, 为了找到绿色的 HSV 值,

代码:

green = np.uint8([[[0, 255, 0]]])
hsv_green = cv2.cvtColor(green, cv2.COLOR_BGR2HSV)
print(hsv_green)

结果:
在这里插入图片描述

图形变换

缩放(cv2.resize())

缩放是调整图片的大小。 OpenCV 使用 cv2.resize() 函数进行调整。可以手动指定图像的大小,也可以指定比例因子。可以使用不同的插值方法。对于下采样(图像上缩小),最合适的插值方法是 cv2.INTER_AREA 对于上采样(放大),最好的方法是 cv2.INTER_CUBIC (速度较慢)和 cv2.INTER_LINEAR (速度较快)。默认情况下,所使用的插值方法都是 cv2.INTER_AREA 。你可以使用如下方法调整输入图片大小:

代码:

import cv2

img = cv2.imread("C:/Users/Zhang-Lei/Desktop/snack.png")
res1 = cv2.resize(img, None, fx=1/2, fy=1/2, interpolation=cv2.INTER_CUBIC) # fx和fy分别对应横纵轴图像放大倍数

height, width = img.shape[:2]
res2 = cv2.resize(img, (width//2, height//2), interpolation=cv2.INTER_CUBIC)  # 第二种方法

cv2.imshow('img', img)
cv2.imshow('res1', res1)
cv2.imshow('res2', res2)
cv2.waitKey()
cv2.destroyAllWindows()

结果:
在这里插入图片描述

可以看出两种方法都将图片的大小缩小为原来大小的一半。

平移

平移变换是物体位置的移动。如果知道 (x,y) 方向的偏移量,假设为 (t_x,t_y),则可以创建如下转换矩阵 M:
在这里插入图片描述
您可以将变换矩阵存为 np.float32 类型的 numpy 数组,并将其作为 cv.warpAffine 的第二个参数。请参见以下转换(100,50)的示例:

代码:

import cv2
import numpy as np

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/snack_gray.png', cv2.IMREAD_UNCHANGED)
rows, cols = img.shape
M = np.float32([[1, 0, 100], [0, 1, 50]])
res = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img', img)
cv2.imshow('res', res)
cv2.waitKey()
cv2.destroyAllWindows()

结果:
在这里插入图片描述
这里可以看到得到的图像相比于原图像是向右下方平移了的。

注意:cv2.warpAffine 函数的第三个参数是输出图像的大小,其形式应为(宽度、高度)。记住宽度=列数,高度=行数。

旋转

以θ角度旋转图片的转换矩阵形式为:
在这里插入图片描述
但 Opencv 提供了可变旋转中心的比例变换,所以你可以在任意位置旋转图片,修改后的转换矩阵为:
在这里插入图片描述
其中:
在这里插入图片描述
为了找到这个转换矩阵,opencv 提供了一个函数
cv2.getRotationMatrix2D 。
请查看下面的示例,它将图像相对于中心旋转 90 度,而不进行任何缩放。

代码:

import cv2

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/snack_gray.png', cv2.IMREAD_UNCHANGED)
rows, cols = img.shape
M = cv2.getRotationMatrix2D(((cols-1)/2.0, (rows-1)/2.0), 90, 1)
res = cv2.warpAffine(img, M, (cols, rows))
cv2.imshow('img', img)
cv2.imshow('res', res)
cv2.waitKey()
cv2.destroyAllWindows()

结果:
在这里插入图片描述
可见图片已经发生了逆时针90°的旋转。

仿射变换

在仿射变换中,原始图像中的所有平行线在输出图像中仍然是平行的。为了找到变换矩阵,我们需要从输入图像中取三个点及其在输出图像中的对应位置。然后 cv2.getPerspectiveTransform 将创建一个 2x3 矩阵,该矩阵将传递给cv2.warpAffine

代码:

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

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/drawing.png')
rows, cols, ch = img.shape
pts1 = np.float32([[50, 50], [200, 50], [50, 200]])
pts2 = np.float32([[10, 100], [200, 50], [100, 250]])
M = cv2.getAffineTransform(pts1, pts2)
dst = cv2.warpAffine(img, M, (cols, rows))
plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

结果:
在这里插入图片描述

透视变换

对透视转换,你需要一个 3x3 变换矩阵。即使在转换之后,直线也将保持直线。要找到这个变换矩阵,需要输入图像上的 4 个点和输出图像上的相应点。在这四点中,任意三点不应该共线。然后通过 cv2.getPerspectiveTransform 找到变换矩阵。然后对这个 3x3 变换矩阵使用 cv2.warpPerspective

代码:

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

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/sudoku.png')
rows, cols, ch = img.shape
pts1 = np.float32([[56, 65], [368, 52], [28, 387], [389, 390]])
pts2 = np.float32([[0, 0], [300, 0], [0, 300], [300, 300]])
M = cv2.getPerspectiveTransform(pts1, pts2)
dst = cv2.warpPerspective(img, M, (300, 300))
plt.subplot(121), plt.imshow(img), plt.title('Input')
plt.subplot(122), plt.imshow(dst), plt.title('Output')
plt.show()

结果:
在这里插入图片描述

二值化

简单阈值法

此方法是直截了当的。如果像素值大于阈值,则会被赋为一个值(可能为白色),否则会赋为另一个值(可能为黑色)。使用的函数是 cv2.threshold。第一个参数是源图像,它应该是灰度图像。第二个参数是阈值,用于对像素值进行分类。第三个参数是 maxval,它表示像素值大于(有时小于)阈值时要给定的值。opencv 提供了不同类型的阈值,由函数的第四个参数决定。不同的类型有:

  • cv.THRESH_BINARY
  • cv.THRESH_BINARY_INV
  • cv.THRESH_TRUNC
  • cv.THRESH_TOZERO
  • cv.THRESH_TOZERO_INV

获得两个输出。第一个是 retval,稍后将解释。第二个输出是我们的阈值图像。

代码:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/snack_gray.png', cv2.IMREAD_UNCHANGED)
ret1, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
ret2, thresh2 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY_INV)
ret3, thresh3 = cv2.threshold(img, 127, 255, cv2.THRESH_TRUNC)
ret4, thresh4 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO)
ret5, thresh5 = cv2.threshold(img, 127, 255, cv2.THRESH_TOZERO_INV)
titles = ['Original', 'BINARY', 'BINARY_INV', 'TRUNC', 'TOZERO', 'TOZERO_INV']
images = [img, thresh1, thresh2, thresh3, thresh4, thresh5]
for i in range(6):
    plt.subplot(2, 3, i+1)
    plt.imshow(images[i], cmap='gray')
    plt.title(titles[i])
    plt.xticks([])
    plt.yticks([])
plt.show()

结果:
在这里插入图片描述
可以看到,其他五幅图像都以不同的方式区分像素。

自适应阈值

在前一节中,我们使用一个全局变量作为阈值。但在图像在不同区域具有不同照明条件的条件下,这可能不是很好。在这种情况下,我们采用自适应阈值。在此,算法计算图像的一个小区域的阈值。因此,我们得到了同一图像不同区域的不同阈值,对于不同光照下的图像,得到了更好的结果。

它有三个“特殊”输入参数,只有一个输出参数。

  • Adaptive Method :它决定如何计算阈值。

  • cv2.ADAPTIVE_THRESH_MEAN_C :阈值是指邻近地区的平均值。

  • cv2.ADAPTIVE_THRESH_GAUSSIAN_C :阈值是权重为高斯窗的邻域值的加权和。

  • Block Size :它决定了计算阈值的窗口区域的大小。

  • C :它只是一个常数,会从平均值或加权平均值中减去该值。

下面的代码比较了具有不同照明的图像的全局阈值和自适应阈值:

代码:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/snack_gray.png', 0)
img = cv2.medianBlur(img, 5)
ret, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
thresh2 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_MEAN_C,cv2.THRESH_BINARY, 11, 2)
thresh3 = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY, 11, 2)
titles = ['Original Image', 'Global Thresholding (v = 127)',
          'Adaptive Mean Thresholding', 'Adaptive Gaussian Thresholding']
images = [img, thresh1, thresh2, thresh3]
for i in range(4):
    plt.subplot(2, 2, i + 1), plt.imshow(images[i], 'gray')
    plt.title(titles[i])
    plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述

Otsu二值化(俗称大津法)

在第一部分中,有一个参数 retval。当我们进行 Otsu 二值化时,它的用途就来了。那是什么?

在全局阈值化中,我们使用一个任意的阈值,对吗?那么,我们如何知道我们选择的值是好的还是不好的呢?答案是,试错法。但是考虑一个双峰图像(简单来说,双峰图像是一个直方图有两个峰值的图像)。对于那个图像,我们可以近似地取这些峰值中间的一个值作为阈值,对吗?这就是 Otsu 二值化所做的。所以简单来说,它会自动从双峰图像的图像直方图中计算出阈值。(对于非双峰图像,二值化将不准确。)

为此,我们使用了 cv2.threshold 函数,但传递了一个额外的符号 cv2.THRESH_OTSU 。对于阈值,只需传入零。然后,该算法找到最佳阈值,并作为第二个输出返回 retval。如果不使用 otsu 阈值,则 retval 与你使用的阈值相同。

查看下面的示例。输入图像是噪声图像。在第一种情况下,我应用了值为 127 的全局阈值。在第二种情况下,我直接应用 otsu 阈值。在第三种情况下,我使用 5x5 高斯核过滤图像以去除噪声,然后应用 otsu 阈值。查看噪声过滤如何改进结果。

代码:

import cv2
import matplotlib.pyplot as plt

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/noisy.png', 0)
# 全局阈值
ret1, thresh1 = cv2.threshold(img, 127, 255, cv2.THRESH_BINARY)
# Otsu 阈值
ret2, thresh2 = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 经过高斯滤波的 Otsu 阈值
blur = cv2.GaussianBlur(img, (5, 5), 0)
ret3, thresh3 = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
# 画出所有的图像和他们的直方图
images = [img, 0, thresh1, img, 0, thresh2, blur, 0, thresh3]
titles = ['Original Noisy Image', 'Histogram', 'Global Thresholding (v=127)',
          'Original Noisy Image', 'Histogram', "Otsu's Thresholding",
          'Gaussian filtered Image', 'Histogram', "Otsu's Thresholding"]
for i in range(3):
    plt.subplot(3, 3, i * 3 + 1), plt.imshow(images[i * 3], 'gray')
    plt.title(titles[i * 3]), plt.xticks([]), plt.yticks([])
    plt.subplot(3, 3, i * 3 + 2), plt.hist(images[i * 3].ravel(), 256)
    plt.title(titles[i * 3 + 1]), plt.xticks([]), plt.yticks([])
    plt.subplot(3, 3, i * 3 + 3), plt.imshow(images[i * 3 + 2], 'gray')
    plt.title(titles[i * 3 + 2]), plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述

Otsu 二值化原理

本节演示了 otsu 二值化的 python 实现,以展示它的实际工作原理。

由于我们使用的是双峰图像,因此 Otsu 的算法试图找到一个阈值(t),该阈值将由下式计算得到的类内加权方差最小化:

其中:
在这里插入图片描述
它实际上找到一个 T 值,它位于两个峰值之间,使得两个类的方差最小。它可以简单地在 python 中实现,如下所示:

代码:

import cv2
import numpy as np

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/noisy.png', 0)
blur = cv2.GaussianBlur(img, (5, 5), 0)
# 找到归一化直方图还有累计分布函数
hist = cv2.calcHist([blur], [0], None, [256], [0, 256])
hist_norm = hist.ravel() / hist.max()
Q = hist_norm.cumsum()
bins = np.arange(256)
fn_min = np.inf
thresh = -1
for i in range(1, 256):
    p1, p2 = np.hsplit(hist_norm, [i])  # 概率
    q1, q2 = Q[i], Q[255] - Q[i]  # 类别总和
    b1, b2 = np.hsplit(bins, [i])  # 权重
    # f 找到均值与方差
    m1, m2 = np.sum(p1 * b1) / q1, np.sum(p2 * b2) / q2
    v1, v2 = np.sum(((b1 - m1) ** 2) * p1) / q1, np.sum(((b2 - m2) ** 2) * p2) / q2
    # 计算最小函数
    fn = v1 * q1 + v2 * q2
    if fn < fn_min:
        fn_min = fn
        thresh = i
# 用 Opencv2 函数的 otsu'阈值
ret, otsu = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
print("{} {}".format(thresh, ret))

结果:
在这里插入图片描述

滤波

二维卷积(图像滤波)

与一维信号一样,图像也可以通过各种低通滤波器(LPF)、高通滤波器(HPF)等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。

opencv 提供了函数 cv2.filter2D(),用于将内核与图像卷积起来。作为一个例子,我们将尝试对图像进行均值滤波操作。5x5 均值滤波卷积核如下:
在这里插入图片描述
操作如下:将该内核中心与一个像素对齐,然后将该内核下面的所有 25 个像素相加,取其平均值,并用新的平均值替换这个25x25窗口的中心像素。它继续对图像中的所有像素执行此操作。试试下面这段代码并观察结果:

代码:

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

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/noisy.png')
kernel = np.ones((5, 5), np.float32) / 25
dst = cv2.filter2D(img, -1, kernel)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(dst), plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述
可见图像在滤波的作用下变得模糊了。

图像模糊(图像平滑)

图像模糊是通过将图像与低通滤波核卷积来实现的。它有助于消除噪音。它实际上从图像中删除高频内容(例如:噪声、边缘)。所以在这个操作中边缘有点模糊。(好吧,有一些模糊技术不会使边缘太模糊)。OpenCV 主要提供四种模糊技术。

均值滤波

这是通过用一个归一化的滤波器内核与图像卷积来完成的。它只需取内核区域下所有像素的平均值并替换中心元素。这是通过函数 cv2.blur()或 cv2.boxFilter() 完成的。有关内核的更多详细信息,请查看文档。我们应该指定滤波器内核的宽度和高度。3x3 标准化框滤波器如下所示:
在这里插入图片描述
注意 :如果你不用标准化滤波,使用cv2.boxFilter(),传入 normalize=False 参数。

5x5 核的简单应用如下所示:

import cv2
from matplotlib import pyplot as plt

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/opencv.jpg')
blur = cv2.blur(img, (5, 5))
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(blur), plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述

高斯滤波

在这种情况下,使用高斯核代替了核滤波器。它是通过函数 **cv2.GaussianBlur()**完成的。我们应该指定内核的宽度和高度,它应该是正数并且是奇数(奇数才有一个中位数)。我们还应该分别指定 x 和 y 方向的标准偏差、sigmax 和 sigmay。如果只指定 sigmax,则 sigmay 与 sigmax 相同。如果这两个值都是 0,那么它们是根据内核大小计算出来的。高斯模糊是消除图像高斯噪声的有效方法。

如果需要,可以使用函数 cv.getGaussianKernel() 创建高斯内核。

上述代码可以修改为高斯滤波器:

blur = cv2.GaussianBlur(img,(5,5),0)

代码:

import cv2
from matplotlib import pyplot as plt

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/opencv.jpg')
blur = cv2.GaussianBlur(img, (5, 5), 0)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(blur), plt.title('GaussianBlurred')
plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述

中值滤波

在这里,函数 cv2.medianBlur() 取内核区域下所有像素的中值,将中央元素替换为该中值。这对图像中的椒盐噪声非常有效。有趣的是,在上面的过滤器中,中心元素是一个新计算的值,它可能是图像中的像素值,也可能是一个新值。但在中值模糊中,中心元素总是被图像中的一些像素值所取代,可以有效降低噪音。它的内核大小应该是一个正的奇数整数。

在这个演示中,我在原始图像中添加了 5000个椒盐噪声,并应用了中间模糊。只需要将上面代码改为中值滤波器:

median = cv2.medianBlur(img,5)

代码:

import random
import cv2
from matplotlib import pyplot as plt


# 添加椒盐噪声
def noise(dst):
    height, width = dst.shape[:2]
    for _ in range(height*width//4):
        x = random.randint(0, height-1)
        y = random.randint(0, width-1)
        dst[x, y] = 255  # 添加盐噪声
        p = random.randint(0, height-1)
        q = random.randint(0, width-1)
        dst[p, q] = 0  # 添加椒噪声


img = cv2.imread('C:/Users/Zhang-Lei/Desktop/snack_gray.png', 0)
plt.subplot(131), plt.imshow(img, cmap='gray'), plt.title('Original')
plt.xticks([]), plt.yticks([])
noise(img)
plt.subplot(132), plt.imshow(img, cmap='gray'), plt.title('Noise')
plt.xticks([]), plt.yticks([])
median = cv2.medianBlur(img, 5)
plt.subplot(133), plt.imshow(median, cmap='gray'), plt.title('MedianBlurred')
plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述

可以看到,第二张照片是在原图的基础上添加了噪声,第三张图片虽然去除了噪声,但仍然会有部分模糊。

双边滤波

cv2.bilateralFilter() 在保持边缘锐利的同时,对噪声去除非常有效。但与其他过滤器相比,操作速度较慢。我们已经看到高斯滤波器取像素周围的邻域并找到其高斯加权平均值。该高斯滤波器是一个空间函数,即在滤波时考虑相邻像素。但是它不考虑像素是否具有几乎相同的强度,也不考虑像素是否是边缘像素。所以它也会模糊边缘,这是我们不想做的。

双边滤波器在空间上也采用高斯滤波器,而另一个高斯滤波器则是像素差的函数。空间的高斯函数确保模糊只考虑邻近像素,而强度差的高斯函数确保模糊只考虑与中心像素强度相似的像素。所以它保留了边缘,因为边缘的像素会有很大的强度变化。

下面的示例显示使用双边滤波,同样的,只需要将上面代码改为双边滤波器:

blur = cv2.bilateralFilter(img,9,75,75)

代码:

import cv2
from matplotlib import pyplot as plt

img = cv2.imread('C:/Users/Zhang-Lei/Desktop/snack_gray.png', 0)
plt.subplot(121), plt.imshow(img, cmap='gray'), plt.title('Original')
plt.xticks([]), plt.yticks([])
blur = cv2.bilateralFilter(img, 9, 75, 75)
plt.subplot(122), plt.imshow(blur, cmap='gray'), plt.title('BilateralBlurred')
plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述

可见图像经过双边滤波变得模糊了一些。
在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

2021-09-23 opencv学习笔记(图像变换,二值化,滤波器介绍及python实现) 的相关文章

  • 使用 os.popen 在 python 中创建列表

    以前 我已经能够使用类似于以下内容的命令创建列表 os popen ls fits gt samplelist 现在 我尝试通过按编号将文件分组来将文件组织到列表中 这些文件的命名如下 Name 0000 J fits Name 0001
  • 如何使用 .ui 文件创建小部件?

    我想在 MainWindow 内创建一个小部件 该小部件从使用 QtDesigner 创建的文件中获取其设计 我创建的 ui 文件是test ui 我有一个继承自的 MainWindow 实例QMainWindow这将创建一个堆叠小部件里面
  • Python 中的“断言”有什么用?

    什么是assert意思是 它是如何使用的 The assert语句几乎存在于所有编程语言中 它有两个主要用途 它有助于在程序早期发现问题 原因明确 而不是等到其他操作失败时才发现问题 例如 Python 中的类型错误在实际引发错误之前可能会
  • df.drop(如果存在)

    下面是一个函数 它接受一个文件并删除列名row num start date end date 问题是并非每个文件都有这些列名 因此该函数返回错误 我的目标是更改代码 以便删除这些列 如果存在 但如果某个列不存在则不会返回错误 def re
  • ValueError:展开时包装器循环

    我的示例代码中的 Python3 测试用例 文档测试 失败 但在 Python2 中同样可以正常工作 test py class Test object def init self a 0 self a a def getattr self
  • 找不到文件 setuptools-27.2.0-py3.5.egg

    这个问题适用于Python 3 5 2 在Windows 10 64位 上使用Anaconda 4 3 0 当我尝试使用 pip 安装软件包时 出现以下错误 Command python setup py egg info failed w
  • 从 colab 中的驱动器中的 python 脚本导入 python 模块

    我目前正在 Google Colab 上开展一个使用 Tensorflow API 的机器学习项目 我创建了一个文件夹并将其上传到谷歌驱动器上以在谷歌Colab上运行 我成功安装了谷歌驱动器并可以运行脚本 但是当我尝试从同一文件夹中的脚本导
  • Django 星级评定系统和 AJAX

    我正在尝试在 Django 网站上实现星级评级系统 在我的模型中存储评级是排序的 就像在页面上显示分数一样 但我希望用户能够对页面进行评分 基本上从 1 到 5 而无需刷新或更改页面 我发现了以下内容 并且喜欢这里明星的风格 http jv
  • 来自 ANTLR 解析树的 Python AST?

    我找到了一个ANTLR4 Python3 语法 https github com bkiers python3 parser 但它会生成一个解析树 该树通常有许多无用的节点 我正在寻找一个已知的包来从该解析树获取 Python AST 这样
  • manage.pysyncdb 不会为某些模型添加表

    今天我的第二个不太熟练的问题 我有一个 django 项目 其中安装了四个应用程序 当我运行manage py syndb时 它只为其中两个创建表 据我所知 我的任何模型文件都没有问题 并且所有应用程序都在我的设置文件中的 INSTALLE
  • 基本的 Python OpenCV 裁剪和调整大小

    有人可以帮我一些裁剪算法吗 它的 openCV 我想弄清楚这一点 我知道方法是crop image y y1 x x1 如果我有一个带有 new dimensionXxnew dimensionY 像素的图像 并且我想将其裁剪为相同的宽度
  • 如何为 PyDev 制作文件模板?

    我希望在我创建的每个新文件的顶部都有一些有关许可证 作者等的样板信息 但我找不到要勾选的正确框 基本上 我想创建一个新文件 并已将其填充 在顶部 author Me license something copyright something
  • opencv如何使用鼠标事件不规则地选择图像区域? c/c++ [关闭]

    Closed 这个问题需要细节或清晰度 help closed questions 目前不接受答案 最近在学习opencv 有没有办法使用鼠标事件选择图像区域 我已经尝试过三角形的了 如果我想选择特定区域而不是三角形怎么办 谢谢你 我对此进
  • python中的“如果不是”条件语句[重复]

    这个问题在这里已经有答案了 if not start new next None return new 如果不是 是什么意思 这段代码什么时候执行 这和说的是一样的吗 if start None 那么做点什么 if是声明 not start
  • OpenCV Python RTSP 流

    我想使用 RTSP 从 IP 摄像机流式传输视频 但我有一个问题 我已经安装了先决条件 而且我的 RTSP 链接可以在 VlC 播放器上运行 但是当我在编辑器中尝试并运行它时 它说找不到相机 这是我的代码 import cv2 import
  • 从 pandas 数据帧中提取阶段/段以及相应的时间戳

    我有以下数据框 Sleep Stage Time hh mm ss Event Duration s 0 SLEEP S0 23 27 14 SLEEP S0 30 1 SLEEP S0 23 27 44 SLEEP S0 30 2 SLE
  • 为什么我必须在 pybson (=bson, GitHub:py-bson) 之后安装 pymongo 才能成功导入 pybson?

    编辑 将问题放在网上很长时间后 我注意到这是一个衍生产品无法使用 pymongo 2 2 连接到 MongoDB 2 0 5 数据库 https stackoverflow com questions 10603754 cant conne
  • 如何使用BeautifulSoup查找所有下一个链接

    我目前正在通过预设一个名为 number of pages 的变量来抓取特定网站的所有页面 预设此变量一直有效 直到添加了我不知道的新页面 例如 下面的代码适用于 3 个页面 但网站现在有 4 个页面 base url https secu
  • 如何获取当前的 IPython / Jupyter Notebook 名称

    我试图在运行 IPython 笔记本时获取当前的笔记本名称 我知道我可以在笔记本顶部看到它 我在追求什么 currentNotebook IPython foo bar notebookname 我需要在变量中获取名称 添加到以前的答案 要
  • 在 Raspberry Pi 4 上的多个输出设备上播放多个 mp3 文件

    我需要 4 8 个同时播放立体声音频音乐频道 连续播放 SD 卡上特定文件夹中的 mp3 音乐 Working 板载 3 5 音频插孔 USB声卡正常播放音乐 Problem 但一旦我尝试在树莓派上使用带有 USB 声卡的第三个音频输出 其

随机推荐

  • secureCRT 查看日志常用命令

    cd 进入根目录 cd 回到自己的目录 用户不同则目录也不同 root为 root xxt为 home xxt cd 回到上级目录 pwd 显示当前所在的目录 ls 显示当前目录下的所有文件 grep catalina out 在日志中查找
  • 【1G-6G】移动通信技术发展

    移动通信技术发展 1G 早在1947年 贝尔实验室的科学家就提出了蜂窝通信的概念 在20世纪60年代对此进行了系统的实验 20世纪60年代末 70年代初开始出现了第一个蜂窝 Cellular 系统 蜂窝的意思是将一个大区域划分为若干个相邻的
  • ATT&CK - T1546.003

    事件触发的执行 WMI事件订阅 目的 出现场景 ATT CK T1546 003 https attack mitre org techniques T1546 003 检查方式 复现方式 目的 建立持久性 出现场景 比如一些病毒的启动方式
  • excel 两列模糊匹配给出结果_EXCEL快速对比两列数据的不同

    作者 Miss 蜗牛 链接 https www jianshu com p 68b867d4558a 在工作中 我们经常需要对比两列数据或文本是否相同 如果是比较简单并且比较少的时候 我们可以肉眼一个一个的核对 或者都是数字的时候 可以用减
  • MySQL数据库和Oracle数据库的区别

    由于SQL Server不常用 所以这里只针对MySQL数据库和Oracle数据库的区别 1 对事务的提交 MySQL默认是自动提交 而Oracle默认不自动提交 需要用户手动提交 需要在写commit 指令或者点击commit按钮 2 分
  • TensorFlow Lite 入门样例,亲测有效

    参考链接 tensorflow 物体检测模型相关资料 https github com tensorflow models tree master research object detection java api接口 https ten
  • Java设计模式-状态模式

    状态模式 在软件开发过程中 应用程序中的有些对象可能会根据不同的情况做出不同的行为 我们把这种对象称为有状态的对象 而把影响对象行为的一个或多个动态变化的属性称为状态 当有状态的对象与外部事件产生互动时 其内部状态会发生改变 从而使得其行为
  • 【转】机器学习--- 分类算法详解

    原文链接 http blog csdn net china1000 article details 48597469 感觉狼厂有些把机器学习和数据挖掘神话了 机器学习 数据挖掘的能力其实是有边界的 机器学习 数据挖掘永远是给大公司的业务锦上
  • 电阻并联计算_电工必备10套计算公式,收藏了!

    1 串联电路电流和电压有以下几个规律 如 R1 R2串联 电流 I I1 I2 串联电路中各处的电流相等 电压 U U1 U2 总电压等于各处电压之和 电阻 R R1 R2 总电阻等于各电阻之和 如果n个阻值相同的电阻串联 则有R总 nR
  • Linux如何删除服务器上以问号开头的文件

    编辑配置文件的时候由于写入了中文 保存的时候乱码了 生成了问号文件 正常的删除命令是无法删除的 rm rf vimrc 那如何删除呢 使用文件的inode号 获取inode号 ls i 删除文件 find inum 34164153 exe
  • E: Could not get lock /var/lib/dpkg/lock-frontend - open (11: Resource temporarly unavailable)

    这篇文章阅读量最高 就借下楼 下面是我的视频主页 有数字图像处理 深度学习相关的一些视频分享 欢迎围观 MYVision MY视界的个人空间 哔哩哔哩 bilibili 数字图像处理通俗教程 冈萨雷斯 哔哩哔哩 bilibili 0 Pyt
  • opencv人脸检测--detectMultiScale函数

    opencv人脸检测 detectMultiScale函数 转载请注明出处 http blog csdn net itismelzp article details 50379359 首先上两张图 现在要对上面两张图进行人脸检测 一 Haa
  • sqli-labs 21-40关

    21关 进行基本尝试发现用户名与密码都被过滤 那么先登陆试试吧 登陆之后页面变为 发现注入点可能为ip cookie agent 使用抓包软件试试 看这个东西显然被加密了 尝试过之后发现cookie是注入点 不加密时 报错 查看一下题目co
  • 大数据Hadoop学习之————基于物品的协同过滤算法实现物品推荐

    一 基础概念 协同过滤算法一般分为两种实现 基于用户的协同过滤算法 userCF 通过寻找相似兴趣的其他用户 为指定用户推荐物品 比如用户A喜欢商品A B 用户B也喜欢商品A和B 则可以认为用户A和B兴趣相似 这时候就可以像用户A推荐用户B
  • 小程序基本知识点

    Page data定义内容 data name ball changename 更新data里面的数据 this setData name name
  • 如何用人工智能预测股票(完整答案)

    前言 十分钟实现人工智能股价预测 是一个深度学习的练习项目 其通过机器学习算法 根据过去几年与某只股票相关的K线走势 公司相关报道的情感分析作为数据集 通过训练来得到可以预测股价的机器学习模型 并用该模型对股价进行预测 本项目使用几种不同的
  • ajax请求必须打断点才能成功,请问ajax请求过程中都经历了哪些状态?

    紫衣仙女 AJAX运行过程中5种状态 0 未初始化 还没有调用send 方法 1 载入 已调用send 方法 正在发送请求 2 载入完成 send 方法执行完成 3 交互 正在解析响应内容 4 完成 响应内容解析完成 可以在客户端调用了 p
  • RT-DETR论文解读与代码

    RTdetr ecoder和decoder部分pytorch复现代码链接见文末 1 初始化策略与源码有所差异 使用过程中可以根据自己的需求进行更换 2 代码经过一条一条的debug 本身没有bug 并且是依据作者源码用pytorch实现 但
  • 给定数组长度2n,分成n对,求n对最小元素之和最大

    给定长度为 2n 的数组 你的任务是将这些数分成 n 对 例如 a1 b1 a2 b2 an bn 使得从1 到 n 的 min ai bi 总和最大 示例 1 输入 1 4 3 2 输出 4 解释 n 等于 2 最大总和为 4 min 1
  • 2021-09-23 opencv学习笔记(图像变换,二值化,滤波器介绍及python实现)

    opencv学习笔记 颜色空间 改变颜色空间 cv2 cvtColor 目标追踪 如何查找某个颜色的HSV值 图形变换 缩放 cv2 resize 平移 旋转 仿射变换 透视变换 二值化 简单阈值法 自适应阈值 Otsu二值化 俗称大津法