OPenCV中图像的变换

形态学变换

形态学变换是一种基于形状的简单变换,它的处理对象通常是二值化图像。形态学变换有两个输入,一个输出:输入为原图像、核),输出为形态学变换后的图像,基本操作是腐蚀和碰撞

腐蚀与膨胀

腐蚀操作就是使用核在二值化的图片上进行从左到右、从上到下的滑动。在滑动中,令核值为1的区域与被核覆盖的对应区域进行相乘,得到其最小值,该最小值就是卷积核覆盖区域的中心像素点的新像素值,接着继续滑动。由于操作图像为二值图,所以不是黑就是白,这就意味着,在被核值为1覆盖的区域内,只要有黑色(像素值为0),那么该区域的中心像素点必定为黑色(0),使得二值化图像中的白色部分尽可能的压缩。

腐蚀操作能够逐步收缩目标物体边界,消除孤立的噪声像素以及细化连续的前景区域。

import cv2
import numpy as np
img=np.zeros([8,8],dtype=np.uint8)
kernel = np.ones((3,3), np.uint8)
img[2:6,2:6]=10
img[3,3]=240
img[3,4]=110
print(img)
erode=cv2.erode(img, kernel, iterations=1)
print(erode)

cv2.dilate(img,kernel,iterations=1)  kernel:卷积核或者滤波算子 iterations:卷的次数

可以看到在3*3范围内的数字都变成了最大数

胀操作就是使用核在原图)上进行从左到右、从上到下的滑动),在滑动过程中,令核值为1的区域与被核覆盖的对应区域进行相乘,得到其最大值,该最大值就是核覆盖区域的中心像素点的新像素值,由于操作图像为二值图,所以不是黑就是白,这就意味着,在卷积核覆盖的区域内,只要有白色(像素值为255),那么该区域的中心像素点必定为白色(255)。

import cv2
import numpy as np
img=np.zeros([8,8],dtype=np.uint8)
kernel = np.ones((3,3), np.uint8)
img[2:6,2:6]=10
img[3,3]=240
img[3,4]=110
erosion = cv2.dilate(img, kernel, iterations=1)
print(erosion)

cv2.erode(img, kernel, iterations=1)  参数设置不变

闭运算与开运算

开运算是先腐蚀后膨胀,其作用是:分离物体,消除小区域。特点:消除噪点,去除小的干扰块,而不影响原来的图像

闭运算与开运算相反,是先膨胀后腐蚀,作用是消除/“闭合”物体里面的孔洞,特点:可以填充闭合区域

分别是闭运算与开运算,闭运算让图片连起来消除眼部空洞,开运算让图片眼睛的地方消失

import cv2
import numpy as np
image = cv2.imread('2.png', cv2.IMREAD_GRAYSCALE)
kernel = np.ones((5, 5), np.uint8)
opening = cv2.morphologyEx(image, cv2.MORPH_OPEN, kernel)
closing = cv2.morphologyEx(image, cv2.MORPH_CLOSE, kernel)
cv2.imshow('Opening', opening)
cv2.imshow('Closing', closing)
cv2.waitKey(0)

调用不同的API即可,了解与熟悉,用处不是特别大,修图一点点部分,yolo模型与vit transform等等在这方面处理的更好

礼帽运算与黑帽运算

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

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

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

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

有一个概念叫形态学梯度,也可以检测边缘,后续也有边缘计策,这个相当于图片的预处理方法

import cv2
import numpy as np
image = cv2.imread('2.png', cv2.IMREAD_GRAYSCALE)
kernel = np.ones((5, 5), np.uint8)
tophat = cv2.morphologyEx(image,cv2.MORPH_TOPHAT,kernel) 
blackhat = cv2.morphologyEx(image,cv2.MORPH_BLACKHAT,kernel)
cv2.imshow('tophat', tophat)
cv2.imshow('blackhat', blackhat)
cv2.waitKey(0)
cv2.destroyAllWindows()

旋转,镜像,缩放,矫正

旋转

图像的旋转,镜像等等投影类的变换都是原图像在自然基的作用下,即在正常的X轴正方向,Y轴正方向下的图片,按照新基生成新的张量空间

在OpenCV中,要得到仿射变换矩阵可以使用cv2.getRotationMatrix2D(),参数设置:

Center:表示旋转的中心点,是一个二维的坐标点(x,y)

Angle:表示旋转的角度

Scale:表示缩放比例,可以通过该参数调整图像相对于原始图像的大小变化

插值为当有像素增加时的填充方式,后面讲述

import cv2

if __name__ == "__main__":
    path = "./1.jpg"
    image_np = cv2.imread(path)
    img_shape = image_np.shape
    # 对图片进行旋转(旋转中心点,旋转角度,缩放比例)
    M = cv2.getRotationMatrix2D((img_shape[0] / 2, img_shape[1] / 2), 45, 0.5)
    #image_np处理的图像  M变换矩阵  (img_shape[0], img_shape[1]) 变换后的图像宽高 flags插值方式  borderMode填充方式
    #rotation_image = cv2.warpAffine(image_np, M, (img_shape[0], img_shape[1]),flags=cv2.INTER_LANCZOS4, borderMode=cv2.BORDER_REFLECT_101)
    rotation_image=cv2.warpAffine(img,M,(shape[1],shape[0]))
    cv2.imshow("rotation_image", rotation_image)
    cv2.waitKey(0)

镜像

图像的旋转是围绕一个特定点进行的,而图像的镜像旋转则是围绕坐标轴进行的。图像的镜像旋转分为水平翻转、垂直翻转、水平垂直翻转三种。

水平翻转就是将图片的像素点沿y轴翻转,具体到像素点来说就是令其坐标从(x,y)翻转为(-x,y)。

垂直翻转就是将图片的像素点沿x轴翻转,具体到像素点来说就是其坐标从(x,y)翻转为(x,-y)

水平垂直翻转就是水平翻转和垂直翻转的结合,具体到像素点来说就是其坐标从(x,y)翻转为(-x,-y)

import cv2
if __name__ == "__main__":
    path = "./1.jpg"
    image_np = cv2.imread(path)
    mirroring_image = cv2.flip(image_np, 0)
    cv2.imshow("mirroring_image", mirroring_image)
    cv2.waitKey(0)

参数flipcode有三个选择:0:垂直翻转,大于0:水平翻转,小于0:水平垂直翻转

缩放

与图像旋转里的缩放的原理一样,图像缩放的原理也是根据需要将原图像的像素数量增加或减少,并通过插值算法来计算新像素的像素值。本实验中也是提供了五种插值方法,分别时最近邻插值、双线性插值、像素区域插值、立方插值、Lanczos插值,与图像旋转实验中的五个插值方法相同


if __name__ == "__main__":
    path = "./1.jpg"
    image_np = cv2.imread(path)
    resize_image = cv2.resize(image_np, None, fx=0.6, fy=0.6, interpolation=cv2.INTER_LINEAR)  # 对图片进行缩放
    cv2.imshow("resize_image", resize_image)
    cv2.imshow("image_np", image_np)
    cv2.waitKey(0)

图片缩放方法

cv2.resize(image_np, dsize=None, fx=0.6, fy=0.6, interpolation=cv2.INTER_LINEAR)

参数说明:image_np:这是待缩放的原始图像,它是一个numpy数组表示的图像。None:这个参数代表目标图像的尺寸(宽度和高度),在这里设置为 None 意味着我们不直接指定新图像的具体尺寸,而是通过接下来的 fxfy 参数来按比例缩放原图像。fx:这是一个缩放因子,用来控制图像水平方向(宽度)的缩放比例。如果 fx=0.6,那么原图像的宽度将缩小到原来宽度的60%。fy:同样是一个缩放因子,但它控制的是图像垂直方向(高度)的缩放比例。当 fy=0.6 时,原图像的高度将缩小到原来高度的60%。interpolation:插值方法,用于决定如何计算新尺寸图像中的像素值。cv2.INTER_LINEAR 表示双线性插值,这是一种常用的、平滑且质量相对较高的插值方式,能够较好地保留图像细节和连续性。

图像的矫正

图像矫正的原理是透视变换,在图像旋转里接触过仿射变换,知道仿射变换是把一个二维坐标系转换到另一个二维坐标系的过程,转换过程坐标点的相对位置和属性不发生变换,是一个线性变换,该过程只发生旋转和平移过程。因此,一个平行四边形经过仿射变换后还是一个平行四边形

import cv2
import numpy as np

if __name__ == "__main__":
    path = "./3.png"
    image_np = cv2.imread(path)
    img_shape = image_np.shape
    # 原图中卡片的四个角点
    pts1 = np.float32([[178, 100], [487, 134], [124, 267], [473, 308]])
    img_line = image_np
    cv2.line(img_line, pts1[0].astype(np.int64).tolist(), pts1[1].astype(np.int64).tolist(), (0, 0, 255), 2,
             cv2.LINE_AA)
    cv2.line(img_line, pts1[0].astype(np.int64).tolist(), pts1[2].astype(np.int64).tolist(), (0, 0, 255), 2,
             cv2.LINE_AA)
    cv2.line(img_line, pts1[3].astype(np.int64).tolist(), pts1[1].astype(np.int64).tolist(), (0, 0, 255), 2,
             cv2.LINE_AA)
    cv2.line(img_line, pts1[3].astype(np.int64).tolist(), pts1[2].astype(np.int64).tolist(), (0, 0, 255), 2,
             cv2.LINE_AA)
    # 变换后分别在左上、右上、左下、右下四个点
    pts2 = np.float32([[0, 0], [img_shape[1], 0], [0, img_shape[0]], [img_shape[1], img_shape[0]]])
    pts = cv2.getPerspectiveTransform(pts1, pts2)  # 生成透视变换矩阵
    correct_image = cv2.warpPerspective(image_np, pts, (img_shape[1], img_shape[0]), flags=cv2.INTER_LINEAR, borderMode=cv2.BORDER_REFLECT_101)  # 进行透视变换
    # 返回处理正确后的内容
    cv2.imshow("image_np", image_np)
    cv2.imshow('img_line', img_line)
    cv2.imshow("correct_image", correct_image)
    cv2.waitKey(0)

getPerspectiveTransform(src,dst)   参数设置:

src:原图像上需要进行透视变化的四个点的坐标,这四个点用于定义一个原图中的四边形区域。

dst:透视变换后,src的四个点在新目标图像的四个新坐标。

该函数会返回一个透视变换矩阵,得到透视变化矩阵之后,使用warpPerspective()函数即可进行透视变化计算,并得到新的图像。

cv2.warpPerspective(src, M, dsize, flags, borderMode)   参数设置:

src:输入图像。

M:透视变换矩阵。这个矩阵可以通过getPerspectiveTransform函数计算得到。

dsize:输出图像的大小。它可以是一个Size对象,也可以是一个二元组。

flags:插值方法的标记。

borderMode:边界填充的模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值