【python-opencv】 sobel算子 图像边缘检测 图像二值化处理 并进行框标定

一、rgb空间下的sobel边缘检测

(1)代码

# -*- coding: utf-8 -*-
import cv2
import matplotlib.pyplot as plt

# 读取图像
# 此处注意cv2.imread读出来的是bgr格式要转为rgb
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)

# Sobel算子
x = cv2.Sobel(grayImage, cv2.CV_16S, 1, 0)  # 对x求一阶导
y = cv2.Sobel(grayImage, cv2.CV_16S, 0, 1)  # 对y求一阶导
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)代码

# -*- coding: utf-8 -*-
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]
    # plt.imshow(img)

    # 高斯模糊去噪
    # img = cv2.medianBlur(img, 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]
    # cv2.imshow("image1", lab_b)

    # Sobel算子
    x = cv2.Sobel(S, cv2.CV_16S, 1, 0)  # 对x求一阶导
    y = cv2.Sobel(S, cv2.CV_16S, 0, 1)  # 对y求一阶导
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

    ## b.设置卷积核5*5s
    kernel = np.ones((1, 1), np.uint8)

    ## 图像的膨胀
    dst = cv2.dilate(sobel, kernel)

    ## c.图像的腐蚀,默认迭代次数
    erosion = cv2.erode(dst, kernel)

    out = erosion

    # out = fillHole(dst)
    return img, out


if __name__ == '__main__':
    # 读取图像
    # 此处注意cv2.imread读出来的是bgr格式要转为rgb
    img = cv2.imread('7.jpg')

    img, out = sobel_cal(img)

    # 显示图形
    cv2.imshow('out', out)
    cv2.waitKey()

(2)结果

  • 可以看到很好的将边缘都检测出来了,效果很明显,纹理也都很清晰
    在这里插入图片描述

三、hsv-s空间下的加入图像腐蚀和图像膨胀,并进行孔洞填充后的sobel边缘检测

(1)代码

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from 图片裁剪 import cut_pic

def fillHole(im_in):
    # Threshold.
    # Set values equal to or above 40 to 255.
    # Set values below 40 to 0.
    # https://blog.csdn.net/a19990412/article/details/81172426 thresh的用法
    th, im_th = cv2.threshold(im_in, 55, 255, cv2.THRESH_BINARY)

    # Copy the thresholded image.
    im_floodfill = im_th.copy()
    # print(im_th)

    # Mask used to flood filling.
    # Notice the size needs to be 2 pixels than the image.
    h, w = im_th.shape[:2]
    mask = np.zeros((h + 2, w + 2), np.uint8)

    # Floodfill from point (0, 0)
    cv2.floodFill(im_floodfill, mask, (0, 0), 255)

    # Invert floodfilled image
    im_floodfill_inv = cv2.bitwise_not(im_floodfill)

    # Combine the two images to get the foreground.
    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)

    # plt.imshow(img)

    # 高斯模糊去噪
    img = cv2.medianBlur(imgs, 7)

    # 高斯模糊去噪
    # img = cv2.medianBlur(img, 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]
    # cv2.imshow("image1", lab_b)

    color_space = S
    # Sobel算子
    x = cv2.Sobel(color_space, cv2.CV_16S, 1, 0)  # 对x求一阶导
    y = cv2.Sobel(color_space, cv2.CV_16S, 0, 1)  # 对y求一阶导
    absX = cv2.convertScaleAbs(x)
    absY = cv2.convertScaleAbs(y)
    sobel = cv2.addWeighted(absX, 0.5, absY, 0.5, 0)

    # b.设置卷积核5*5
    kernel = np.ones((2, 2), np.uint8)

    # 腐蚀的作用说白了就是让暗的区域变大,而膨胀的作用就是让亮的区域变大
    # 图像的膨胀
    dst = cv2.dilate(sobel, kernel)

    # 空洞填充
    out = fillHole(dst)

    # c.图像的腐蚀,默认迭代次数
    erosion = cv2.erode(out, kernel)

    # 图像的膨胀
    dst = cv2.dilate(erosion, kernel)

    # 去除小的斑点
    out = baweraopen(dst, 300)

    return imgs, out


if __name__ == '__main__':
    # 读取图像
    # 此处注意cv2.imread读出来的是bgr格式要转为rgb
    img = cv2.imread('img/10.jpg')

    img, out = sobel_cal(img)

    # 显示图形
    # cv2.imwrite('10.jpg', img)
    cv2.imshow('out', out)
    cv2.waitKey()

(2)结果

  • 可以发现,进行孔洞填充和不进行孔洞填充,对图片进行二值化处理后的效果差距明显。
    在这里插入图片描述
  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值