一、rgb空间下的sobel边缘检测
(1)代码
import cv2
import matplotlib.pyplot as plt
img = cv2.imread('7.jpg')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = cv2.resize(img, (0, 0), fx=0.2, fy=0.2, interpolation=cv2.INTER_NEAREST)[25:25 + 700, 210:210 + 760]
plt.imshow(img)
img = cv2.medianBlur(img, 7)
grayImage = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0)
y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
Sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
plt.imshow(Sobel, 'gray')
plt.show()
(2)结果
- 可以看到效果不是很好,所以接下来会在hsv空间下改进
二、hsv-s空间下的加入图像腐蚀和图像膨胀的sobel边缘检测
(1)代码
import cv2
import numpy as np
def sobel_cal(img):
img = cv2.resize(img, (0, 0), fx=0.2, fy=0.2, interpolation=cv2.INTER_NEAREST)[25:25 + 700, 210:210 + 760]
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
H, S, V = cv2.split(hsv)
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
lab_l = lab[..., 0]
lab_a = lab[..., 1]
lab_b = lab[..., 2]
x = cv2.Sobel(S, cv2.CV_16S, 1, 0)
y = cv2.Sobel(S, cv2.CV_16S, 0, 1)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
kernel = np.ones((1, 1), np.uint8)
dst = cv2.dilate(sobel, kernel)
erosion = cv2.erode(dst, kernel)
out = erosion
return img, out
if __name__ == '__main__':
img = cv2.imread('7.jpg')
img, out = sobel_cal(img)
cv2.imshow('out', out)
cv2.waitKey()
(2)结果
- 可以看到很好的将边缘都检测出来了,效果很明显,纹理也都很清晰
三、hsv-s空间下的加入图像腐蚀和图像膨胀,并进行孔洞填充后的sobel边缘检测
(1)代码
import cv2
import numpy as np
from 图片裁剪 import cut_pic
def fillHole(im_in):
th, im_th = cv2.threshold(im_in, 55, 255, cv2.THRESH_BINARY)
im_floodfill = im_th.copy()
h, w = im_th.shape[:2]
mask = np.zeros((h + 2, w + 2), np.uint8)
cv2.floodFill(im_floodfill, mask, (0, 0), 255)
im_floodfill_inv = cv2.bitwise_not(im_floodfill)
im_out = im_th | im_floodfill_inv
return im_out
def baweraopen(image, size):
'''
@image:单通道二值图,数据类型uint8
@size:欲去除区域大小(黑底上的白区域)
'''
output = image.copy()
nlabels, labels, stats, centroids = cv2.connectedComponentsWithStats(image)
for i in range(1, nlabels - 1):
regions_size = stats[i, 4]
if regions_size < size:
x0 = stats[i, 0]
y0 = stats[i, 1]
x1 = stats[i, 0] + stats[i, 2]
y1 = stats[i, 1] + stats[i, 3]
for row in range(y0, y1):
for col in range(x0, x1):
if labels[row, col] == i:
output[row, col] = 0
return output
def sobel_cal(imgs):
if imgs.size != 1596000:
imgs = cut_pic(imgs)
img = cv2.medianBlur(imgs, 7)
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
H, S, V = cv2.split(hsv)
lab = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
lab_l = lab[..., 0]
lab_a = lab[..., 1]
lab_b = lab[..., 2]
color_space = S
x = cv2.Sobel(color_space, cv2.CV_16S, 1, 0)
y = cv2.Sobel(color_space, cv2.CV_16S, 0, 1)
absX = cv2.convertScaleAbs(x)
absY = cv2.convertScaleAbs(y)
sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)
kernel = np.ones((2, 2), np.uint8)
dst = cv2.dilate(sobel, kernel)
out = fillHole(dst)
erosion = cv2.erode(out, kernel)
dst = cv2.dilate(erosion, kernel)
out = baweraopen(dst, 300)
return imgs, out
if __name__ == '__main__':
img = cv2.imread('img/10.jpg')
img, out = sobel_cal(img)
cv2.imshow('out', out)
cv2.waitKey()
(2)结果
- 可以发现,进行孔洞填充和不进行孔洞填充,对图片进行二值化处理后的效果差距明显。