图像处理-007形态变换(二)

Hit-and-Miss Transform(击中击不中)

Hit-and-Miss从二值图像中查找前景色/背景色的特定模式非常有用,与腐蚀,膨胀使用的kernel仅存在0,1不同,hit-and-Misss的kernel中除0,1外还存在空白。腐蚀,膨胀,开操作,闭操作,形态学梯度,顶帽,黑帽运算使用的kernel中1用来表示前景色,0表示不关注, 在hit-and-miss运算中的1表示前景色,0表示背景色,空白表示不关注。

以图006-14中展示的kernel为例,该kernel可用来找到二值图像中的角点,运算时将kernel置于图像之上,锚点依次与图像中的坐标P对应,P的邻域元素依次与kernel的邻域元素比较,除去kernel中的空白元素外,其余元素完全匹配时则P标记为1,否则为0.

图007-1 查找图像角点的kernel

使用图007-2中的kernel找出图像中的四个角点如图007-3所示

图007-2 寻找图像四角点的kernel

图007-3 二值图像Hit-And-Miss运算结果图

实现代码: C++

/*** hit and miss* @param img* @return*/
int Morphological::hit_and_miss_transform(const Mat &img) {logger_info("======hit_and_miss_transform=====================");//  kernel size为7*7Mat kernel = getStructuringElement(MORPH_ELLIPSE, Size(7, 7));Mat dst;morphologyEx(img, dst, MORPH_HITMISS, kernel);imshow("hit_and_miss", dst);return EXIT_SUCCESS;
}

实现代码:python

# hit and miss
def hit_and_miss_transform(origin_img):# 非灰度图像转化维灰度图像if origin_img.shape[2] == 3:gray_image = cv.cvtColor(origin_img, cv.COLOR_BGR2GRAY)else:gray_image = origin_imgtitles = ["origin_image"]images = [cv.cvtColor(gray_image, cv.COLOR_BGR2RGB)]for i in range(3, 13, 2):kernel = cv.getStructuringElement(cv.MORPH_RECT, (i, i))dst = cv.morphologyEx(gray_image, cv.MORPH_HITMISS, kernel)titles.append("hit_and_miss_kernel_" + str(i))images.append(cv.cvtColor(dst, cv.COLOR_BGR2RGB))for i in range(6):plt.subplot(2, 3, i + 1)plt.imshow(images[i], 'gray', vmin=0, vmax=255)plt.title(titles[i])plt.xticks([]), plt.yticks([])plt.show()

图007-4 二值图像不同kernel大小下hit-and-miss效果图

Thining(细化)

细化会删除二值图像中选定的前景(白色)像素,类似于腐蚀、开操作,删除不必要的像素点,仅保留图像的轮廓。

dst=thining(src,element)=src−hit-and-miss(src,element)\texttt{dst} = \mathrm{thining} ( \texttt{src} , \texttt{element} )= \texttt{src} - \texttt{hit-and-miss} ( \texttt{src} , \texttt{element} ) dst=thining(src,element)=src−hit-and-miss(src,element)

图像细化后依然保持图像的骨架且细小部分的连通性不变,细化将图像线条从多像素宽度减少至单位像素宽度。

opencv提供函数thinning() 用于图像的细化。其详细描述如下:

void cv::ximgproc::thinning(InputArray     src,    #输入图像 8bit单通道灰度图像OutputArray     dst, #输出图像 与输入图像同类型,同大小int     thinningType = THINNING_ZHANGSUEN #细化类型)
Python:
cv.ximgproc.thinning(src[, dst[, thinningType]]    )->dst

实现代码: C++

/*** 图像细化 THINNING_ZHANGSUEN* @param img* @return*/
int Morphological::thinning_ZHANGSUEN_transform(const Mat &img) {logger_info("======hit_and_miss_transform=====================");Mat dst;ximgproc::thinning(img, dst, ximgproc::ThinningTypes::THINNING_ZHANGSUEN);imshow("thinning zhangsuen", dst);return EXIT_SUCCESS;
}/*** 图像细化 THINNING_GUOHALL* @param img* @return*/
int Morphological::thinning_GUOHALL_transform(const Mat &img) {logger_info("======thinning_GUOHALL_transform=====================");Mat dst;ximgproc::thinning(img, dst, ximgproc::ThinningTypes::THINNING_GUOHALL);imshow("thinning guohall", dst);return EXIT_SUCCESS;
}

实现代码: python

# thinning
def thinning_transform(origin_img):# 非灰度图像转化维灰度图像if origin_img.shape[2] == 3:gray_image = cv.cvtColor(origin_img, cv.COLOR_BGR2GRAY)else:gray_image = origin_imgtitles = ["origin_image"]# images = [cv.cvtColor(gray_image, cv.COLOR_BGR2RGB)]images = [gray_image]dst = cv.ximgproc.thinning(gray_image, cv.ximgproc.THINNING_ZHANGSUEN)images.append(dst)titles.append("thinning_zhangsuen")dst = cv.ximgproc.thinning(gray_image, cv.ximgproc.THINNING_GUOHALL)images.append(dst)titles.append("thinning_gauhall")for i in range(3):plt.subplot(1, 3, i + 1)plt.imshow(images[i], 'gray', vmin=0, vmax=255)plt.title(titles[i])plt.xticks([]), plt.yticks([])plt.show()

细化效果图如图007-5所示

图007-5 图像细化效果图

Thickening(粗化)

粗化是形态学的相对操作,细化前景色相当于粗化背景色。粗化操作由源图像与hit-and-miss处理后的并集组成。

dst=thining(src,element)=src∪hit-and-miss(src,element)\texttt{dst} = \mathrm{thining} ( \texttt{src} , \texttt{element} )= \texttt{src} \cup \texttt{hit-and-miss} ( \texttt{src} , \texttt{element} ) dst=thining(src,element)=src∪hit-and-miss(src,element)

Skeletonization/Medial Axis Transform

骨架化指将二值图像的前景色(高亮部分)减少直至骨架的过程,该过程丢弃原始图像中大量的前景像素,但保留了图像的原始区域范围与连通性。

骨架化后的图像既然保留了原始图像的骨架及连通性,则在视觉处理中可大幅减少数据量的计算和对内存的占用。

实现代码: C++

/*** 骨架* @param img* @return*/
int Morphological::skeleton_transform(const Mat &img) {logger_info("======skeleton_transform=====================");imshow("image", img);Mat dst;
//  图像阈值转化  灰度图像转二值图像threshold(img, dst, 127, 255, THRESH_BINARY);
// 卷积核Mat kernel = getStructuringElement(MORPH_CROSS, Size(7, 7));Mat skel(dst.size(), CV_8UC1, cv::Scalar(0));Mat temp(dst.size(), CV_8UC1);bool done;do {cv::morphologyEx(dst, temp, MORPH_OPEN, kernel);cv::bitwise_not(temp, temp);cv::bitwise_and(dst, temp, temp);cv::bitwise_or(skel, temp, skel);cv::erode(dst, dst, kernel);double max;cv::minMaxLoc(dst, 0, &max);done = (max == 0);} while (!done);imshow("skeleton", skel);return EXIT_SUCCESS;
}

实现代码:python


# 骨架化
def skeleton_transform(origin_img):# 非灰度图像转化维灰度图像if origin_img.shape[2] == 3:gray_image = cv.cvtColor(origin_img, cv.COLOR_BGR2GRAY)else:gray_image = origin_imgtitles = ["origin_image"]images = [gray_image]ret, binary_img = cv.threshold(gray_image, 127, 255, cv.THRESH_BINARY)titles.append("binary_image")images.append(binary_img)# 获取卷积核kernel = cv.getStructuringElement(cv.MORPH_CROSS, (7, 7))skeleton_img = np.zeros(binary_img.shape, np.uint8)# tmp_img = np.zeros(binary_img.shape, np.uint8)while True:# 开运算tmp_img = cv.morphologyEx(binary_img, cv.MORPH_OPEN, kernel)tmp_img = cv.bitwise_not(tmp_img)tmp_img = cv.bitwise_and(binary_img, tmp_img)skeleton_img = cv.bitwise_or(skeleton_img, binary_img)binary_img = cv.erode(binary_img, kernel)min, max, _, _ = cv.minMaxLoc(binary_img)if max == 0:breaktitles.append("skeleton_image")images.append(skeleton_img)for i in range(3):plt.subplot(1, 3, i + 1)plt.imshow(images[i], 'gray', vmin=0, vmax=255)plt.title(titles[i])plt.xticks(), plt.yticks([])plt.show()

参考文献:

  1. https://homepages.inf.ed.ac.uk/rbf/HIPR2/morops.htm

  2. http://www.cs.cmu.edu/~cil/vision.html

  3. https://docs.opencv.org/4.6.0/db/d06/tutorial_hitOrMiss.html

  4. https://felix.abecassis.me/2011/09/opencv-morphological-skeleton/

图像处理-007形态变换(二)相关推荐

  1. 数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法

    数字图像处理学习笔记(二):SIFT(尺度不变特征变换)算法 一.概述: 提到特征点算法,首先就是大名鼎鼎的SIFT算法了.SIFT的全称是Scale Invariant Feature Transf ...

  2. OpenCV-Python击中击不中HITMISS形态变换详解

    ☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一.引言 从学习完黑帽变换后的这段时间,都在学习和钻研基本形态变换的最后一个变换–击中击不 ...

  3. OpenCV-Python图像形态变换概述及morphologyEx函数介绍

    ☞ ░ 前往老猿Python博客 https://blog.csdn.net/LaoYuanPython ░ 一.形态变换概念 图像形态变换又称为形态学图像处理.图像形态学,它是基于数学形态学(Mat ...

  4. 9.2.3 Python图像处理之图像数学形态学-二值形态学应用-区域填充

    9.2.3 Python图像处理之图像数学形态学-二值形态学应用-区域填充 文章目录 9.2.3 Python图像处理之图像数学形态学-二值形态学应用-区域填充 1 算法原理 2 代码 3 效果 1 ...

  5. 9.2.2 Python图像处理之图像数学形态学-二值形态学应用-目标检测

    9.2.2 Python图像处理之图像数学形态学-二值形态学应用-目标检测(击中与击不中) 文章目录 9.2.2 Python图像处理之图像数学形态学-二值形态学应用-目标检测(击中与击不中) 1 算 ...

  6. 图像处理学习笔记(二)

    图像处理学习笔记(二) 4 OpenCV图像处理: 4.2 形态学操作: 4.2.1 连通性: 4.2.1 腐蚀和膨胀: 4.2.2 开闭运算: 4.2.3 礼帽和黑帽: 4.2.4 形态学操作总结: ...

  7. OpenCV-Python形态变换、图像金字塔、轮廓属性、直方图

    OpenCV基础 1. Morphological Transformations(形态变换) 2. Image Pyramids(图像金字塔) 3. Contours(轮廓) 4. 轮廓的特性进阶 ...

  8. python 简单图像处理(13) 二值图腐蚀和膨胀,开运算、闭运算

    原文:http://www.cnblogs.com/xianglan/archive/2010/12/29/1921211.html python 简单图像处理(13) 二值图腐蚀和膨胀,开运算.闭运 ...

  9. OpenCV图像处理基础(变换和去噪)

    OpenCV图像处理基础(变换和去噪) 基础知识 使用OpenCV读取图片 图像变换 仿射变换 图像缩放 图像旋转 图像平移 图像裁剪 图像翻转 亮度与对比度变换 图像去噪 高斯噪声 椒盐噪声 中值和 ...

最新文章

  1. 带monkey的测流量!
  2. oracle 删除补全日志组_【REDO】删除REDO LOG重做日志组后需要手工删除对应的日志文件(转)...
  3. es每次结果不一样_电子血压计不准!每次测血压都不一样……
  4. 用Tableau画幂函数柱状图
  5. 剑指offer之和为s的数组
  6. zookeeper出现Error contacting service. It is probably not running.
  7. 单片机人流统计装置的程序_单片机其实不难
  8. 笔试 - 高德软件有限公司python问题 和 答案
  9. 二叉树前序遍历_LeetCode125|二叉树的前序遍历
  10. matlab chirp函数模糊函数,8个OFDM-Chirp波形的时频域图及自(互)模糊函数图
  11. 第二章 Java浮点数精确计算
  12. android7.0+关闭wifi连接CA验证
  13. [转]架构师的职责及工作描述
  14. webuploader 手机端上传图片默认打开相机 改为选择相册
  15. 2021年中国化妆品发展现状及进出口状况分析:消费升级局面下,化妆品市场依旧景气 [图]
  16. 怎么调整图片大小会不变形?
  17. 【考试题解】 递归递推
  18. 一起来看流星雨剧情简介/剧情介绍/剧情分集介绍第四集
  19. 基于stm32单片机单相用电器分析电流电压功率因子监测装置
  20. C++ Primer 18 用于大型程序的工具

热门文章

  1. 基于小波分析和机器学习的时间序列分析与识别
  2. 痔疮最佳治疗方法 十人九痔 不必害羞
  3. 拉普拉斯金字塔图像融合原理
  4. 考研数学随笔(2)——微分积分关系,中值定理
  5. 【分析】RBD Mirroring - 原理、概念、命令
  6. DHCP 解决单位网络私接路由器的办法
  7. 解除同居关系时共同财产的分割
  8. 女巫的魔法-第12届蓝桥杯Scratch省赛3真题第2题
  9. Mysql的AUTO_INCREMENT
  10. 终极大招~pycharm自动补全opencv代码提示功能