• 《计算机视觉技术与应用》-----第五章 边缘和轮廓


    系列文章目录

    《计算机视觉技术与应用》-----第二章 图像处理基础

    《计算机视觉技术与应用》-----第三章 图形用户界面

    《计算机视觉技术与应用》-----第四章 图像变换

    《计算机视觉技术与应用》-----第五章 边缘和轮廓

    《计算机视觉技术与应用》-----第六章 边缘和轮廓

    《计算机视觉技术与应用》-----第七章 边缘和轮廓

    《计算机视觉技术与应用》----- 重点复盘


    前言

    提示:这里可以添加本文要记录的大概内容:

    例如:随着人工智能的不断发展,机器学习这门技术也越来越重要,很多人都开启了学习机器学习,本文就介绍了机器学习的基础内容。


    一、Laplacian边缘检测

    在这里插入图片描述

    #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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在这里插入图片描述

    opencv:边缘检测之Laplacian算子思想及实现
    Opencv学习——边缘检测(Laplacian)

    二、Sobel边缘检测

    在这里插入图片描述

    #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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    OpenCV——Sobel边缘检测

    三、Canny边缘检测

    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)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    应用双阈值确定边缘
    完成上述步骤后,图像内的强边缘已经在当前获取的边缘图像内。但是,一些虚边缘可能也在边缘图像内。这些虚边缘可能是真实图像产生的,也可能是由于噪声所产生的。对于后者,必须将其剔除。
    设置两个阈值,其中一个为高阈值 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)                                            
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    在这里插入图片描述
    参考: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
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    六、轮廓特征

    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()                         #关闭所有窗口
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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)          #输出轮廓面积
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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)                  #输出轮廓长度
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    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()                         #关闭所有窗口
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    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()                             #关闭所有窗口
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    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()                             	#关闭所有窗口
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    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()                             		#关闭所有窗口
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    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()                             		#关闭所有窗口
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    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()                             		#关闭所有窗口
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    10.轮廓的拟合直线
    在这里插入图片描述
    参考:opencv-python 中直线拟合函数cv.fitLine()的2D直线拟合(适合小白观看)

    5.3 霍夫变换

    在这里插入图片描述

    5.4 实验

    实验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()                                 #关闭所有窗口
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    实验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()                         		#关闭所有窗口
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    习题

    习题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)
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    总结

    提示:这里对文章进行总结:

    1. Laplacian和Sobel边缘检测:ksize是算子的大小,必须为1、3、5、7。默认为1 用于计算二阶导数的滤波器的孔径尺寸,大小必须为正奇数(正奇数才能有中心点)
    2. 数据类型结构: CV_ 【bit_depth】【S/U/F】【C】CV_8U - 8位无符号整数(0…255)
    3. Sobel边缘检测中:dx和dy指的是求导的阶数,0表示这个方向上没有求导,所填的数一般为0、1、2(dx >= 0 && dy >= 0 && dx+dy > 0)
    4. Canny边缘检测中:其中一个为高阈值 maxVal,另一个为低阈值 minVal。
  • 相关阅读:
    第六节:如何解决@ComponentScan只能扫描当前包及子包(自学Spring boot 3.x的第一天)
    React项目使用craco(由create-react-app创建项目)
    【Flowable】Flowable自动生成的数据库表的含义
    CADD课程学习(5)-- 构建靶点已知的化合结构(ChemDraw)
    操作系统4小时速成:进程管理占考试40%,进程状态,组织,通信,线程拥有调度,进程拥有资源,进程和线程的区别
    --对列--
    【Linux 操作系统】I /O输入与输出
    HTML5期末大作业——HTML+CSS+JavaScript平遥古城旅游景点介绍(6页)
    Python爬虫脚本的基本组成
    深入理解计算机网络-2计算机网络概述
  • 原文地址:https://blog.csdn.net/xiaoren886/article/details/127930809