提示:这里可以添加本文要记录的大概内容:
例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。
#test5-1.py:拉普拉斯边缘检测
import cv2
img=cv2.imread('bee.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
img2=cv2.Laplacian(img,cv2.CV_8U,ksize=1)
img3=cv2.Laplacian(img,-1,ksize=5)
#边缘检测 ksize ksize是算子的大小,必须为1、3、5、7。默认为1 用于计算二阶导数的滤波器的孔径尺寸,大小必须为正奇数(正奇数才能有中心点)
#cv2.cv_8U,输出图像的深度(数据类型)
#可以使用-1, 与原图像保持一致np.uint8
#数据类型结构: CV_ 【bit_depth】【S/U/F】【C】
#CV_8U - 8位无符号整数(0..255)
cv2.imshow('Laplacian2',img2) #显示结果
cv2.imshow('Laplacian3',img3) #显示结果
cv2.waitKey(0)
opencv:边缘检测之Laplacian算子思想及实现
Opencv学习——边缘检测(Laplacian)
#test5-2.py:Sobel边缘检测
import cv2
img=cv2.imread('bee.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
img2=cv2.Sobel(img,cv2.CV_8U,0,1) #边缘检测
#dx和dy指的是求导的阶数,0表示这个方向上没有求导,所填的数一般为0、1、2
#(0表示不求偏导,1表示1阶偏导,2表示2阶偏导)
# dx >= 0 && dy >= 0 && dx+dy > 0
#ksize是Sobel算子的大小,即卷积核的大小,必须为奇数1、3、5、7。如果ksize=-1,就演变成为3x3的Scharr算子,
# scale是缩放导数的比例常数,默认情况为没有伸缩系数。
# borderType是判断图像边界的模式,这个参数默认值为cv2.BORDER_DEFAULT。
img3=cv2.Sobel(img,cv2.CV_8U,0,1,ksize=7) #sobel内核大小设置为7
img4=cv2.Sobel(img,cv2.CV_8U,0,2) #dx=0 dy=2 表示对y求二阶偏导
cv2.imshow('Sobel_2',img2) #显示结果
cv2.imshow('Sobel_3',img3) #显示结果
cv2.imshow('Sobel_4',img4)
cv2.waitKey(0)
OpenCV——Canny边缘检测(cv2.Canny())
Canny()边缘检测步骤
Canny 边缘检测分为如下几个步骤:
步骤 1:去噪。噪声会影响边缘检测的准确性,因此首先要将噪声过滤掉。
步骤 2:计算梯度的幅度与方向。
步骤 3:非极大值抑制,即适当地让边缘“变瘦”。
步骤 4:确定边缘。使用双阈值算法确定最终的边缘信息。
#test5-3.py:Canny边缘检测
import cv2
img=cv2.imread('bee.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
img2=cv2.Canny(img,200,300) #边缘检测
#threshold1 表示处理过程中的第一个阈值。
#threshold2 表示处理过程中的第二个阈值。
#其中一个为高阈值 maxVal,另一个为低阈值 minVal。
# 根据当前边缘像素的梯度值(指的是梯度幅度,下同)
# 与这两个阈值之间的关系,判断边缘的属性
img3=cv2.Canny(img,100,400)
cv2.imshow('Canny_2',img2) #显示结果
cv2.imshow('Canny_3',img3) #显示结果
cv2.waitKey(0)
应用双阈值确定边缘
完成上述步骤后,图像内的强边缘已经在当前获取的边缘图像内。但是,一些虚边缘可能也在边缘图像内。这些虚边缘可能是真实图像产生的,也可能是由于噪声所产生的。对于后者,必须将其剔除。
设置两个阈值,其中一个为高阈值 maxVal,另一个为低阈值 minVal。根据当前边缘像素的梯度值(指的是梯度幅度,下同)与这两个阈值之间的关系,判断边缘的属性。具体步骤为:
(1)如果当前边缘像素的梯度值大于或等于 maxVal,则将当前边缘像素标记为强边缘。
(2)如果当前边缘像素的梯度值介于 maxVal 与 minVal 之间,则将当前边缘像素标记为虚
边缘(需要保留)。
(3)如果当前边缘像素的梯度值小于或等于 minVal,则抑制当前边缘像素。
在上述过程中,我们得到了虚边缘,需要对其做进一步处理。一般通过判断虚边缘与强边缘是否连接,来确定虚边缘到底属于哪种情况。通常情况下,如果一个虚边缘:
与强边缘连接,则将该边缘处理为边缘。
与强边缘无连接,则该边缘为弱边缘,将其抑制。
原文链接:https://blog.csdn.net/m0_51402531/article/details/121066693
OpenCV——Canny边缘检测(cv2.Canny())
报错信息
报错原因,opencv版本问题,我使用的是opencv3.4.11,升级后(opencv4.5.5)解决该问题
#test5-4.py 查找轮廓
#操作步骤
#1. 首先将原图转为灰度图(cv2.cvtColor())
#2. 将灰度图转换为二值图(cv2.threshold())
#3. 通过查找轮廓函数返回点集合[c可能是列表,也有可能是元组] cv2.findcontours()
#4. 绘制轮廓 polylines() 需要c的点集合
#c,h=cv2.findcontours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
#c表示的时轮廓,返回的时列表
#h是层次,返回的是numpy数组
#cv2.RETR_TREE 检索所有轮廓并创建完整的层次列表,比如父级,子级
#cv2.CHAIN_APPROX_SIMPLE:保持水平、垂直、对角线的端点
import cv2
import numpy as np
img = cv2.imread('shapes.jpg')
cv2.imshow('original',img)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转换为灰度图像
ret,img2 = cv2.threshold(gray,125,255,cv2.THRESH_BINARY)#二值化阈值处理,将大于125的像素的值设置为255,
#小于125的像素设置为0
c,h = cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #查找轮廓的函数
print('轮廓:',c) #返回的是列表,但Opencv版本不同,结果可能不同,有可能是元组类型tuple
print('轮廓类型:',type(c))
print('轮廓个数:',len(c))
print('层次类型',type(h))
print('层次',h)
for n in(range(3)):
img3 = np.zeros(img.shape,np.uint8)+255 #按原图大小创建一个白色背景
cv2.polylines(img3,[c[n]],True,(255,0,0),2) #按照点的集合重新绘制查找到的轮廓 cv2.polylines()函数 44页
#c[n]表示各个轮廓的点集合,c[0]表示第一个轮廓点集
cv2.imshow('%s'%n,img3) #显示轮廓 %s表示占位符
cv2.waitKey(0)
参考:opencv:图像轮廓检测 cv2.findContours() 与 cv2.drawContours()
#test5-5.py:绘制轮廓
#先查找后绘制,前7行代码与查找轮廓代码一致
import cv2
import numpy as np
img=cv2.imread('shapes.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY)#二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
#image=cv2.drawContours(image,contours,contourIdx,color,thickness)
#image:原图
#contours为要绘制的轮廓
img3=cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓 -1表示绘制所有轮廓
cv2.imshow('Contours',img3) #显示轮廓图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
1.轮廓的矩
#test5-6.py:轮廓矩
import cv2
import numpy as np
img=cv2.imread('shape2.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY)#二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
img3=cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓 -1表示绘制所有轮廓
cv2.imshow('Contours',img3) #显示轮廓图像
for n in range(len(c)):
m=cv2.moments(c[n]) #cv2.moments()函数用于返回轮廓的矩
#返回的结果是字典类型 字典的内容在花括号 {} 内,
# 键-值(key-value)之间用冒号 : 分隔,键值对之间用逗号 , 分隔
print('轮廓%s的矩:'%n,m) #输出轮廓矩 %s是占位符
print('轮廓%s的面积:'%n,m['m00']) #输出轮廓面积
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
2.轮廓面积
#test5-7.py:轮廓面积
import cv2
import numpy as np
img=cv2.imread('shape2.jpg') #读取图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)#查找轮廓
for n in range(len(c)):
m=cv2.contourArea(c[n]) #计算轮廓面积
print('轮廓%s的面积:'%n,m) #输出轮廓面积
3.轮廓的长度
#test5-8.py:轮廓长度
import cv2
import numpy as np
img=cv2.imread('shape2.jpg') #读取图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #查找轮廓
for n in range(len(c)):
m=cv2.arcLength(c[n],True) #计算轮廓长度 True表示轮廓是封闭的
print('轮廓%s的长度:'%n,m) #输出轮廓长度
4.轮廓的近似多边形
#test5-9.py:轮廓的近似多边形
import cv2
import numpy as np
img=cv2.imread('shape3.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY)#二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #查找轮廓
ep=[0.1,0.05,0.01]
arcl=cv2.arcLength(c[0],True) #计算轮廓长度
print(arcl)
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
img3=cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓
for n in range(3):
eps=ep[n]*arcl
img4=img3.copy()
app=cv2.approxPolyDP(c[0],eps,True) #获得近似多边形
img4=cv2.drawContours(img4,[app],-1,(255,0,0),2) #绘制近似轮廓
cv2.imshow('appro %.2f' % ep[n],img4) #显示轮廓图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
5.轮廓的凸包
#test5-10.py:轮廓的凸包
import cv2
import numpy as np
img=cv2.imread('shape3.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY)#二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #查找轮廓
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
img3=cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓
hull = cv2.convexHull(c[0]) #returnPoints没写出来,则默认值是True,返回的是凸包关键点的坐标
print('returnPoints=True时返回的凸包:\n',hull)
hull2 = cv2.convexHull(c[0],returnPoints=False)
print('returnPoints=False时返回的凸包:\n',hull2)
cv2.polylines(img3,[hull],True,(255,0,0),2) #绘制凸包
cv2.imshow('Convex Hull',img3) #显示轮廓图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
6.轮廓的直边界矩形
#test5-11.py:轮廓的直边界矩形
import cv2
import numpy as np
img=cv2.imread('shape4.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #计算轮廓
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓
ret=cv2.boundingRect(c[0]) #计算直边矩形 返回值ret是一个四元组
#(ret[0],ret[1])矩形左上角坐标 ret[2]、ret[3]矩形宽度和高度
print('直边界矩形:',ret)
pt1=(ret[0],ret[1])
pt2=(ret[0]+ret[2],ret[1]+ret[3]) #pt1的对角点坐标
cv2.rectangle(img3,pt1,pt2,(255,0,0),2) #绘制直边界矩形
cv2.imshow('Rectangle',img3) #显示结果图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
7.轮廓的旋转矩阵
#test5-12.py:轮廓的旋转矩形
import cv2
import numpy as np
img=cv2.imread('shape4.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #计算轮廓
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓
ret=cv2.minAreaRect(c[0]) #计算最小矩形
#返回值ret是一个三元组,((矩形中心点坐标x,y),(矩形的w,h),矩形的旋转角度)
print("三元组ret:",ret)
rect=cv2.boxPoints(ret) #计算矩形顶点
print("矩形顶点:",rect)
print("rect类型:",type(rect))
rect=np.int0(rect) #转换为整数
cv2.drawContours(img3,[rect],0,(255,0,0),2) #绘制旋转矩形
cv2.imshow('Rectangle',img3) #显示结果图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
8.轮廓的最小外包圆
#test5-13.py:轮廓的最小圆
import cv2
import numpy as np
img=cv2.imread('shape4.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #计算轮廓
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓
(x,y),radius=cv2.minEnclosingCircle(c[0]) #计算可容轮廓的最小外包圆
#(x,y)表示圆心,radius表示半径
center = (int(x),int(y))
radius = int(radius)
cv2.circle(img3,center,radius,(255,0,0),2) #绘制最小圆
cv2.imshow('Circle',img3) #显示结果图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
9.轮廓的拟合椭圆
#test5-14.py:轮廓的拟合椭圆
import cv2
import numpy as np
img=cv2.imread('shape4.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #计算轮廓
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓
ellipse = cv2.fitEllipse(c[0]) #计算拟合椭圆
print(ellipse)
cv2.ellipse(img3,ellipse,(255,0,0),2) #绘制拟合椭圆
cv2.imshow('ellipse',img3) #显示结果图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
10.轮廓的拟合直线
参考:opencv-python 中直线拟合函数cv.fitLine()的2D直线拟合(适合小白观看)
实验1
#test5-20.py:实验1 执行Canny边缘检测
import cv2
import numpy as np
img=cv2.imread('gate.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
img2=cv2.Canny(img,100,150) #执行边缘检测
cv2.imshow('Canny',img2) #显示结果图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
实验2
#test5-20.py:实验2 查找和绘制轮廓
import cv2
import numpy as np
img=cv2.imread('gate.jpg') #读取图像
cv2.imshow('original',img) #显示原图像
gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY) #转化为灰度图像
ret,img2=cv2.threshold(gray,125,255,cv2.THRESH_BINARY) #二值化阈值处理
c,h=cv2.findContours(img2,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) #查找轮廓
img3=np.zeros(img.shape, np.uint8)+255 #按原图大小创建一幅白色图像
img3=cv2.drawContours(img3,c,-1,(0,0,255),2) #绘制轮廓 -1表示绘制所有轮廓
cv2.imshow('Contours',img3) #显示轮廓图像
cv2.waitKey(0) #按任意键结束等待
cv2.destroyAllWindows() #关闭所有窗口
习题5-1 5-2 5-3
#选择一幅图像,对其执行Laplacian、Sobel、Canny边缘检测
import cv2
img = cv2.imread('bee.jpg')
cv2.imshow('original',img)
#Laplacian边缘检测
img2 = cv2.Laplacian(img,cv2.CV_8U,ksize=1) # ddepth参数可以用-1表示(与原图深度一致)
#CV_8U 数据累心结构:CV_【bit_depth】【U】 U表示无符号
#ksize内核大小设置为1,3,5,7
#Sobel边缘检测
img3=cv2.Sobel(img,cv2.CV_8U,0,1) #边缘检测
#dx和dy指的是求导的阶数,0表示这个方向上没有求导,所填的数一般为0、1、2
#(0表示不求偏导,1表示1阶偏导,2表示2阶偏导)
# dx >= 0 && dy >= 0 && dx+dy > 0
#ksize是Sobel算子的大小,即卷积核的大小,必须为奇数1、3、5、7。如果ksize=-1,就演变成为3x3的Scharr算子,
# scale是缩放导数的比例常数,默认情况为没有伸缩系数。
# borderType是判断图像边界的模式,这个参数默认值为cv2.BORDER_DEFAULT。
img4 = cv2.Canny(img,100,200,apertureSize=3) #边缘检测 100表示的是最低阈值,200表示最高阈值,这两个阈值自定义设置
#注意,这里aperturSize=3表示计算梯度时使用的Sobel算子
cv2.imshow('Laplacian',img2)
cv2.imshow('Sobel',img3)
cv2.imshow('Canny',img4)
cv2.waitKey(0)
提示:这里对文章进行总结: