专栏首页Petrichor的专栏opencv: 形态学 转换(图示+源码)

opencv: 形态学 转换(图示+源码)

综述

OpenCV中的形态学转换操作有七种:腐蚀,膨胀,开运算,闭运算,形态学梯度,礼帽,黑帽。

API参照表

中文名

英文名

api

原理

个人理解

腐蚀

erode

erosion = cv2.erode(src=girl_pic, kernel=kernel)

对滑窗中的像素点按位乘,再从中取最小值点作为输出。可以去浅色噪点

浅色成分被腐蚀

膨胀

dilate

dilation = cv2.dilate(src=girl_pic, kernel=kernel)

对滑窗中的像素点按位乘,再从中取最大值点作为输出。可以增加浅色成分

浅色成分得膨胀

开运算

morphology-open

opening = cv2.morphologyEx(girl_pic, cv2.MORPH_OPEN, kernel)

先腐蚀,后膨胀,去白噪点

先合再开,对浅色成分不利

闭运算

morphology-close

closing = cv2.morphologyEx(girl_pic, cv2.MORPH_CLOSE, kernel)

先膨胀,后腐蚀,去黑噪点

先开再合,浅色成分得势

形态学梯度

morphology-grandient

gradient = cv2.morphologyEx(girl_pic, cv2.MORPH_GRADIENT, kernel)

一幅图像腐蚀与膨胀的区别,可以得到轮廓

数值上解释为:膨胀减去腐蚀

礼帽

tophat

tophat = cv2.morphologyEx(girl_pic, cv2.MORPH_TOPHAT, kernel)

原图像减去开运算的差

数值上解释为:原图像减去开运算

黑帽

blackhat

blackhat = cv2.morphologyEx(girl_pic, cv2.MORPH_BLACKHAT, kernel)

闭运算减去原图像的差

数值上解释为:闭运算减去原图像

实验思路:

  1. 写代码,实现OpenCV 自带的 七种形态学转换操作,并将生成的图片存入 pic 文件夹;
  2. 礼帽生成图 加上 开运算生成图,看看能否得到 原图,并将生成的图片存入 pic 文件夹;
  3. 闭运算生成图 减去 黑帽生成图,看看能否得到 原图,并将生成的图片存入 pic 文件夹;
  4. 如果成功,则验证自己的思路是正确的 。

Demo:

原始图像

(../pic/girl.jpg):

七种形态学转换操作

erode 腐蚀(../pic/erosion.jpg):

dilate 膨胀 (../pic/dilation.jpg):

open 开运算 (../pic/opening.jpg):

close 闭运算 (../pic/closing.jpg):

gradient 形态学梯度 (../pic/gradient.jpg):

tophat 礼帽 (../pic/tophat.jpg):

blackhat 黑帽 (../pic/blackhat.jpg):

通过转换后的图像得到原图像

cv2.add(open, tophat) cv2.add(开运算, 礼帽) (../pic/open_and_tophat.jpg):

close-blackhat 闭运算-黑帽 (../pic/close_subtract_blackhat.jpg):

附上自己写的实验代码:

# -*- coding: utf-8 -*-

import cv2
import numpy as np

girl_pic = cv2.imread('../pic/girl.jpg')

kernel = np.ones((5, 5), np.uint8)

# erode 腐蚀
erosion = cv2.erode(src=girl_pic, kernel=kernel)
cv2.imshow('erosion', erosion)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/erosion.jpg', erosion)

# dilate 膨胀
dilation = cv2.dilate(src=girl_pic, kernel=kernel)
cv2.imshow('dilation', dilation)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/dilation.jpg', dilation)

# open 开运算
opening = cv2.morphologyEx(girl_pic, cv2.MORPH_OPEN, kernel)
cv2.imshow('opening', opening)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/opening.jpg', opening)

# close 闭运算
closing = cv2.morphologyEx(girl_pic, cv2.MORPH_CLOSE, kernel)
cv2.imshow('closing', closing)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/closing.jpg', closing)

# gradient 形态学梯度
gradient = cv2.morphologyEx(girl_pic, cv2.MORPH_GRADIENT, kernel)
cv2.imshow('gradient', gradient)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/gradient.jpg', gradient)

# tophat 礼帽
tophat = cv2.morphologyEx(girl_pic, cv2.MORPH_TOPHAT, kernel)
cv2.imshow('tophat', tophat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/tophat.jpg', tophat)

# blackhat 黑帽
blackhat = cv2.morphologyEx(girl_pic, cv2.MORPH_BLACKHAT, kernel)
cv2.imshow('blackhat', blackhat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/blackhat.jpg', blackhat)

# cv2.add(open, tophat) cv2.add(开运算, 礼帽)
open_and_tophat = cv2.add(opening, tophat)
cv2.imshow('open_and_tophat', open_and_tophat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/open_and_tophat.jpg', open_and_tophat)

# close-blackhat 闭运算-黑帽
close_subtract_blackhat = closing - blackhat
cv2.imshow('close_subtract_blackhat', close_subtract_blackhat)
cv2.waitKey(2000)
cv2.destroyAllWindows()
cv2.imwrite('../pic/close_subtract_blackhat.jpg', close_subtract_blackhat)

实际遇到的问题及解决方法:

一开始设计实验时,用礼帽生成的图像加上开运算生成的图像能够得到原图,用黑帽生成的图像加上闭运算生成的图像却得不到原图,反而得到一张比闭运算图像更浅色的图片(如下):

想了一下,发现了问题所在:书上对黑帽的定义是:

进行闭运算之后得到的图像和原始图像的差

但是却没有说清楚被减数和减数分别是谁。根据闭运算和黑帽的定义,我觉得应该是:

黑帽 = 闭运算 - 原图

即可得:

原图 = 闭运算 - 黑帽

修改代码后进行验证,果然生成了原图像:

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • opencv: 合成视频

    JNingWei
  • opencv: 图像缩放(cv2.resize)

    使用cv2.resize时,参数输入是 宽×高×通道 ,与以往操作不同,需要注意。具体参见opencv: cv2.resize 探究(源码)。

    JNingWei
  • opencv: 旋转图片

    但是不管怎么旋转,该图像的shape始终和原图像一致。这在某种程度上会造成不好的影响。

    JNingWei
  • 计算机视觉 | Python OpenCV 3 使用背景减除进行目标检测

    背景减除(Background Subtraction)是许多基于计算机视觉的任务中的主要预处理步骤。如果我们有完整的静止的背景帧,那么我们可以通过帧差法来计算...

    用户1332428
  • 图像凸性检测函数convexityDefects在Python2.7下使用opencv3.0的问题

    最近在学习Python下的OpenCV,在图像的凸性检测中,发现opencv3.0下的convexityDefects函数对图像的凸性缺陷处理有错误。不知道是o...

    红色石头
  • 镜头的标定与矫正(python)

    原理:https://docs.opencv.org/2.4/doc/tutorials/calib3d/camera_calibration/camera_c...

    thugliu
  • OpenCV 读写视频

    下面是完整的代码,里面额外添加了一些边缘检测,求帧差,镜像,添加文字等功能。(上传的动图像素差是腾讯的锅,压缩得太厉害)

    用户6021899
  • opencv 8 --背景减除 -- BackgroundSubtractorMOG2

    例如顾客统计,使用一个静态摄像头来记录进入和离开房间的人数;或者是交通摄像头,需要提取交通工具的信息等。

    wust小吴
  • 进一步理解指针2:双指针、指针数组和数组指针

    1) 如果int* p,则“1”实际是sizeof(int),也就是p指向的类型大小;

    一见
  • OpenCV 处理中文路径、绘制中文文字的烦恼,这里通通帮你解决!

    在 OpenCV 中,由于编码的缘故,对于中文的处理并不是很友好,比如中文路径的图片读取和写入以及在图片上绘制中文文字等,这几个问题都是笔者经常遇到的,本文列出...

    机器视觉CV

扫码关注云+社区

领取腾讯云代金券