openCVday02

形态学变换

形态学变换是一种基于形状的简单变换,它处理的对象通常是二值化对象。形态学变换有两个输入,一个输出。输入为原图像、核(结构化元素),输出为形态学变换后的图像。其基本操作有腐蚀和膨胀,这两种操作是相反的,即较亮的像素会被腐蚀和膨胀。

1、核

核(kernel)其实就是一个小区域,通常都是奇数列的方阵。它有自己的结构,比如矩形结构、椭圆结构,十字结构。通过不同的结构可以对不同特征的图像进行形态学操作的处理。

2、腐蚀

腐蚀操作就是使用核在原图(一般是二值化图,其实可以是彩色图)上进行从左至右、从上往下的滑动。在滑动的过程中,让核值为1的区域与被核覆盖的对应区域,取其中的最小值,该最小值就是核覆盖区域中心像素点的新像素值。

ps:腐蚀的其实就是白色部分,因为都是最小值在替换原本的像素值,像素值越小,图像就越黑。

腐蚀的详细流程:

1、初始化:

​ 设置一个起始位置(一般从图像的左上角开始)

​ 准备好核(结构元素),通常都是奇数列的方阵,因为这样才有明确的中心点。

2、逐像素处理:对于输入图像的每一个像素,执行以下步骤:

​ a:定位:将核移动到当前处理像素的位置,使核的中心与该像素对齐

​ b:区域覆盖:核会覆盖图像上的一个局部区域,这个区域由核的尺寸决定

​ c:条件检查:检查核覆盖区域内所有原图像的像素颜色。

​ d:侵蚀决策:如果核覆盖的所有元素都是白色,则原图像中的中心像素保持不变,否则让被核值为1覆盖的区域的最小值替代中心元素的像素值。

3、迭代移动:核沿着原图像从左至右从上至下逐列移动,重复上述过程,直到整个图像都被核遍历过

4、循环处理:如果指定了多个迭代次数,那么在整个图像完成一次遍历后,再次从头进行同样的遍历和侵蚀,直到达到指定的迭代次数。

import cv2
import numpy as np
img1 = cv2.imread("./src/1.jpg", cv2.IMREAD_GRAYSCALE)
img2 = cv2.adaptiveThreshold(img1,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,3,1)
kenel = np.ones((3,3),dtype=np.uint8)
img3 = cv2.erode(img2,kenel,iterations=1)
cv2.imshow("img2",img2)
cv2.imshow("img3",img3)
cv2.waitKey(0)

在这里插入图片描述

3、膨胀

膨胀与腐蚀的作用相反,腐蚀是核值为1的覆盖区域的最小值替代原图像中心像素的像素值,而膨胀是最大值替代其像素值。

import cv2
import numpy as np
img1 = cv2.imread("./src/1.jpg",cv2.IMREAD_GRAYSCALE)
img2 = cv2.adaptiveThreshold(img1,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,3,1)
kenel = np.ones((3,3),dtype=np.uint8)
img3 = cv2.dilate(img2,kenel,iterations=1)
cv2.imshow("img2",img2)
cv2.imshow("img3",img3)
cv2.waitKey(0)

在这里插入图片描述

4、开运算

开运算是先腐蚀后膨胀

import cv2
import numpy as np
img1 = cv2.imread("./src/car.png")
kenel = np.ones((3,3),np.uint8)
img2 = cv2.erode(img1,kenel,iterations=1)
img3 = cv2.dilate(img2,kenel,iterations=1)
cv2.imshow("img1",img1)
cv2.imshow("img2",img2)
cv2.imshow("img3",img3)
cv2.waitKey(0)

import cv2
import numpy as np
img1 = cv2.imread("./src/car.png")
kenel = np.ones((3,3),np.uint8)
img2 = cv2.morphologyEx(img1,cv2.MORPH_OPEN,kenel)
cv2.imshow("img1",img1)
cv2.imshow("img2",img2)



在这里插入图片描述
在这里插入图片描述

5、闭运算

闭运算与开运算相反,是先膨胀后腐蚀

import cv2
import numpy as np
img1 = cv2.imread("./src/car.png")
kenel = np.ones((3,3),np.uint8)
img2 = cv2.dilate(img1,kenel,iterations=1)
img3 = cv2.erode(img2,kenel,iterations=1)
cv2.imshow("img1",img1)
cv2.imshow("img2",img2)
cv2.imshow("img3",img3)
cv2.waitKey(0)

import cv2
import numpy as np
img1 = cv2.imread("./src/car.png")
kenel = np.ones((3,3),np.uint8)
img2 = cv2.morphologyEx(img1,cv2.MORPH_CLOSE,kenel)
cv2.imshow("img1",img1)
cv2.imshow("img2",img2)

在这里插入图片描述在这里插入图片描述

6、礼貌运算

原图像与“开运算“的结果图之差,因为开运算带来的结果是放大了裂缝或者局部低亮度的区域,因此,从原图中减去开运算后的图,得到的效果图突出了比原图轮廓周围的区域更明亮的区域,且这一操作和选择的核的大小相关。

礼帽运算用来分离比邻近点亮一些的斑块。当一幅图像具有大幅的背景的时候,而微小物品比较有规律的情况下,可以使用礼帽运算进行背景提取

在这里插入图片描述

7、黑帽运算

黑帽运算为”闭运算“的结果图与原图像之差,

黑帽运算后的效果图突出了比原图轮廓周围的区域更暗的区域,且这一操作和选择的核的大小相关。

黑帽运算用来分离比邻近点暗一些的斑块

import cv2
import numpy as np

img1 = cv2.imread("./src/car.png")
kenel = np.ones((3, 3), dtype=np.uint8)
img2 = cv2.morphologyEx(img1, cv2.MORPH_OPEN, kenel)
img3 = cv2.morphologyEx(img1, cv2.MORPH_CLOSE, kenel)
img4 = img1 - img2
img5 = img1 - img3
cv2.imshow("img1",img1)
cv2.imshow("img4",img4)
cv2.imshow("img5",img5)
cv2.waitKey(0)

img1 = cv2.imread("./src/car.png")
kenel = np.ones((3, 3), dtype=np.uint8)
img2 = cv2.morphologyEx(img1, cv2.MORPH_BLACKHAT, kenel)
img3 = cv2.morphologyEx(img1, cv2.MORPH_TOPHAT, kenel)

cv2.imshow("img1",img1)
cv2.imshow("img2",img2)
cv2.imshow("img3",img3)
cv2.waitKey(0)

在这里插入图片描述

8、形态学梯度

形态学梯度是一个基于结构元素的图像处理方法,它通过比较原图像与膨胀图和腐蚀图之间的差异来突出图像边缘特征。具体来说,对于图像中的每个像素点,其形态学梯度值是该像素点在膨胀后的图像值与其在腐蚀后的图像值之差。这样得到的结果通常能够强化图像的边缘信息,并且对噪声有一定的抑制作用

#膨胀图像与腐蚀图像之差
import cv2
import numpy as np
img1 = cv2.imread("./src/car.png")
img2 = cv2.erode(img1,np.ones((3,3),dtype=np.uint8),iterations=1)
img3 = cv2.dilate(img1,np.ones((3,3),dtype=np.uint8),iterations=1)
img4 = img2-img3
img5 = img3-img2
img6 = cv2.morphologyEx(img1,cv2.MORPH_GRADIENT,np.ones((3,3),dtype=np.uint8))
cv2.imshow("img1",img1)
cv2.imshow("img4",img4)
cv2.imshow("img5",img5)
cv2.imshow("img6",img6)
cv2.waitKey(0)

在这里插入图片描述

图像颜色识别

1、RGB颜色空间

在图像处理中,最常见的就是RGB颜色空间。RGB颜色空间是我们接触最多的颜色空间,是一种用于表示和显示彩色图像的一种颜色模型。RGB代表红色(Red)、绿色(Green)和蓝色(Blue),这三种颜色通过不同强度的光的组合来创建其他颜色,广泛应用于我们的生活中,比如电视、电脑显示屏以及上面实验中所介绍的RGB彩色图。

RGB颜色模型基于笛卡尔坐标系,RGB原色值位于3个角上,依次是青色、红色和黄色位于另外三个角上,黑色位于原点处,白色位于离原点最远的角上。因为黑色在RGB三通道中表现为(0,0,0),所以映射到这里就是原点;而白色是(255,255,255),所以映射到这里就是三个坐标为最大值的点。

RGB颜色空间可以产生大约1600万种颜色,几乎包括了世界上的所有颜色,也就是说可以使用RGB颜色空间来生成任意一种颜色。

注意:在OpenCV中,颜色是以BGR的方式进行存储的,而不是RGB,这也是上面红色的像素值是(0,0,255)而不是(255,0,0)的原因

2、颜色加法

你可以使用OpenCV的cv.add()函数把两幅图像相加,或者可以简单地通过numpy操作添加两个图像,如res = img1 + img2。两个图像应该具有相同的大小和类型。

OpenCV加法和Numpy加法之间存在差异。OpenCV的加法是饱和操作,而Numpy添加是模运算

>>> x = np.uint8([250])
>>> y = np.uint8([10])
>>> print( cv.add(x,y) ) # 250+10 = 260 => 255
[[255]]
>>> print( x+y )          # 250+10 = 260 % 256 = 4
[4]
import cv2
import numpy as np
img1 = cv2.imread("./src/cao.png")
img2 = cv2.imread("./src/pig.png")
img3 = cv2.add(img1,img2)
img4 = img1 + img2
cv2.imshow("img3",img3)
cv2.imshow("img4",img4)
cv2.waitKey(0)

在这里插入图片描述
在这里插入图片描述

3、颜色加权加法

这其实也是加法,但是不同的是两幅图像的权重不同,这就会给人一种混合或者透明的感觉。图像混合的计算公式如下:

g(x) = (1−α)f0(x) + αf1(x)

通过修改 α 的值(0 → 1),可以实现非常炫酷的混合。

现在我们把两幅图混合在一起。第一幅图的权重是0.7,第二幅图的权重是0.3。函数cv2.addWeighted()可以按下面的公式对图片进行混合操作。

dst = α⋅img1 + β⋅img2 + γ

这里γ取为零。

import cv2
img1 = cv2.imread("./src/cao.png")
img2 = cv2.imread("./src/pig.png")
img3 = cv2.addWeighted(img1,0.7,img2,0.3,0)
cv2.imshow("img3",img3)
cv2.waitKey(0)

在这里插入图片描述

4、HSV颜色空间

HSV颜色空间指的是HSV颜色模型,这是一种与RGB颜色模型并列的颜色空间表示法。RGB颜色模型使用红、绿、蓝三原色的强度来表示颜色,是一种加色法模型,即颜色的混合是添加三原色的强度。而HSV颜色空间使用色调(Hue)、饱和度(Saturation)和亮度(Value)三个参数来表示颜色,色调H表示颜色的种类,如红色、绿色、蓝色等;饱和度表示颜色的纯度或强度,如红色越纯,饱和度就越高;亮度表示颜色的明暗程度,如黑色比白色亮度低。

HSV颜色模型是一种六角锥体模型

色调H:

使用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,紫色为300°。通过改变H的值,可以选择不同的颜色

饱和度S:

饱和度S表示颜色接近光谱色的程度。一种颜色可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例越大,颜色接近光谱色的程度就越高,颜色的饱和度就越高。饱和度越高,颜色就越深而艳,光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,其中0%表示灰色或无色,100%表示纯色,通过调整饱和度的值,可以使颜色变得更加鲜艳或者更加灰暗。

明度V:

明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白),通过调整明度的值,可以使颜色变得更亮或者更暗。

一般对颜色空间的图像进行有效处理都是在HSV空间进行的,然后对于基本色中对应的HSV分量需要给定一个严格的范围,下面是通过实验计算的模糊范围(准确的范围在网上都没有给出)。

H: 0— 180

S: 0— 255

V: 0— 255

为什么有了RGB颜色空间我们还是需要转换成HSV颜色空间来进行图像处理呢?

  • 符合人类对颜色的感知方式:人类对颜色的感知是基于色调、饱和度和亮度三个维度的,而HSV颜色空间恰好就是通过这三个维度来描述颜色的。因此,使用HSV空间处理图像可以更直观地调整颜色和进行色彩平衡等操作,更符合人类的感知习惯。
  • 颜色调整更加直观:在HSV颜色空间中,色调、饱和度和亮度的调整都是直观的,而在RGB颜色空间中调整颜色不那么直观。例如,在RGB空间中要调整红色系的颜色,需要同时调整R、G、B三个通道的数值,而在HSV空间中只需要调整色调和饱和度即可。
  • 降维处理有利于计算:在图像处理中,降维处理可以减少计算的复杂性和计算量。HSV颜色空间相对于RGB颜色空间,减少了两个维度(红、绿、蓝),这有利于进行一些计算和处理任务,比如色彩分割、匹配等。

因此,在进行图片颜色识别时,我们会将RGB图像转换到HSV颜色空间,然后根据颜色区间来识别目标颜色。

5、制作掩膜

掩膜(mask)是一种在图像处理中常见的操作,它用于选择性地遮挡图像的某些部分,以实现特定任务的目标。掩膜通常是一个二值化图像,并且与原图像的大小相同,其中目标区域被设置成白色,其他区域被设置为黑色,并且目标区域可以根据HSV的颜色范围进行修改。

import cv2
import numpy as np
img1 = cv2.imread("./src/3.png")
img2 = cv2.cvtColor(img1,cv2.COLOR_BGR2HSV)
color_down = np.array([26,43,46])
color_up = np.array([34,255,255])
mask = cv2.inRange(img2,color_down,color_up)
cv2.imshow("mask",mask)
cv2.imshow("img2",img1)
cv2.waitKey(0)

在这里插入图片描述

6、与运算

与运算底层就是按位与操作

import cv2
import numpy as np
img1 = cv2.imread("./src/3.png")
img2 = cv2.cvtColor(img1,cv2.COLOR_BGR2HSV)
color_down = np.array([26,43,46])
color_up = np.array([34,255,255])
mask = cv2.inRange(img2,color_down,color_up)
img3 = cv2.bitwise_and(img1,img1,mask=mask)
cv2.imshow("mask",mask)
cv2.imshow("img2",img1)
cv2.imshow("img3",img3)
cv2.waitKey(0)

图片颜色替换

由于掩膜与原图的大小相同,并且像素位置一一对应,那么我们就可以得到掩膜中白色(也就是像素值为255)区域的坐标,并将其带入到原图像中,即可得到原图中的红色区域的坐标,然后就可以修改像素值了,这样就完成了颜色的替换

import cv2
import numpy as np
img1 = cv2.imread("./src/demo.png")
img2 = cv2.cvtColor(img1,cv2.COLOR_BGR2HSV)
color_down = np.array([26,43,46])
color_up = np.array([34,255,255])
mask = cv2.inRange(img2,color_down,color_up)
img1[mask==255]=[0,0,255]

cv2.imshow("mask",mask)
cv2.imshow("img1",img1)

cv2.waitKey(0)


在这里插入图片描述在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值