在OpenCV中进行图像预处理

news2024/11/26 15:39:12

今天,我们进一步深入,并处理在图像处理中常用的形态学操作。形态学操作用于提取区域、边缘、形状等。

什么是形态学操作?

形态学操作是在二值图像上进行的。二值图像可能包含许多不完美之处。特别是由一些简单的阈值操作产生的二值图像(如果你对阈值不熟悉,现在不用担心)可能包含许多噪声和畸变。OpenCV库中提供了不同的形态学操作来处理这些噪声和缺陷。

形态学操作生成与原始图像相同形状的图像。形态学操作将结构元素应用于输入图像。结构元素可以是任何形状。在今天的所有形态学操作中,将比较输入图像的每个像素与相邻像素以生成输出图像。

对于不同的形态学操作,比较方式有所不同。我们将详细讨论这一点。

在深入讨论问题之前,这是我们将在本教程中使用的图片:

b49938df5a12b0dabafd3422ca9e0601.jpeg

在这里,我们导入必要的包,将图像读取为数组,并将其转换为二值图像,正如前面提到的,形态学操作应用于二值图像:

import cv2 
import matplotlib.pyplot as plt
#Reading the image to an array
image = cv2.imread('practice.jpg')

#converting it to a binary image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

这是'gray'的样子:

e04c4c03188c8ebe1133a9502967015f.jpeg

我们将使用这个灰度图像来观察形态学操作的工作原理。

在深入示例之前,我想创建一个3x3的内核和一个6x3的内核:

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (6, 3))

我们将在下面的形态学操作中使用这两个内核。如果需要,稍后我们将创建更多的内核。

内核可以是任何形状。你也可以尝试一些其他不同形状的内核,如1x4、4x4、5x5、7x18或更多。根据你的项目,内核的形状和大小可能会产生重大差异。

腐蚀

腐蚀做了它听起来的事情。它侵蚀图像的方式就像水侵蚀河岸一样。在腐蚀操作中,它将一个结构元素从输入图像的左到右、从上到下滑动。如果结构元素内的所有像素都大于0,则保留原始像素值。否则,将像素设置为0。

腐蚀用于去除被视为噪声的小斑点。

以下是腐蚀的语法:

eroded1 = cv2.erode(gray.copy(), kernel, iterations = 1)
cv2.imwrite('erode1.jpg', eroded1)

腐蚀函数cv2.erode()使用图像、结构元素和迭代次数。这里的'iterations'参数是可选的。如果你不提供'iterations'值,它会自动执行一次迭代。

这是'erode1'的样子:

6d3276e00db4babeab5fa6d381afeb9a.jpeg

将其与原始图像进行比较。它已经被腐蚀掉了。此外,原始图像中的其他小元素也被去除了。

在任何OCR(光学字符识别)项目中,我们只想识别字母或数字。但图像中可能还有其他更小的字母和元素,可能会混淆你的算法。腐蚀可以消除这些噪声。

如果我们尝试2或3次迭代,它将被更加腐蚀:

eroded2 = cv2.erode(gray.copy(), kernel, iterations = 2)
cv2.imwrite('erode2.jpg', eroded2)

eroded3 = cv2.erode(gray.copy(), kernel, iterations = 3)
cv2.imwrite('erode3.jpg', eroded3)

这是2次和3次迭代的结果:

86351c8b3a1dce2f269858c48461d3c3.jpeg dc402c6cea47a4478368ce75340be056.jpeg

你可以看到,随着迭代次数的增加,图像变得越来越腐蚀。因此,如果你需要提取粗体并且周围有很多噪声的字母,可以通过侵蚀图像来消除噪声。

膨胀

膨胀与腐蚀的作用恰恰相反。它增加前景,从而有助于连接断裂部分。在膨胀中,如果结构元素中的任何像素大于0,则将像素值设置为白色或255。这里我们使用1和3次迭代进行膨胀,以查看差异并了解其工作原理。

dilated1 = cv2.dilate(gray.copy(), kernel, iterations=1)
cv2.imwrite('dilate1.jpg', dilated1)

dilated3 = cv2.dilate(gray.copy(), kernel, iterations=3)
cv2.imwrite('dilate3.jpg', dilated3)

这是膨胀1次迭代(第二个图像)和3次迭代(第三个图像)的图像。原始灰度图像在顶部。

7773f101794173b34cb95dc51ccc24ba.jpeg 470ab7eb87bb688a530cea829595af14.jpeg 40c79879d2657f80be6edd59d1ea288d.jpeg

如果我们将顶部的原始图像与经过一次膨胀的第二个图像进行比较,会有一些微小的差异,经过3次迭代后,差异变得更加显著。根据你的项目,你可以使用尽可能多的迭代次数。

开运算

开运算也是从图像中去除噪声的另一种方法。它在一次迭代中执行腐蚀后进行膨胀。这里有两个示例,我使用了之前准备好的内核和内核1:

opening1 = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel)
cv2.imwrite('open1.jpg', opening1)

opening2 = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel1)                         )
cv2.imwrite('open2.jpg', opening2)

这里,我将原始图像放在顶部,然后是'opening1'操作的图像,底部是'opening2'操作的图像。

515fca54de04fe95991c2f34af4c328d.jpeg dfdbd7eb91b0bf8f31cd86641849bcac.jpeg afae2e36328c1596f7ade5a91b4a30a8.jpeg

正如你所看到的,在使用3x3内核的中间图片中,左下角的小文本消失了,在使用大小为6x3的kernel1的底部图片中,添加了一个黑色阴影。

闭运算

闭运算与开运算相反。在闭运算中,首先进行膨胀,然后进行腐蚀。

让我们看一些示例:

closing1 = cv2.morphologyEx(gray.copy(), cv2.MORPH_CLOSE, kernel, iterations=1)
cv2.imwrite('close1.jpg', closing1)

closing3 = cv2.morphologyEx(gray.copy(), cv2.MORPH_CLOSE, (3, 3), iterations=3)
cv2.imwrite('close3.jpg', closing3)

与之前一样,我将原始灰度图像放在顶部进行比较,然后是'closing1'和'closing2'的输出图像。

106452f51ae12dd137acf82433e27acd.jpeg 5d457ca431c6f45e786f92c62702a29c.jpeg 8187c8b2a259ba35fa202bd2916ad6fd.jpeg

形态梯度

形态梯度对于检测对象的轮廓非常有用。它可用于边缘检测。基本上,它是膨胀操作和腐蚀操作之间的差异。

这是使用kernel和kernel1的两个示例:

grad1 = cv2.morphologyEx(gray.copy(), cv2.MORPH_GRADIENT, kernel)
cv2.imwrite('grad1.jpg', grad1)

grad2 = cv2.morphologyEx(gray.copy(), cv2.MORPH_GRADIENT, kernel1)
cv2.imwrite('grad3.jpg', grad2)

这是'grad1'和'grad2'的输出图像:

bfc9de4783089336af6117ebdfcdc92e.jpeg 20d0c0b0c3b1e137d3c75e661ea8bf61.jpeg

正如你所看到的,不同形状的内核提供了两种不同类型的输出。

顶帽/白帽

顶帽操作是原始二值图像与开运算之间的差异。当你需要从黑色背景中找到亮区域时,它很有帮助。

对于这个操作,我们将使用不同的输入图像和其他操作:

这是输入图像:

5d49f0c00c10f60e0de6405536c15efb.jpeg

这辆车的车牌比车身更亮。让我们看看如何提取出那个白色区域。和往常一样,我们应该将其转换为灰度图像,并定义两个不同的内核。

image = cv2.imread('car.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (23, 5))

kernel1 = cv2.getStructuringElement(cv2.MORPH_RECT, (35, 8))

我尝试了一些不同形状的内核,然后使用了这两个内核大小。请随意尝试一些其他内核大小并比较结果。

tophat1 = cv2.morphologyEx(gray.copy(), cv2.MORPH_TOPHAT, kernel1)
cv2.imwrite('tophat1.jpg', tophat1)

这是输出图像:

1e1edec5adf7ccb56eeb0a4de6430187.jpeg

看,它检测到了车牌从车身上的亮区域。

黑帽

黑帽操作与顶帽相反。

blackhat1 = cv2.morphologyEx(gray.copy(), cv2.MORPH_BLACKHAT, kernel)
cv2.imwrite('blackhat1.jpg', blackhat1)

这是黑帽操作的输出:

e583e3d65157c62261ba1e75cac3b5c9.jpeg

如果你注意到,它聚焦于车牌上的字母。

经过顶帽操作后,检测到了车牌区域,经过黑帽操作后,突出显示了白色车牌上的黑色字母。

因此,如果我们想要检测车牌上的数字,我们将执行顶帽操作,然后是黑帽操作。

结论

本文试图通过示例解释一些众所周知的形态学操作。在将来的一些文章中,我将使用它们来解决一些实际问题。那将更有趣。

☆ END ☆

如果看到这里,说明你喜欢这篇文章,请转发、点赞。微信搜索「uncle_pn」,欢迎添加小编微信「 woshicver」,每日朋友圈更新一篇高质量博文。

扫描二维码添加小编↓

91422f37ebbb885b720d8dc7f4f62286.jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/740186.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023-07-10 cmake管理的项目中使用vcpkg管理第三方库

一、安装 从Github上克隆Vcpkg仓库然后执行安装命令即可: git clone https://github.com/microsoft/vcpkg .\vcpkg\bootstrap-vcpkg.bat 安装自己需要的第三方库 .\vcpkg\vcpkg install [packages to install] 更多教学可参考: https://learn.microsoft…

kubenetes手动安装V1.22.4

kubenetes手动安装V1.22.4 1、主节点和工作节点需要的组件 提示:为了方便测试请关闭selinux、关闭防火墙、swap. SELinux防火墙的设置: [rootlocalhost]#getenforce Disabled # 修改/etc/selinux/config文件 vim /etc/selinux/config 将SELINUXenfor…

【python】Excel文件的读取操作

测试用例.xlsx文件内容 利用xlrd模块读取文件 import xlrdfilename 测试用例.xlsx # 读取Excel表文件 wb xlrd.open_workbook(filename) # 读取Excel表中的第一个工作表 sheet wb.sheet_by_index(0) # 读取有内容的表格行数 rows sheet.nrows # 读取有内容的表格列数 cols…

嵌入式系统之ADC采样

嵌入式系统往往会有模拟信号的采集,比如模拟传感器温度、压力、流量、速度、光强等模拟量,经过放大整形滤波电路后送给ADC芯片,将电信号转转变成离散的数字量这个过程称之为AD采样,AD采样应用广泛,普遍遵循采样率3倍于…

ES 知识体系

https://www.easyice.cn/archives/367

【力扣算法03】之正则表达式匹配- python

文章目录 问题描述示例 1示例2示例3提示 思路分析代码分析完整代码运行效果及示例代码示例代码1运行结果示例代码2运行结果示例代码3运行结果 完结 问题描述 给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘’ 的正则表达式匹配。 ‘.’ 匹配任意…

企业省时又省力:人工智能电话客服机器人的广泛应用

人工智能技术的崛起正深刻地改变着各个行业,其中之一便是客服领域。过去,人们常常在电话中与生硬的自动语音应答机打交道,这种体验常常令人沮丧。然而,随着人工智能电话客服机器人的广泛应用,企业不仅能够省时又省力&a…

MYSQL数据库系统期末试题及参考答案(2)

期末试题 : 一,创建数据库Game 二,数据表操作 1、创建表格players,记录游戏玩家信息: player_id:玩家ID,主键 player_name:玩家姓名,不能为空 age:年龄,必须…

Python数据分析常见Matplotlib SeaBorn图表

Matplotlib绘图 Matplotlib基本概念 Matplotlib:基于对象的思维构建的视觉符号。 每一个Axes(坐标轴)对象包含一个或者多个Axis(轴)对象,比如X轴、Y轴。 一个Figure(画像)是由一堆坐标轴对象组成的。 换…

2023中国数交会|美创科技获数字和软件服务行业两项大奖!

7月6日-9日,为期四天的2023中国国际数字和软件服务交易会(简称:数交会)圆满落幕。 作为国务院批准举办的国家级展会,本届数交会由商务部、科技部、中国贸促会和辽宁省政府主办,以“数字创新、融合发展”为主…

操作系统实战45讲|03.黑盒之中有什么、04.震撼的Linux全景图

03.黑盒之中有什么 黑盒之中有什么 从抽象的角度来看,内核就是计算机资源的管理者,管理资源是为了让应用使用资源。 计算机中的资源分为两类:硬件资源、软件资源; 硬件资源有以下这些: 总线,负责连接各种…

一个Transformer在尺度上适合多模态扩散的所有分布

文章目录 One Transformer Fits All Distributions in Multi-Modal Diffusion at Scale摘要本文方法实验结果 One Transformer Fits All Distributions in Multi-Modal Diffusion at Scale 摘要 本文提出了一个统一的扩散框架(UniDiffuser)来拟合一个模型中与一组多模态数据相…

Vue3+Vite+Pinia+Naive后台管理系统搭建之三:vue-router 的安装和使用

前言 如果对 vue3 的语法不熟悉的,可以移步 Vue3.0 基础入门快速入门。 如果对 vue-router 语法不熟悉的,可以移步Vue3 系列:vue-router。 1. 安装依赖 yarn add vue-router // or npm install vue-router 2. 构建 src/router/index.js …

对话式ai人工智能的主要好处有哪些

对话式 AI 是客户服务的一个重要且不断增长的组成部分,尤其是客户越来越多地采用的数字自助服务。 对话式 AI 可以在提高客户满意度 (CSAT) 方面发挥很重要的作用。在 IBM 于 2021 年进行的一项研究中,99% 的公司报告称,由于使用虚拟对话式 …

支持源码的低代码核心工具,逻辑引擎

在现代企业管理中,决策扮演着至关重要的角色。然而,随着业务规模的扩大和数据量的增加,人工决策变得越来越困难和耗时,而且容易受到主观因素的影响。逻辑引擎的出现为企业提供了一种高效、准确的决策推理工具,能够以逻…

数字化转型迫在眉睫

在挑战商业世界现状并实现数字化转型时,一定程度的阻力是不可避免的。事实上,《福布斯》的一篇文章援引哈佛商学院的研究表明,70%的组织变革努力都失败了,“原因之一是高管们没有从足够多的人那里了解他们的计划和想法。”支持。”…

市面上的ipad国产触控笔怎么样?好用的电容笔合集

而对那些把IPAD当作学习工具的人而言,这个Apple Pencil绝对是不可或缺的。然而,苹果版本的Pencil却是昂贵得让许多人望而却步。因此,最佳方法是选择一个平替的电容笔。我是从几年前开始用IPAD的,也是一个数码爱好者,近…

AIGC行业周刊【2023-0709】【第六期】2023年世界人工智能大会大佬发言汇总

点击加入->【智子纪元-AIGC】技术交流群 一、大咖观点: 0709AI日报:2023年世界人工智能大会大佬发言汇总「5年内,人类程序员没了」,Stability AI老板大胆预测,一众大佬狂怼:大错特错,都懒得…

在vite创建的vue3项目中加载Cesium立体地形信息并调整初始化角度

在vite创建的vue3项目中加载Cesium立体地形信息并调整初始化角度 使用vite创建vue3项目 npm create vitelatestcd到创建的项目文件夹中 npm install安装Cesium npm i cesium vite-plugin-cesium vite -D配置 (1)在项目的vite.config.js文件中添加&#x…

算法训练营第三十一天||理论基础 ● 455.分发饼干 ● 376. 摆动序列 ● 53. 最大子序和

理论基础 贪心的本质是选择每一阶段的局部最优,从而达到全局最优。 这么说有点抽象,来举一个例子: 例如,有一堆钞票,你可以拿走十张,如果想达到最大的金额,你要怎么拿? 指定每次…