首页 > 其他分享 >OpenCV 的几种查找图像中轮廓边缘的方法

OpenCV 的几种查找图像中轮廓边缘的方法

时间:2024-06-02 22:02:00浏览次数:12  
标签:阈值 image cv2 OpenCV 查找 图像 import 轮廓 grad

 原始图片:

 

1、Sobel()

Sobel 算子结合了高斯平滑和微分,用于计算图像的梯度,从而突出显示边缘。

import cv2

# 读取图像
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)

# 使用 Sobel 算子查找水平和垂直边缘
sobel_x = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
sobel_y = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)

# 叠加水平和垂直边缘
edges = cv2.addWeighted(cv2.convertScaleAbs(sobel_x), 0.5, cv2.convertScaleAbs(sobel_y), 0.5, 0)



# 显示结果
cv2.imshow("Original Image", image)
cv2.imshow("Edges", edges)

cv2.waitKey(0)
cv2.destroyAllWindows()

函数原型:

sobel = cv2.Sobel(src, ddepth, dx, dy, ksize, scale, delta, borderType) 

参数说明:

  1. src: 输入图像(单通道,例如灰度图)。
  2. ddepth: 输出图像的深度(例如 cv2.CV_64F 表示 64 位浮点数)。
  3. dx: x 方向上的导数阶数(0表示没有导数,1表示一阶导数)。
  4. dy: y 方向上的导数阶数(与 dx 类似)。
  5. ksize: Sobel 核的大小,必须是 1, 3, 5 或 7 等奇数。
  6. scale: 可选值,缩放导数结果,以便调整图像亮度(默认值为 1)。
  7. delta: 可选值,在存储之前添加到结果中的值(默认值为 0)。
  8. borderType: 边界类型,用于确定图像边界(默认值为 cv2.BORDER_DEFAULT)。

 2、Scharr()

Scharr 算子是一种改进的 Sobel 算子,适用于增强边缘检测的精度,在正常的 Sobel 核的尺寸上有更好的性能。

scharr_x = cv2.Scharr(src, ddepth, dx, dy, scale, delta, borderType)

参数说明:

  • 与 cv2.Sobel() 相同,只是 ksize 参数被硬编码为 3。

import cv2
import numpy as np

# 读取图像并转换为灰度图
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)

# 使用 Scharr 算子计算 x 和 y 方向上的梯度
grad_x = cv2.Scharr(image, cv2.CV_64F, 1, 0)
grad_y = cv2.Scharr(image, cv2.CV_64F, 0, 1)

# 将梯度取绝对值并转换为 8 位图像
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)

# 合并 x 方向和 y 方向的梯度
scharr = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)

# 显示图像
cv2.imshow('Scharr Edge Detection', scharr)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

3、Canny()

Canny 边缘检测是一种多级边缘检测算法,效果较为显著,常用来检测图像中的明显边缘。

 函数原型:

edges = cv2.Canny(image, threshold1, threshold2, apertureSize, L2gradient)

参数说明:

  • image: 输入图像,通常是灰度图。
  • threshold1: 较低的阈值,用于边缘检测的滞后阈值过程。
  • threshold2: 较高的阈值。
  • apertureSize: Sobel 算子的大小,默认值为 3。
  • L2gradient: 可选参数,用于计算图像梯度幅值的标志。如果为 True,则使用更精确的 L2 范数计算梯度,否则使用 L1 范数。
  • import cv2
    
    # 读取图像并转换为灰度图
    image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
    
    # 使用 Canny 边缘检测
    edges = cv2.Canny(image, 100, 200)
    
    # 显示图像
    cv2.imshow('Canny Edge Detection', edges)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

4、Laplacian ()

Laplacian 算子是一种二阶导数算子,用于检测图像中的边缘。

laplacian = cv2.Laplacian(src, ddepth, ksize, scale, delta, borderType)

参数说明:

  • src: 输入图像。
  • ddepth: 输出图像的深度。
  • ksize: Laplacian 算子的大小,必须是正奇数。
  • scale: 可选参数,用于缩放导数值,默认值为 1。
  • delta: 可选参数,在存储之前添加到结果中的值,默认值为 0。
  • borderType: 边界模式,默认值为 cv2.BORDER_DEFAULT
    import cv2
    import numpy as np
    
    # 读取图像并转换为灰度图
    image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)
    
    # 使用 Laplacian 边缘检测
    laplacian = cv2.Laplacian(image, cv2.CV_64F)
    
    # 将结果转换为 8 位图像
    laplacian = cv2.convertScaleAbs(laplacian)
    
    # 显示图像
    cv2.imshow('Laplacian Edge Detection', laplacian)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

5、Prewitt算子

Prewitt 算子是另一种一阶导数算子,可以检测水平和垂直边缘。虽然 OpenCV 没有直接提供 cv2.prewitt() 函数,但可以使用 cv2.filter2D 函数自定义 Prewitt 核来实现。 

import cv2
import numpy as np

# 读取图像并转换为灰度图
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)

# 定义 Prewitt 核
prewitt_kernel_x = np.array([[1, 0, -1],
                             [1, 0, -1],
                             [1, 0, -1]])
prewitt_kernel_y = np.array([[1, 1, 1],
                             [0, 0, 0],
                             [-1, -1, -1]])

# 使用 Prewitt 核进行边缘检测
grad_x = cv2.filter2D(image, cv2.CV_64F, prewitt_kernel_x)
grad_y = cv2.filter2D(image, cv2.CV_64F, prewitt_kernel_y)

# 计算梯度幅值
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
prewitt = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)

# 显示图像
cv2.imshow('Prewitt Edge Detection', prewitt)
cv2.waitKey(0)
cv2.destroyAllWindows()

  

 6、Roberts Cross算子

罗伯特交叉算子是一种简单且快速的边缘检测算子,适用于检测图像的对角边缘。OpenCV 中没有直接提供罗伯特交叉算子,但可以通过自定义卷积核实现。

import cv2
import numpy as np

# 读取图像并转换为灰度图
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 定义 Roberts 核
roberts_kernel_x = np.array([[1, 0],
                             [0, -1]])
roberts_kernel_y = np.array([[0, 1],
                             [-1, 0]])

# 使用 Roberts 核进行边缘检测
grad_x = cv2.filter2D(image, cv2.CV_64F, roberts_kernel_x)
grad_y = cv2.filter2D(image, cv2.CV_64F, roberts_kernel_y)

# 计算梯度幅值
abs_grad_x = cv2.convertScaleAbs(grad_x)
abs_grad_y = cv2.convertScaleAbs(grad_y)
roberts = cv2.addWeighted(abs_grad_x, 0.5, abs_grad_y, 0.5, 0)

# 显示图像
cv2.imshow('Roberts Edge Detection', roberts)
cv2.waitKey(0)
cv2.destroyAllWindows()

7、自定义卷积核

还可以通过自定义卷积核来进行边缘检测。

import cv2
import numpy as np

# 读取图像并转换为灰度图
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)

# 定义自定义卷积核
custom_kernel = np.array([[-1, -1, -1],
                          [-1, 7, -1],
                          [-1, -1, -1]])

# 使用自定义卷积核进行边缘检测
custom_edges = cv2.filter2D(image, cv2.CV_64F, custom_kernel)

# 将结果转换为 8 位图像
custom_edges = cv2.convertScaleAbs(custom_edges)

# 显示图像
cv2.imshow('Custom Kernel Edge Detection', custom_edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

 8、基于直方图的边缘检测

基于直方图的方法,通过分析图像的灰度直方图来检测边缘。

import cv2
import numpy as np

# 读取图像并转换为灰度图
image = cv2.imread('image.png', cv2.IMREAD_GRAYSCALE)

# 计算图像的直方图
hist = cv2.calcHist([image], [0], None, [256], [0, 256])

# 找到直方图的峰值
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(hist)

# 使用峰值作为阈值进行二值化处理
_, binary = cv2.threshold(image, max_loc[1] - 30, 255, cv2.THRESH_BINARY)

# 显示图像
cv2.imshow('Histogram Based Edge Detection', binary)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

9、adaptiveThreshold()

自适应阈值

自适应阈值可以在照明不均匀的情况下检测边缘。

函数原型:

cv2.adaptiveThreshold(src, maxValue, adaptiveMethod, thresholdType, blockSize, C[, dst])

参数说明:

  • src:输入图像,应为灰度图像(单通道)。
  • maxValue:指定在满足条件时给输出像素赋予的最大值(通常为255)。
  • adaptiveMethod:自适应方法。可选值有:
    • cv2.ADAPTIVE_THRESH_MEAN_C:基于邻域均值的自适应阈值化方法。
    • cv2.ADAPTIVE_THRESH_GAUSSIAN_C:基于邻域加权均值的自适应阈值化方法。
  • thresholdType:阈值类型,应为 cv2.THRESH_BINARY 或 cv2.THRESH_BINARY_INV
  • blockSize:指定用于计算阈值的邻域大小,一般为奇数。
  • C:从计算的平均值或加权平均值中减去的常数。

import cv2

# 读取图像并转换为灰度图
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 自适应阈值
adaptive_threshold = cv2.adaptiveThreshold(image, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)

# 显示图像
cv2.imshow('Adaptive Threshold Edge Detection', adaptive_threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

10、threshold()

阈值化 (cv2.threshold)

简单的全局阈值化方法,通过固定的阈值来二值化图像以检测边缘。

import cv2

# 读取图像并转换为灰度图
image = cv2.imread('image.jpg', cv2.IMREAD_GRAYSCALE)

# 全局阈值化
_, threshold = cv2.threshold(image, 127, 255, cv2.THRESH_BINARY)

# 显示图像
cv2.imshow('Global Threshold Edge Detection', threshold)
cv2.waitKey(0)
cv2.destroyAllWindows()

 

标签:阈值,image,cv2,OpenCV,查找,图像,import,轮廓,grad
From: https://blog.csdn.net/xulibo5828/article/details/139394245

相关文章

  • 成绩表中查找排名第k的学生
    给定一个长度为n的成绩表(成绩表中包含学生的姓名、成绩),以及一个整数k,请设计一个算法求出成绩表从小到大排序后的第k个学生的姓名、成绩(成绩保留到小数点后1位),并列则全部输出。输入描述:第一行两个正整数,n和k然后后n行,每行两个整数,分别代表每个学生的姓名和成绩输出描述:所......
  • 二分_查找
    intmain(){ intarr[]={1,2,3,4,5,6,7,8,9,10}; intk=7;//要查找的数字 //在这个arr有序数组中查找k的下标的值 intsz=sizeof(arr)/sizeof(arr[0]);//数组的元素个数 intleft=0; intright=sz-1; while(left<=right) { intmid=(left+r......
  • 解决OpenCV读取目标图像,cv2.imshow出现闪退的问题
    前言本文是该专栏的第17篇,后面将持续分享OpenCV计算机视觉的干货知识,记得关注。最近有粉丝朋友询问到OpenCV读取目标图像出现的一个问题,在基于python语言“使用OpenCV读取目标图像的时候,利用cv2.imshow函数出现闪退”的情况。而本文,笔者将详细介绍针对上述问题,给出一个详......
  • 【Python--openCV图像处理】Python学习-OpenCV图像处理基础超详细的学习笔记(黑马程序
    一,openCV基础说明:笔记是跟着B站黑马程序员的openCV课程时做的课程资料可以在黑马程序员评论区获取1,图像基本操作1-1图像基础操作1-1-1安装相关库pipinstallopencv-pythonpipinstallopencv-contrib-python##尽量保持两个库安装的版本,比如我都是4.9.0.80ope......
  • LeetCode 704 二分查找
    第一次提交错误:if-else语句中第二个if前未加else,导致循环出错//二分查找//有序情况下的查找方式,时间复杂度O(logn)//注意左右边界以及停止循环条件left<=right classSolution{publicintsearch(int[]nums,inttarget){......
  • 基于Python+OpenCV高速公路行驶车辆的速度检测系统
    欢迎大家点赞、收藏、关注、评论啦,由于篇幅有限,只展示了部分核心代码。文章目录一项目简介二、功能三、系统四.总结一项目简介  一、项目背景与意义随着交通流量的增加和高速公路的快速发展,高速公路上的车辆速度管理成为了保障道路安全和提升通行效率的重......
  • Linux搜索查找类
    1.find  【find指令将从指定目录向下递归遍历其中各个子目录,将满足条件的文件或者目录显示在终端】       案例1:按文件名:根据名称查找/home目录下的hello.txt文件find/home-namehello.txt   案例2:按拥有者:查找/opt目录下,用户名称为Tom的......
  • 如何使用带有 typescript 的 playwright 查找 react 应用程序的 LCP?
    需要获取使用playwright和typescript的react应用程序的最大Contentful画面这是用于网络性能测试的,应该是精确的值我尝试了https://web.dev/articles/lcp#measure-lcp-in-javascript并使用Typescript实现了相同的功能但是我们需要知道,我们是否还有其他东西returnp......
  • 【LeetCode刷题】专题三:二分查找模板
    【LeetCode刷题】Day11专题三:二分查找模板:1.朴素二分模板:2.区间左值模板:3.区间右值模板:题目1:704.二分查找思路分析:思路1:朴素二分查找O(logN)题目2:34.在排序数组中查找元素的第一个和最后一个位置思路分析:思路1:区间左右值二分查找O(logN)专题三:二分查找模板......
  • 完全二叉树查找
    描述有一棵树,输出某一深度的所有节点,有则输出这些节点,无则输出EMPTY。该树是完全二叉树。输入描述输入有多组数据,遇到0时终止输入。每组输入一个n(1<=n<=1000),然后将树中的这n个节点依次输入,再输入一个d代表深度。输出描述输出该树中第d层得所有节点,节点间用空格隔开,最后......