Digital Image Processing--Edge Detection

Digital Image Processing – Edge Detection

main content

(1) Complete image reading and display, and add Gaussian noise to the image;
(2) Use three first-order differential operators (Roberts, Sobel, Prewitt operators) and second-order differential operators (Laplacian , LOG, DOG) to achieve edge detection;

source code

Without further ado, let's go to the code

import numpy as np
import cv2
import matplotlib.pyplot as plt
from skimage import util,filters

def roberts_operator(block):
    kernel1 = np.array([[1,0], [0,-1]])
    kernel2 = np.array([[0,-1], [1,0]])
    return np.abs(np.sum(block[1:,1:] * kernel1)) + np.abs(np.sum(block[1:,1:] * kernel2))

def sobel_operator(block, orientation):
    if orientation == 'horizontal':
        kernel = np.array([[-1,-2,-1], [0,0,0], [1,2,1]])
    elif orientation == 'vertical':
        kernel = np.array([[-1,0,1], [-2,0,2], [-1,0,1]])
    else:
        raise('Orientation Error')
    return np.abs(np.sum(block * kernel))

def prewitt_operator(block):
    kernel1 = np.array([[1,0,-1],[1,0,-1],[1,0,-1]])
    kernel2 = np.array([[-1,-1,-1],[0,0,0],[1,1,1]])
    return np.abs(np.sum(block * kernel1)) + np.abs(np.sum(block * kernel2))

def laplacian_operator(block):
    kernel = np.array([[0,-1,0], [-1,4,-1], [0,-1,0]])
    return np.abs(np.sum(block * kernel))

def Dog_operator(img, operator_type):
    if operator_type == 'dog':
        #两次高斯滤波
        gimg1 = filters.gaussian(img, sigma=2)
        gimg2 = filters.gaussian(img, sigma=1.6 * 2)
        #两个高斯运算的差分
        dimg = gimg2 - gimg1
        #归一化
        dimg /= 2
        return dimg

def Log_operator(img,operator_type):
    if operator_type == 'log':
        img = cv2.GaussianBlur(img, (3, 3), sigmaX=0)    # 以核大小为3x3,方差为0的高斯函数进行高斯滤波

        filter = np.array([[0, 0, 1, 0, 0],
                             [0, 1, 2, 1, 0],
                             [1, 2, 16, 2, 1],
                             [0, 1, 2, 1, 0],
                             [0, 0, 1, 0, 0]])
        img = np.pad(img, ((2, 2), (2, 2)), 'constant')  # 填充
        # 高斯滤波:平滑
        w, h = img.shape
        for i in range(w - 4):
            for j in range(h - 4):
                img[i][j] = np.sum(img[i:i + 5, j:j + 5] * filter)
        #laplace算子
        lap4_filter = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]])
        img = np.pad(img, ((1, 1), (1, 1)), 'constant')

        edge4_img = np.zeros((w, h))
        for i in range(w - 2):
            for j in range(h - 2):
                edge4_img[i, j] = np.sum(img[i:i + 3, j:j + 3] * lap4_filter)
                if edge4_img[i, j] < 0:
                    edge4_img[i, j] = 0  # 把所有负值修剪为0
                elif edge4_img[i,j] > 0:
                    edge4_img[i,j] = 152 # 增强一些正值的像素值
        return edge4_img

def operator_process(img, operator_type, orientation=None):
    n, m = img.shape
    res = np.zeros((n, m))

    for i in range(1, n-1):
        for j in range(1, m-1):
            if operator_type == 'roberts':
                res[i][j] = roberts_operator(img[i-1:i+2, j-1:j+2])
            elif operator_type == 'sobel':
                res[i][j] = sobel_operator(img[i-1:i+2, j-1:j+2], orientation)
            elif operator_type == 'prewitt':
                res[i][j] = prewitt_operator(img[i-1:i+2, j-1:j+2])
            elif operator_type == 'laplacian':
                res[i][j] = laplacian_operator(img[i-1:i+2, j-1:j+2])
            else:
                raise('Operator Type Error')

    return res


# 图像转化成灰度图像
rose = cv2.imread('2.png', cv2.IMREAD_GRAYSCALE)
#添加高斯噪声
rose_Gaussian = util.random_noise(rose,mode = 'Gaussian')
rose_Gaussian = rose_Gaussian*255

#Roberts算子
Roberts = operator_process(rose_Gaussian,'roberts')

#Sobel算子
Sobel = operator_process(rose_Gaussian,'sobel','horizontal')

#Prewitt算子
Prewitt = operator_process(rose_Gaussian,'prewitt')

#拉普拉斯算子
Laplacian = operator_process(rose_Gaussian,'laplacian')

#Dog算子
Dog = Dog_operator(rose_Gaussian,'dog')

#Log算子:图像去噪+拉普拉斯算子
Log = Log_operator(rose_Gaussian,'log')

#绘图
#设置画布标题字体为中文,不设置的话,可能会出现乱码结果
plt.rcParams["font.sans-serif"]=["SimHei"]
plt.rcParams["axes.unicode_minus"]=False

plt.subplot(331),plt.imshow(rose,cmap='gray'),plt.title('原图')
plt.subplot(332),plt.imshow(rose_Gaussian,cmap='gray'),plt.title('After-Gaussian')

plt.subplot(334),plt.imshow(Roberts,cmap='gray'),plt.title('Roberts')
plt.subplot(335),plt.imshow(Sobel,cmap='gray'),plt.title('Sobel')
plt.subplot(335),plt.imshow(Sobel,cmap='gray'),plt.title('Sobel')
plt.subplot(336),plt.imshow(Prewitt,cmap='gray'),plt.title('Prewitt')

plt.subplot(337),plt.imshow(Laplacian,cmap='gray'),plt.title('Laplacian')
plt.subplot(338),plt.imshow(Log,cmap='gray'),plt.title('Log')
plt.subplot(339),plt.imshow(Dog,cmap='gray'),plt.title('Dog')

plt.suptitle('边缘检测',fontsize = 20)
plt.tight_layout(rect=(0, 0, 1, 0.9))
plt.show()

achieve results

insert image description here
Result analysis: As shown in the figure above, it is easy to see that the expressive power of the three first-order differential operators is still very good. The Roberts operator is more accurate in positioning, and has a better effect on image processing with steep low noise, but it is still relatively sensitive to noise. The Sobel operator and the Prewitt operator are better at processing images with grayscale gradients and more noise. The results in the figure above show that the boundaries are relatively clear.
However, the second-order differential operator Laplacian operator is very sensitive to noise and loses a lot of edge direction information, so the effect is not very good. LoG: Through image smoothing and then performing Laplacian operator operations, the positioning accuracy is improved, the edge continuity is good, and weaker edge points can also be extracted. Finally, the DoG operator Gaussian difference is simple to calculate, but its expressive power is the strongest among the above six operators, and it realizes edge detection very well.

Xiaobai is a beginner!

Guess you like

Origin blog.csdn.net/MZYYZT/article/details/128114623