1、Primitiv
# 原始图像梯度算子
import cv2
import numpy as np
moon = cv2.imread("./sudoku.jpg", 0)
row, column = moon.shape
moon_f = np.copy(moon)
moon_f = moon_f.astype("float")
Primary = np.zeros((row, column))
for x in range(row - 1):
for y in range(column - 1):
gx = abs(moon_f[x + 1, y] - moon_f[x, y])
gy = abs(moon_f[x, y + 1] - moon_f[x, y])
Primary[x, y] = gx + gy
sharp = moon_f + Primary
sharp = np.where(sharp < 0, 0, np.where(sharp > 255, 255, sharp))
sharp = sharp.astype("uint8")
cv2.imshow("src", moon)
cv2.imshow("Primary_sharp", sharp)
cv2.imwrite('./Primary_sharp.jpg', sharp)
cv2.waitKey()
2、Roberts
import cv2
import numpy as np
moon = cv2.imread("./sudoku.jpg", 0)
row, column = moon.shape
moon_f = np.copy(moon)
moon_f = moon_f.astype("float")
Roberts = np.zeros((row, column))
for x in range(row - 1):
for y in range(column - 1):
gx = abs(moon_f[x + 1, y + 1] - moon_f[x, y])
gy = abs(moon_f[x + 1, y] - moon_f[x, y + 1])
Roberts[x, y] = gx + gy
sharp = moon_f + Roberts
sharp = np.where(sharp < 0, 0, np.where(sharp > 255, 255, sharp))
sharp = sharp.astype("uint8")
cv2.imshow("src", moon)
cv2.imshow("Roberts_sharp", sharp)
cv2.imwrite('./Roberts_sharp.jpg', sharp)
cv2.waitKey()
3、Prewitt
import cv2
import numpy as np
moon = cv2.imread("./sudoku.jpg", 0) # 读取图片,并且为灰度图
row, column = moon.shape # 获取图片形状 (行, 列)
moon_f = np.copy(moon)
moon_f = moon_f.astype("float")
prewitt = np.zeros((row, column))
print(type(prewitt[0, 0]))
# 计算X轴和Y轴梯度
for x in range(1, row - 1):
for y in range(1, column - 1):
gx = abs((moon_f[x + 1, y - 1] + moon_f[x + 1, y] + moon_f[x + 1, y + 1]) - (
moon_f[x - 1, y - 1] + moon_f[x - 1, y] + moon_f[x - 1, y + 1]))
gy = abs((moon_f[x - 1, y + 1] + moon_f[x, y + 1] + moon_f[x + 1, y + 1]) - (
moon_f[x - 1, y - 1] + moon_f[x, y - 1] + moon_f[x + 1, y - 1]))
prewitt[x, y] = gx + gy
sharp = moon_f + prewitt
sharp = np.where(sharp < 0, 0, np.where(sharp > 255, 255, sharp))
sharp = sharp.astype("uint8")
cv2.imshow("src", moon)
cv2.imshow("prewitt_sharp", sharp)
cv2.waitKey()
4、Sobel
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
核大小(ksize)。如果ksize=-1,表示使用3X3的Scharr滤波器。
建议在处理速度相同的情况下,尽量使用Scharr滤波器。
"""
import cv2 as cv
import numpy as np
def nothing(x):
pass
cv.namedWindow('Sobel x')
cv.namedWindow('Sobel y')
# 创建滑动条
cv.createTrackbar('xsize', 'Sobel x', 1, 15, nothing)
cv.createTrackbar('ysize', 'Sobel y', 1, 15, nothing)
# def sp_noise(image,prob):
# '''
# 添加椒盐噪声
# 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)
cv.imshow("src", img)
while True:
kx = cv.getTrackbarPos('xsize', 'Sobel x')
ky = cv.getTrackbarPos('ysize', 'Sobel y')
if (kx % 2) == 0:
kx += 1
if (ky % 2) == 0:
ky += 1
# 参数 1,0 为只在 x 方向求一 导数 最大可以求 2 导数。
sobelx = cv.Sobel(img, cv.CV_64F, 1, 0, ksize=kx)
# 参数 0,1 为只在 y 方向求一 导数 最大可以求 2 导数。
sobely = cv.Sobel(img, cv.CV_64F, 0, 1, ksize=ky)
# 求绝对值
sobelx = cv.convertScaleAbs(sobelx)
sobely = cv.convertScaleAbs(sobely)
sobel_xy = cv.addWeighted(sobelx, .5, sobely, .5, 1)
k = cv.waitKey(24) & 0xFF
if chr(k) == 'q':
break
cv.imshow('Sobel x', sobelx)
cv.imshow('Sobel y', sobely)
cv.imshow('sobel_xy', sobel_xy)
cv.destroyAllWindows()
5、soble_video
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import cv2 as cv
def nothing(x):
pass
cv.namedWindow('Sobel x')
cv.namedWindow('Sobel y')
cv.namedWindow('Sobel_xy')
# 创建滑动条
cv.createTrackbar('xsize', 'Sobel x', 1, 15, nothing)
cv.createTrackbar('ysize', 'Sobel y', 1, 15, nothing)
cap = cv.VideoCapture(0)
while cap.isOpened():
ret, frame = cap.read()
# frame = cv.blur(frame, (5, 5))
frame = cv.GaussianBlur(frame, (5, 5), -1)
gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
if (not ret):
break
kx = cv.getTrackbarPos('xsize', 'Sobel x')
ky = cv.getTrackbarPos('ysize', 'Sobel y')
if (kx % 2) == 0:
kx += 1
if (ky % 2) == 0:
ky += 1
# 参数 1,0 为只在 x 方向求一 导数 最大可以求 2 导数。
sobelx = cv.Sobel(gray, cv.CV_64F, 1, 0, ksize=kx)
# 参数 0,1 为只在 y 方向求一 导数 最大可以求 2 导数。
sobely = cv.Sobel(gray, cv.CV_64F, 0, 1, ksize=ky)
# 计算绝对值,并将结果转换为8位
# 在输入数组的每个元素上,函数convertScaleAbs。顺序执行三个操作:缩放,取绝对值。值,转换为无符号8位类型
sobelx = cv.convertScaleAbs(sobelx)
sobely = cv.convertScaleAbs(sobely)
sobel_xy = cv.addWeighted(sobelx, .5, sobely, .5, 1)
k = cv.waitKey(24) & 0xFF
if chr(k) == 'q':
break
cv.imshow('Sobel x', sobelx)
cv.imshow('Sobel y', sobely)
ret, img = cv.threshold(sobel_xy, 130, 255, cv.THRESH_BINARY_INV)
cv.imshow('Sobel_xy', sobel_xy)
cv.destroyAllWindows()