Fly-AI竞赛服务平台 flyai.com

在开始学习之前推荐大家可以多在FlyAI竞赛服务平台多参加训练和竞赛,以此来提升自己的能力。FlyAI是为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台。每周免费提供项目开源算法样例,支持算法能力变现以及快速的迭代算法模型。

如果需要处理的原图及代码,请移步小编的GitHub地址

传送门:请点击我
  如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice

  形态学操作简单来说,就是改变物体的形状,下面学习一下,首先本文的目录如下:

  • 1,定义结构元素
  • 2,腐蚀和膨胀
  • 3,开运算和闭运算
  • 4,礼帽/顶帽,黑帽算法
  • 5,梯度运算
  • 6,形态学运算 检测边和角点(1,检测边缘 ; 2,检测拐角)

1,定义结构元素

  形态学操作的原理:在特殊领域运算形式——结构元素(Structure Element),在每个像素位置上与二值图像对应的区域进行特定的逻辑运算。运算结构是输出图像的相应像素。运算效果取决于结构元素大小内容以及逻辑运算性质。

  结构元素:膨胀和腐蚀操作的最基本组成部分,用于测试输出图像,通常要比待处理的图像小很多,二维平面结构元素由一个数值为0或1的矩阵组成。结构元素的原点指定了图像中需要处理的像素范围,结构元素中数值为1的点决定结构元素的领域像素进行膨胀或腐蚀操作时是否需要参与计算。

  形态学处理的核心就是定义结构元素,在OpenCV-Python中,可以使用其自带的 getStructuringElement 函数,也可以直接使用 Numpy 的 ndarray 来定义一个结构元素,形象图如下:

  下面代码为上图的十字形,代码如下:

#_*_coding:utf-8_*_import cv2import numpy as npdef show_element():element_cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))print(element_cross)element_ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))print(element_ellipse)element_rect = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))print(element_rect)'''[[0 0 1 0 0][0 0 1 0 0][1 1 1 1 1][0 0 1 0 0][0 0 1 0 0]][[0 0 1 0 0][1 1 1 1 1][1 1 1 1 1][1 1 1 1 1][0 0 1 0 0]][[1 1 1 1 1][1 1 1 1 1][1 1 1 1 1][1 1 1 1 1][1 1 1 1 1]]'''def define_cross_structure():NpKernel = np.uint8(np.zeros((5, 5)))for i in range(5):NpKernel[2, i] = 1NpKernel[i, 2] = 1print("NpKernel", NpKernel)'''NpKernel [[0 0 1 0 0][0 0 1 0 0][1 1 1 1 1][0 0 1 0 0][0 0 1 0 0]]'''

  上面我们自定义了一个结构元素 kernel,先声明一个矩阵,然后对其进行赋值,这种方法灵活但是略显复杂。OpenCV提供了一个函数 也就是上面展示的,可以获取常用结构元素的性质:矩形(包括线形),椭圆(包括圆形)以及十字形。下面具体学习一下此方法

1.1 定义一些基本符号和关系

1,元素

  设有一幅图像X,若点 a 在 X 的区域以内,则称 a 为 X 的元素,记做 a 属于 X,如图 6.1所示。

2,B包含于X

  设有两幅图像 B, X。对于 B中所有的元素 ai, 都有 ai 属于 X,则称B包含于 (included in)X ,记做 B 属于 X,如图6.2所示。

3,B击中 X

  设有两幅图像B, X。若存在这一一个点,它即是B的元素,又是 X 的元素,则称 B 击中(hit)X,记做 B ↑ X,如图6.3所示。

4,B不击中 X

  设有两幅图像B, X。若不存在任何一个点,它既是B的元素,又是 X的元素,即 B和 X的交集是空,则称 B 不击中(miss)X,记做 B ∩ X = Φ;其中 ∩ 是集合运算相交的符号,Φ 表示空集,如图6.4所示。

5,补集

  设有一幅图像 X,所有 X 区域以外的点构成的集合称为 X 的补集,记做 Xc,如下图所示。显然,如果B ∩ X = Φ,则 B 在 X的补集内,即 B 属于 Xc。

6,结构元素

  设有两幅图像B,X。若X是被处理的对象,而B是用来处理X的,则称B为结构元素(structure element),又被形象的称作刷子。结构元素通常都是一些比较小的图像。

7,对称集

  设有一幅图像B,将B中所有元素的坐标取反,即令(x, y)变为(-x, -y),所有这些点构成的新的集合称为B的对称集,记做 Bv,如下图6.6所示。

8,平移

  设有一幅图像B,有一个点a(x0, y0),将B平移a后的结果是,把B中所有元素的横坐标加 x0,纵坐标加 y0,即令(x, y)变成(x + x0, y+y0),所有这些点构成新的集合称为B的平移,记做 Ba,如图6.7所示。

1.2 getStructuringElement 方法

  getStructuringElement 是OpenCV提供的一个函数,getStructuringElement 的内部并没有什么优化实现,只是封装了一些功能,其原理同样是声明了一个矩阵,然后求形状,指定矩阵的值。而我们只需要直接调用即可。

  函数原型如下:

def getStructuringElement(shape, ksize, anchor=None):

  参数的意思:

  • shape 表示内核的形状,有三种形状可以选择:

    ——十字形:cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))

    ——椭圆:cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))

    ——矩形:cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

  • ksize 表示内核的尺寸(n, n)
  • anchor 锚点的位置

  此函数最终会返回指定形状和尺寸的结构元素。

  下面代码实现一下,这里同时展示一下自己写的:

kernel1 = np.ones((3, 3), np.uint8)kernel2 = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))print(kernel1)print(kernel2)print(kernel1 == kernel2)'''[[1 1 1][1 1 1][1 1 1]][[1 1 1][1 1 1][1 1 1]][[ True  True  True][ True  True  True][ True  True  True]]'''

  这里其实再证明一次。

2,腐蚀和膨胀

  图像的膨胀(Dilation)和腐蚀(Erosion)是两种基本的形态学运算,主要用来寻找图像中的极大区域和极小区域。其中膨胀类似于“领域扩张”,将图像中的高亮区域或白色部分进行扩张,其运行结果图比原图的高亮区域更大;腐蚀类似于“领域被蚕食”,将图像中的高亮区域或白色部分进行缩减细化,其运行结果图比原图的高亮区域更小。

  形态学各种功能实现,都归结为腐蚀 erode 和 膨胀 dilate 的组合,形象理解一下就是腐蚀等于变瘦,膨胀等于变胖,所以下面学习一下腐蚀和膨胀。

注意:腐蚀和膨胀主要针对二值化图像的白色部分。

2.1 腐蚀

  腐蚀就是把结构元素B平移a后得到Ba,若Ba包含于X,我们记下这个a点,所有满足上述条件的 a点组成的集合称为X被B腐蚀(Erosion)的结果。

  上图 X 是被处理的对象,B是结构元素,不难知道,对于任意一个在阴影部分的点 a,Ba包含于X,所以 X被B腐蚀的结果就是那个阴影部分,阴影部分在 X的范围之内,且比 X小,就像 X 被剥掉了一层似的,这0就是为什么叫腐蚀的原因。

  腐蚀的运算符为 “ - ”,其定义如下:

  该公式表示图像A用卷积模板B来进行腐蚀处理,通过模板B与图像A进行卷积计算,得到B覆盖区域的像素点最小值,并用这个最小值来替代参考点的像素值。如图所示,将左边的原始图像A腐蚀处理为右边的效果图A-B。

腐蚀:腐蚀会把物体的边界腐蚀掉,卷积核沿着图像滑动,如果卷积核对应的原图的所有像素值为1,那么中心元素就保持原来的值,否则变为零。主要应用在去除白噪声,也可以断开连在一起的物体。

  在原图的每一个区域中取最小值,由于是二值化图像,只要有一个点为0,则为0,来达到瘦身的目的。

腐蚀的作用:

  • 1,对象大小减少1个像素(3*3)
  • 2,平滑对象边缘
  • 3,弱化或者分割图像之间的半岛型连接

2.2 膨胀(Dilate)

  膨胀可以看做是腐蚀的对偶运算,其定义是:把结构元素B平移 a 后得到 Ba,若Ba击中X,我们记下这个 a 点。所有满足上述条件的 a点组成的集合称为 X被B膨胀的结果。

  膨胀的方法是:拿B的中心点和X上的点及X周围的点一个一个的对,如果B上有一个点落在X的范围内,则该点为黑,可以看出X的范围就像X膨胀一圈似的。

  图像膨胀的运算符是“⊕”,其定义如下:

  这个公式表示用B来对图像A进行膨胀处理,其中B是一个卷积模板或卷积核,其形状可以为正方形或圆形,通过模板B与图像A进行卷及计算,扫描图像中的每一个像素点,用模板元素与二值图像元素做“与”运算,如果都为0,那么目标像素点为0,否则为1。从而计算B覆盖区域的像素点最大值,并用该值替换参考点的像素值实现膨胀。下图是将左边的原始图像A膨胀处理为右边的效果图 A⊕B。

膨胀:卷积核所对应的原图像的像素值只要有一个是1,中心像素值就是1.一般在除噪声,先腐蚀再膨胀,因为腐蚀在去除白噪声的时候也会使图像缩小,所以我们之后要进行膨胀。当然也可以用来将两者物体分开。

膨胀的作用:

  • 1,对象大小增加一个像素 (3*3)
  • 2,平滑对象边缘
  • 3,减少或者填充对象之间的距离

2.3 代码展示

  代码如下:

import cv2import numpy as npdef erode_image(img_path):origin_img = cv2.imread(img_path)gray_img = cv2.cvtColor(origin_img, cv2.COLOR_BGR2GRAY)# OpenCV定义的结构元素kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))# 腐蚀图像eroded = cv2.erode(gray_img, kernel)# 显示腐蚀后的图像cv2.imshow('Origin', origin_img)cv2.imshow('Erode', eroded)cv2.waitKey(0)cv2.destroyAllWindows()def dilate_image(img_path):origin_img = cv2.imread(img_path)gray_img = cv2.cvtColor(origin_img, cv2.COLOR_BGR2GRAY)# OpenCV定义的结构元素kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))# 膨胀图像dilated = cv2.dilate(gray_img, kernel)# 显示腐蚀后的图像cv2.imshow('Dilate', dilated)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':img_path = 'origin.jpg'erode_image(img_path)dilate_image(img_path)

  如上所示,腐蚀和膨胀的处理很简单,只需设置好结构元素,然后分别调用 cv2.erode() 和 cv2.dilate()函数,其中第一个参数为需要处理的图像,第二个是结构元素,返回处理好的图像。

  下图从左到右依次是 原图,腐蚀,膨胀(我们可以看出腐蚀是将线条变瘦,膨胀是变胖):

2.4 腐蚀和膨胀的知识点补充

  1,可以看做膨胀是将白色区域扩大,腐蚀是将黑色区域扩大。

  2,可以不进行灰度处理,对彩色图像进行处理

腐蚀cv2.erode(src,                     # 输入图像kernel,                  # 卷积核dst=None,anchor=None,iterations=None,         # 迭代次数,默认1borderType=None,borderValue=None)膨胀cv2.dilate(src,                    # 输入图像kernel,                 # 卷积核dst=None,anchor=None,iterations=None,        # 迭代次数,默认1borderType=None,borderValue=None)

3,开运算和闭运算

  开运算和闭运算就是将腐蚀和膨胀按照一定的次序进行处理。但是这两者并不是可逆的,即先开后闭并不能得到原来的图像。

  为了获取图像中的主要对象:对一幅二值图连续使用闭运算和开运算,或者消除图像中的噪声,也可以对图像先用开运算后用闭运算,不过这样也会消除一些破碎的对象。

  • 开运算:先腐蚀后膨胀,用于移除由图像噪声形成的斑点
  • 闭运算:先膨胀后腐蚀,用来连接被误分为许多小块的对象

3.1 开运算

  开运算 = 先腐蚀运算,再膨胀运算(看上去把细微连在一起的两块目标分开了)

  开运算的效果图如下图所示:

  开运算总结:

  • (1)开运算能够除去孤立的小点,毛刺和小桥,而总的位置和形状不变。
  • (2)开运算是一个基于几何运算的滤波器
  • (3)结构元素大小的不同将导致滤波效果的不同
  • (4)不同的结构元素的选择导致了不同的分割,即提取出不同的特征。

3.2 闭运算

  闭运算=先膨胀运算,再腐蚀运算(看上去将两个细微连接的图封闭在一起)

  闭运算的效果如下图所示:

  闭运算总结:

  • (1)闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
  • (2)闭运算是通过填充图像的凹角来滤波图像的。
  • (3)结构元素大小的不同将导致滤波效果的不同。
  • (4)不同结构元素的选择导致了不同的分割。

  代码如下:

import cv2import numpy as npdef Open_operation(img_path):origin_img = cv2.imread(img_path)gray_img = cv2.cvtColor(origin_img, cv2.COLOR_BGR2GRAY)# OpenCV定义的结构元素kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 开运算open = cv2.morphologyEx(gray_img, cv2.MORPH_OPEN, kernel)# 显示腐蚀后的图像cv2.imshow('Open', open)cv2.waitKey(0)cv2.destroyAllWindows()def Closed_operation(img_path):origin_img = cv2.imread(img_path)gray_img = cv2.cvtColor(origin_img, cv2.COLOR_BGR2GRAY)# OpenCV定义的结构元素kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 闭运算closed = cv2.morphologyEx(gray_img, cv2.MORPH_CLOSE, kernel)# 显示腐蚀后的图像cv2.imshow('Closed', closed)cv2.waitKey(0)cv2.destroyAllWindows()def show_origin(origin_path):# img = cv2.imread(origin_path, )# 灰度化img = cv2.imread(origin_path, 0)cv2.imshow('origin', img)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':# 此图为加了高斯噪声的图片img_path = 'butterfly_Gaussian.jpg'show_origin(img_path)Closed_operation(img_path)Open_operation(img_path)import cv2import numpy as npdef Open_operation(img_path):origin_img = cv2.imread(img_path)gray_img = cv2.cvtColor(origin_img, cv2.COLOR_BGR2GRAY)# OpenCV定义的结构元素kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 开运算open = cv2.morphologyEx(gray_img, cv2.MORPH_OPEN, kernel)# 显示腐蚀后的图像cv2.imshow('Open', open)cv2.waitKey(0)cv2.destroyAllWindows()def Closed_operation(img_path):origin_img = cv2.imread(img_path)gray_img = cv2.cvtColor(origin_img, cv2.COLOR_BGR2GRAY)# OpenCV定义的结构元素kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))# 闭运算closed = cv2.morphologyEx(gray_img, cv2.MORPH_CLOSE, kernel)# 显示腐蚀后的图像cv2.imshow('Closed', closed)cv2.waitKey(0)cv2.destroyAllWindows()def show_origin(origin_path):# img = cv2.imread(origin_path, )# 灰度化img = cv2.imread(origin_path, 0)cv2.imshow('origin', img)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':# 此图为加了高斯噪声的图片img_path = 'butterfly_Gaussian.jpg'show_origin(img_path)Closed_operation(img_path)Open_operation(img_path)

  效果如下:(分布是原图,开运算的图,闭运算的图)

  闭运算用来连接被误分为许多小块的对象,而开运算用于移除由图像噪声形成的斑点。因此,某些情况下可以连续运用这两种运算。如对一幅二值图连续使用闭运算和开运算,将获得图像中的主要读写。同样,如果想消除图像中噪声(即图像中的“小点”),也可以对图像先用开运算后用闭运算,不过这样也会消除一些破碎的对象。

3.3 开运算和闭运算的知识点补充

  这里主要补充函数原型

 开运算图像开运算主要使用的函数morphologyEx,它是形态学扩展的一组函数,其参数cv2.MORPH_OPEN对应开运算。其原型如下:dst = cv2.morphologyEx(src, cv2.MORPH_OPEN, kernel)参数dst表示处理的结果,src表示原图像,cv2.MORPH_OPEN表示开运算,kernel表示卷积核闭运算图像闭运算主要使用的函数morphologyEx,其原型如下:dst = cv2.morphologyEx(src, cv2.MORPH_CLOSE, kernel)参数dst表示处理的结果,src表示原图像, cv2.MORPH_CLOSE表示闭运算,kernel表示卷积核

4,礼帽/顶帽,黑帽算法

  礼帽 :原始图像与其进行开运算后的图像进行一个差

  黑帽:原始图像与其闭运算后的图像进行一个差

  礼帽运算 = 原始图像 - 开运算

  黑帽运算 = 闭运算 - 原始图像

  代码如下:

import cv2def hat_algorithm(img_path):original_img0 = cv2.imread(img_path)original_img = cv2.imread(img_path, 0)kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 定义矩形结构元素TOPHAT_img = cv2.morphologyEx(original_img, cv2.MORPH_TOPHAT, kernel)  # 顶帽运算BLACKHAT_img = cv2.morphologyEx(original_img, cv2.MORPH_BLACKHAT, kernel)  # 黒帽运算# 显示图像cv2.imshow("original_img0", original_img0)cv2.imshow("original_img", original_img)cv2.imshow("TOPHAT_img", TOPHAT_img)cv2.imshow("BLACKHAT_img", BLACKHAT_img)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':img_path = 'butterfly_Gaussian.jpg'hat_algorithm(img_path)

  效果如下:(依次是原图,灰度图图片(两个类似,是因为我将原图做了灰度化高斯处理,所以灰度化之后和原图类似),顶帽图片,黑帽图片)

  该算法可以用于图像识别的预处理,用于图像二值化后取出孤立点,代码如下:

import cv2def deal_isolated(img_path):original_img = cv2.imread(img_path, 0)gray_img = cv2.resize(original_img, None, fx=0.8, fy=0.8,interpolation=cv2.INTER_CUBIC)  # 图形太大了缩小一点kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))  # 定义矩形结构元素(核大小为3效果好)TOPHAT_img = cv2.morphologyEx(gray_img, cv2.MORPH_TOPHAT, kernel)  # 顶帽运算BLACKHAT_img = cv2.morphologyEx(gray_img, cv2.MORPH_BLACKHAT, kernel)  # 黒帽运算bitwiseXor_gray = cv2.bitwise_xor(gray_img, TOPHAT_img)# 显示如下腐蚀后的图像cv2.imshow("gray_img", gray_img)cv2.imshow("TOPHAT_img", TOPHAT_img)cv2.imshow("BLACKHAT_img", BLACKHAT_img)cv2.imshow("bitwiseXor_gray", bitwiseXor_gray)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':img_path = 'lena.jpg'deal_isolated(img_path)

    可以看出,最后效果更加明显了一些:

5,梯度运算

梯度 = 膨胀 - 腐蚀

  下面看一个示例:

import cv2import numpy as npimport matplotlib.pyplot as pltimg = cv2.imread('circle.jpg')kernel = np.ones((7, 7), np.uint8)# kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (7, 7))erosion = cv2.erode(img, kernel, iterations = 5)dilation = cv2.dilate(img, kernel, iterations = 3)gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)result = [img, erosion, dilation, gradient]titles = ['origin img', 'erosion img', 'dilate img', 'gradient img']for i in range(4):plt.subplot(2, 2, i+1), plt.imshow(result[i])plt.title(titles[i])plt.xticks([]), plt.yticks([])plt.show()

  效果如下:

6,用形态学运算检测边和角点

  这里通过一个较复杂的例子学习如何用形态学算子检测图像中的边缘和拐角(这里只做形态学处理例子,实际使用请参考Canny和Harris等算法:请参考博文:深入学习OpenCV中几种图像边缘检测算子)

6.1 检测边缘

  形态学检测边缘的原理很简单,在膨胀时,图像中的物体会向周围“扩张”;腐蚀时,图像的额物体会“收缩”。比较两幅图像,由于其变化的区域只发生在边缘。所以这时将这两幅图像相减,得到的就是图像中的边缘。这里用的依然是参考资料《Opencv2 Computer Vision Application Programming Cookbook》中相关章节的图片:

  代码如下:

# coding=utf-8import cv2import numpydef detection_edge(img_path):image = cv2.imread(img_path, 0)# 构造一个3×3的结构元素element = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))dilate = cv2.dilate(image, element)erode = cv2.erode(image, element)# 将两幅图像相减获得边,第一个参数是膨胀后的图像,第二个参数是腐蚀后的图像# cv2.absdiff参数:(膨胀后的图像,腐蚀后的图像)result = cv2.absdiff(dilate, erode)# 上面得到的结果是灰度图,将其二值化以便更清楚的观察结果retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY)# 反色,即对二值图每个像素取反result = cv2.bitwise_not(result)# 显示图像cv2.imshow("result", result)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':img_path = "building.jpg"detection_edge(img_path)

  结果如下:

6.2 检测角点(拐角)

  与边缘检测不同,拐角的检测过程稍稍有些复杂。但是原理相同,所不同的是先用十字形的结构元素膨胀像素,这种情况下只会在边缘处“扩张”,角点不发生变化。接着用菱形的结构元素腐蚀原图像,导致只有在拐角处才会“收缩”,而直线边缘都未发生变化。

  第二步是用X行膨胀原图像,焦点膨胀的比边要多。这样第二次用方块腐蚀时,角点恢复原状,而边要腐蚀的更多。所以当两幅图像相减时,只保留了拐角处,示意图如下(示意图来自参考资料《Opencv2 Computer Vision Application Programming Cookbook》):

  代码如下:

# coding=utf-8import cv2import numpydef detection_inflexion(img_path):image = cv2.imread(img_path, 0)origin = cv2.imread(img_path)# 构造5×5的结构元素,分别为十字形、菱形、方形和X型cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))# 菱形结构元素的定义稍麻烦一些diamond = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))diamond[0, 0] = 0diamond[0, 1] = 0diamond[1, 0] = 0diamond[4, 4] = 0diamond[4, 3] = 0diamond[3, 4] = 0diamond[4, 0] = 0diamond[4, 1] = 0diamond[3, 0] = 0diamond[0, 3] = 0diamond[0, 4] = 0diamond[1, 4] = 0square = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))x = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))# 使用cross膨胀图像dilate_cross_img = cv2.dilate(image, cross)# 使用菱形腐蚀图像erode_diamond_img = cv2.erode(dilate_cross_img, diamond)# 使用X膨胀原图像dilate_x_img = cv2.dilate(image, x)# 使用方形腐蚀图像erode_square_img = cv2.erode(dilate_x_img, square)# result = result1.copy()# 将两幅闭运算的图像相减获得角result = cv2.absdiff(erode_square_img, erode_diamond_img)# 使用阈值获得二值图retval, result = cv2.threshold(result, 40, 255, cv2.THRESH_BINARY)# 在原图上用半径为5的圆圈将点标出。for j in range(result.size):y = int(j / result.shape[0])x = int(j % result.shape[0])if result[x, y] == 255:cv2.circle(image, (y, x), 5, (255, 0, 0))cv2.imshow("Result", image)cv2.waitKey(0)cv2.destroyAllWindows()if __name__ == '__main__':img_path = "building.jpg"detection_inflexion(img_path)

  通过上面的代码就能检测出图像的拐角并标出来,效果如下:

  当然这个只是一个示例,效果不是很好。

参考文献:https://www.cnblogs.com/ssyfj/p/9276999.htmlhttps://blog.csdn.net/wsp_1138886114/article/details/82917661https://blog.csdn.net/JohinieLi/article/details/81041276https://blog.csdn.net/hanshanbuleng/article/details/80657148
1、《Opencv2 Computer Vision Application Programming Cookbook》
2、《OpenCV References Manule》
最初的来源: https://blog.csdn.net/sunny2038/article/details/9137759https://blog.csdn.net/gbxvip/article/details/50844007


更多精彩内容请访问FlyAI-AI竞赛服务平台;为AI开发者提供数据竞赛并支持GPU离线训练的一站式服务平台;每周免费提供项目开源算法样例,支持算法能力变现以及快速的迭代算法模型。

挑战者,都在FlyAI!!!

开运算和闭运算_OpenCV计算机视觉学习(5)——形态学处理(腐蚀膨胀,开闭运算,礼帽黑帽,边缘检测)...相关推荐

  1. Halcon中的基于区域的形态学处理(腐蚀膨胀开闭预算顶底帽运算)

    形态学处理的作用: 用于提取有意义的局部图像细节,通过改变局部区域的像素形态,对图像进行增强,为后续分割.特征提取.边缘检测做准备. 在开始之前,我们先了解一下:结构元素:StructElement ...

  2. 【opencv】(4) 形态学处理:腐蚀膨胀、梯度运算、礼帽黑帽

    各位同学好,今天和大家分享一下图像的形态学处理方法.内容有: 膨胀腐蚀.开运算和闭运算.梯度运算.礼帽和黑帽 (1)腐蚀:cv2.erode():(2)膨胀:cv2.dilate():(3)形态学函数 ...

  3. 礼帽黑帽操作,开闭运算

    开运算=先腐蚀再膨胀=去除毛刺,去除多余杂纹 闭运算=先膨胀再腐蚀=加强杂纹 礼帽=原始输入减去开运算=保留杂纹 黑帽=闭运算减去原始输入=保留加强杂纹

  4. c语言位运算负数的实例_0基础学习C语言第三章:位运算

    C语言提供了六种位运算符: & 按位与 | 按位或 ^ 按位异或 ~ 取反 << 左移,相当与*2 >> 右移,正数高位补0,负数由计算机决定 循环左移k次 (x< ...

  5. opencv 开操作-闭操作 礼帽-黑帽作用

    1.开操作与闭操作  开操作:先腐蚀再膨胀   作用:消除图像中纤细的部分  闭操作:先膨胀再腐蚀   作用:消除一些孔洞 2.礼帽与黑帽  礼帽(顶帽):=原始图像-开运算后的图像   作用:得到噪 ...

  6. 掩膜区域内像素值_OpenCV计算机视觉学习(2)——图像算术运算 图像阈值(数值计算,掩膜mask操作,边界填充,二值化)...

    如果需要处理的原图及代码,请移步小编的GitHub地址 传送门:请点击我 如果点击有误:https://github.com/LeBron-Jian/ComputerVisionPractice 在O ...

  7. 【学习笔记】opencv的python接口 形态学操作 腐蚀 膨胀 通用形态学函数

    腐蚀 img=np.zeros((5,5),np.uint8) img[1:4,1:4]=1 kernel=np.ones((3,1),np.uint8) erosion=cv2.erode(img, ...

  8. 【OpenCV入门教程之十一】 形态学图像处理(二):开运算、闭运算、形态学梯度、顶帽、黑帽合辑

    本系列文章由@浅墨_毛星云 出品,转载请注明出处. 文章链接: http://blog.csdn.net/poem_qianmo/article/details/23184547 作者:毛星云(浅墨) ...

  9. OpenCV与图像处理学习六——图像形态学操作:腐蚀、膨胀、开、闭运算、形态学梯度、顶帽和黑帽

    OpenCV与图像处理学习六--图像形态学操作:腐蚀.膨胀.开.闭运算.形态学梯度.顶帽和黑帽 四.图像形态学操作 4.1 腐蚀和膨胀 4.1.1 图像腐蚀 4.1.2 图像膨胀 4.2 开运算与闭运 ...

最新文章

  1. nodeType 节点简介
  2. 程序员如何让自己的程序少出BUG- [工作]
  3. SilverLight学习笔记--建立Silverlight自定义控件(5)--绑定动画效果
  4. Android记录一个setTextColor常见的一个bug
  5. 离散数学复习命题公式的范式
  6. abd.exe 需要下java吗_Abd.exe文件下载|
  7. 【每日SQL打卡】​​​​​​​​​​​​​​​DAY 27丨列出指定时间段内所有的下单产品【难度简单】​
  8. JSK-390 计负均正【入门】
  9. 统计学中RR OR AR HR的区别
  10. Qt编写输入法终极版V2018
  11. 在实战中学习项目管理 --专栏《项目管理实战20讲》学习总结
  12. 研究生课程笔记:软件包在流行病学中的应用(一)——PASS软件
  13. 对话系统最新综述II
  14. 网站SEO优化中tilte与h1的区别、b与strong的区别、i与em的区别
  15. 企业为什么要建立档案管理?具体如何实现?
  16. 腾讯会议怎么录屏?几个步骤轻松录屏
  17. 让新股抢跑 -- 富途证券上线港股暗盘交易功能
  18. 基金亏损84万,小灰反手把银行客户经理投诉了
  19. 树莓派安装安装fcitx及google拼音输入法
  20. 【推荐+转摘】如何又快又好的做出一份优质PPT

热门文章

  1. 关于C++,Java和Python中的随机数生成法
  2. 主定理(master theorem)学习小记
  3. nginx系列之四:web服务器
  4. 反汇编RETN 0x0c的理解
  5. 【网络编程】之一、初识WinSocket
  6. 从零开始玩转JMX(三)——Model MBean
  7. Java 程序优化:字符串操作、基本运算方法等优化策略
  8. 【线上分享】RTC在传统流媒体行业的应用实践
  9. 堡垒之夜一年内增1亿玩家、YouTube为支持AV1的8K电视提供8K内容、Elon Musk要过极简生活等...
  10. 走进武汉,探索多媒体开发最佳实践