opencv——图像边缘检测(中)Scharr、Laplacian算子

1、Schaar

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

"""
Scharr算子是高斯平滑与微分操作的结合体,所以它具有很好的抗噪声能力。
"""
import cv2 as cv
import numpy as np

'''
添加椒盐噪声
prob:噪声比例
'''


def sp_noise(image, prob):
    output = np.zeros(image.shape, np.uint8)
    thres = 1 - prob
    for i in range(image.shape[0]):
        for j in range(image.shape[1]):
            rdn = np.random.random()
            if rdn < prob:
                output[i][j] = 0
            elif rdn > thres:
                output[i][j] = 255
            else:
                output[i][j] = image[i][j]
    return output


img = cv.imread('./sudoku.jpg', 0)
# img = sp_noise(img, 0.009)


# 参数 1,0 为只在 x 方向求一 导数 最大可以求 2 导数。
Scharrx = cv.Scharr(img, cv.CV_64F, 1, 0)
# 参数 0,1 为只在 y 方向求一 导数 最大可以求 2 导数。
Scharry = cv.Scharr(img, cv.CV_64F, 0, 1)

# 求绝对值
Scharrx = cv.convertScaleAbs(Scharrx)
Scharry = cv.convertScaleAbs(Scharry)

Scharr_xy = cv.addWeighted(Scharrx, .5, Scharry, .5, 0)
cv.imshow('Scharr x', Scharrx)
cv.imshow('Scharr y', Scharry)
cv.imshow('Scharr_xy', Scharr_xy)
cv.waitKey(0)

cv.destroyAllWindows()

opencv——图像边缘检测(中)Scharr、Laplacian算子_第1张图片

2、Laplacian

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Laplacian(拉普拉斯)算子可以使用二阶导数的形式定义,可假设其离散实现类似于二阶Scharr导数,
事实上OpenCV在算拉普拉斯算子时直接用Sobel算子。
"""
import cv2 as cv


def nothing(x):
    pass


cv.namedWindow('Laplacian')

# 创建滑动条
cv.createTrackbar('ksize', 'Laplacian', 1, 15, nothing)

img = cv.imread('./sudoku.jpg', 0)
while True:
    img = cv.imread('./sudoku.jpg', 0)
    ksize = cv.getTrackbarPos('ksize', 'Laplacian')
    if (ksize % 2) == 0:
        ksize += 1
    laplacian = cv.Laplacian(img, cv.CV_64F, ksize=ksize)

    # 计算绝对值,并将结果转换为8位
    # 在输入数组的每个元素上,函数convertScaleAbs。顺序执行三个操作:缩放,取绝对值。值,转换为无符号8位类型
    laplacian = cv.convertScaleAbs(laplacian)

    k = cv.waitKey(24) & 0xFF
    if chr(k) == 'q':
        break
    cv.imshow('Laplacian', laplacian)

cv.destroyAllWindows()

3、Laplacian_video

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Laplacian(拉普拉斯)算子可以使用二阶导数的形式定义,可假设其离散实现类似于二阶Scharr导数,
事实上OpenCV在算拉普拉斯算子时直接用Sobel算子。
"""
import cv2 as cv


def nothing(x):
    pass


cv.namedWindow('Laplacian')

# 创建滑动条
cv.createTrackbar('ksize', 'Laplacian', 1, 15, nothing)

cap = cv.VideoCapture(0)
while cap.isOpened():
    ret, frame = cap.read()
    frame = cv.GaussianBlur(frame, (5, 5), 0)
    gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
    if (not ret):
        break
    ksize = cv.getTrackbarPos('ksize', 'Laplacian')
    if (ksize % 2) == 0:
        ksize += 1
    laplacian = cv.Laplacian(gray, cv.CV_64F, ksize=ksize)

    # 计算绝对值,并将结果转换为8位
    # 在输入数组的每个元素上,函数convertScaleAbs。顺序执行三个操作:缩放,取绝对值。值,转换为无符号8位类型
    laplacian = cv.convertScaleAbs(laplacian)

    k = cv.waitKey(24) & 0xFF
    if chr(k) == 'q':
        break
    cv.imshow('Laplacian', laplacian)

cv.destroyAllWindows()

4、2D卷积

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
使用自定义卷积核进行图像2D卷积操作
    cv2.filter2D()
"""
import cv2 as cv
import numpy as np

img = cv.imread('./test.png', 0)

# 自己进行垂直边缘提取
kernel = np.array([[-1, 0, 1],
                   [-2, 0, 2],
                   [-1, 0, 1]], dtype=np.float32)

dst = cv.filter2D(img, -1, kernel)

cv.imshow('img', img)
cv.imshow('dst', dst)

cv.waitKey(0)
cv.destroyAllWindows()

opencv——图像边缘检测(中)Scharr、Laplacian算子_第2张图片

你可能感兴趣的:(OpenCV)