基于python的数字图像处理--学习笔记(二)

本文探讨了基于Python的数字图像处理,主要介绍图像矩阵变换,包括向前映射和向后映射的概念及其区别。接着,详细讲解了如何使用Python实现图像旋转,分析了旋转过程中的问题及解决方案,确保图像以中心点旋转并完整显示。此外,还提到了彩色图像的邻域平均操作以及在处理过程中遇到的溢出问题和解决策略。最后,讨论了去除图片加性高斯白噪声的方法和灰度级变换的原理。
摘要由CSDN通过智能技术生成

基于python的简单图像矩阵变换:

使用opencv-python读取图片文件,并使用numpy和math等库对图片进行对称反转、旋转、平移、剪切等操作。

当使用cv2.imread读入一个图片后,完全可以将读入的图片转换为nuparray矩阵,所有对图片灰度(色度)的变化,都可以表示为是对矩阵中像素位置对应的数据的变换操作。
在这里插入图片描述
在这里插入图片描述 也即,图像变换的本质是将像素点的坐标通过某一种函数关系,所有对图像的操作都是对像素矩阵的操作。在本次内容中,还并未涉及灰度值的变换,主要是图像像素坐标的迁移如平移或旋转。

在平移旋转中,变换后的图像和原图像的像素是一一对应的;而对于剪切等变换,会有原图像上多个像素对应变换后图像像素的情况。由此,即可引出,图像映射的前向和后向区分问题。


向前映射和向后映射:

假设变换前图像为I(x,y),变换后图像为I’(x’,y’),则变换前后的图像之间存在下列关系

  1. 由原图像像素表示出变换后的像素,以原图每个像素为基准计算被它影响的新图像素。即为前向映射
    前向变换在这里插入图片描述
  2. 由变换后的图像像素还原出原图像像素,以新图每个像素为基准计算影响它的原图像素。即为后向映射
    后向变换在这里插入图片描述在这种情况下,我们知道输出图像上整数点位置(x’,y’)在变换前位于输入图像上的位置(x,y),一般来说这是个非整数点位置,利用其周围整数点位置的输入图像像素值进行插值,就得到了该点的像素值。我们遍历输出图像,经过坐标变换、插值两步操作,我们就能将其像素值一个个地计算出来,因此向后映射又叫图像填充映射。

前向映射可能会导致多对一的情况,也会出现目标点没有像素,但是原图像有的问题。工程上多使用反向映射,避免上述问题,同时减少计算量。但反向映射需要提前知道反变换,在变换复杂的场合,其反变换会很难求得。

参考:图像变换——向前映射和向后映射

参考:基础图像操作(十三):像素重映射


图像旋转:

终于写到正题了,开始结合python实现对图像的简单变换。

前文说过,图像变换就是矩阵变换:图像旋转也即矩阵旋转。(x’,y’)表示一个点经过旋转后的新位置,(x,y)表示未旋转前的原始位置,θ为旋转角度,编程中以弧度为单位在这里插入图片描述在这里插入图片描述

注意:计算多个点的旋转,需要将每个点位置分别代入公式计算。

  1. 由以上方法,可写出旋转代码。但运行后会发现有诸多问题,这里先按下不表。

    import cv2 as cv
    import numpy as np
    import math
    
    
    def rotate(img, angle):
        height, width, _ = img.shape
        res = np.zeros((height, width, 3), np.uint8) #生成三通道原图片大小的变换后图片模板
        anglePi = angle * np.pi / 180.0
    
        for i in range(height):#y
            for j in range(width):#x
                # y = round(j * np.cos(anglePi) - i * np.sin(anglePi))   前向映射
                # x = round(j * np.sin(anglePi) + i * np.cos(anglePi))
                # 后向映射,下面为逆矩阵
                srcY = (j * np.cos(anglePi) + i * np.sin(anglePi))
                srcX = (-j * np.sin(anglePi) + i * np.cos(anglePi))
                # 后向映射+双线性插值
                x = math.floor(srcX)
                y = math.floor(srcY)
                u = srcX - x
                v = srcY - y
                if 0 <= x <= 255 and 0 <= y <= 255:
                    res[i, j] = (1 - u) * (1 - v) * img[x, y] + u * (1 - v) * img[x + 1, y] + (1 - u) * v * img[x, y + 1] + u * v * img[x + 1, y + 1]
                    # res[i, j] = img[x, y]
                    # res[x, y] = img[i, j]
        print(res.shape)
        return res
    
    if __name__ == '__main__':
        img = cv.imread("pic1.jpg")
        cv.imshow("rotated img"
  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值