Python实现图像的平移、镜像、旋转(不调用CV自身函数)

这篇具有很好参考价值的文章主要介绍了Python实现图像的平移、镜像、旋转(不调用CV自身函数)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Python实现图像的平移、镜像、旋转(不调用CV自身函数)

老师布置的作业。。。。。

平移图像

图像的平移在几何变换中算是最简单的变换之一,话不多说,直奔主题

python图像镜像,图像处理,计算机视觉,python

由图可知,在opencv中图像的原点一般为左上角,设初始坐标为 ( x 0 , x 0 ) (x_{0}, x_{0}) (x0,x0)的经过平移 ( △ x , △ y ) (\bigtriangleup x, \bigtriangleup y) (x,y)后,坐标变为 ( x 1 , y 1 ) (x_{1}, y_{1}) (x1,y1)

则很容易得出两点之间的位置关系:
{ x 1 = x 0 + △ x y 1 = y 0 + △ y \begin{cases} x_{1} = x_{0} + \bigtriangleup x \\y_{1} = y_{0} + \bigtriangleup y \end{cases} {x1=x0+xy1=y0+y
在python中我们可以使用简单for循环实现:

import cv2 as cv
import numpy as np


def show_Img(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)
    cv.destroyAllWindows()


def translate_img(img, move_y, move_x):
    h, w, c = img.shape
    translated_img = np.zeros((h, w, c), dtype=np.uint8)
    for i in range(h):
        for j in range(w):
            if i >= move_y and j >= move_x:
                translated_img[i, j] = img[i - move_y, j - move_x]
    return translated_img


img = cv.imread("images/cat.jpg")
h, w, c = img.shape
translated_img = translate_img(img, h // 3, w // 3)
img_all = np.hstack((img, translated_img))
show_Img("img", img_all)

python图像镜像,图像处理,计算机视觉,python

而通常我们一般是用矩阵形式表示:
[ x 1 , y 1 , 1 ] = [ x 0 , y 0 , 1 ] [ 1 0 0 0 1 0 △ x △ y 1 ] \left [ x_{1} , y_{1}, 1\right ] = \left [ x_{0} , y_{0} , 1 \right ] \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ \bigtriangleup x & \bigtriangleup y&1 \end{bmatrix} [x1,y1,1]=[x0,y0,1] 10x01y001
python实现为:

def translate_image(image, move_x, move_y):
    # 平移矩阵
    translation_matrix = np.array([[1, 0, 0], [0, 1, 0], [move_x, move_y, 1]])
    height, width = image.shape[:2]
    translated_image = np.zeros([height, width, 3], dtype=np.uint8)
    for y in range(height):
        for x in range(width):
            translated_x, translated_y, _ = np.dot([x, y, 1], translation_matrix)
            if 0 <= translated_x < width and 0 <= translated_y < height:
                translated_image[translated_y, translated_x] = image[y, x]
    return translated_image

镜像图像

图像镜像也是最为常用的一种变换,镜像就是相对某一参照面旋转180°的图像,又通常成为对称变换。

这里主要介绍三种镜像方式:

  • 水平镜像
  • 垂直镜像
  • 斜对角线镜像

水平镜像

python图像镜像,图像处理,计算机视觉,python

经数学分析得水平镜像后的x1与x0和为图像宽度,而y点不变,所以:
{ x 1 = w − x 0 y 1 = y 0 \begin{cases} x_{1} = w - x_{0}\\ y_{1} = y_{0} \end{cases} {x1=wx0y1=y0
转换为矩阵得:
[ x 1 , y 1 , 1 ] = [ x 0 , y 0 , 1 ] [ − 1 0 0 0 1 0 w 0 1 ] \left [ x_{1}, y_{1}, 1 \right ] = \left[x_{0}, y_{0}, 1 \right]\begin{bmatrix} -1 & 0 & 0\\ 0 & 1 & 0 \\ w & 0 & 1 \end{bmatrix} [x1,y1,1]=[x0,y0,1] 10w010001

垂直镜像

同理:
[ x 1 , y 1 , 1 ] = [ x 0 , y 0 , 1 ] [ 1 0 0 0 − 1 0 0 h 1 ] \left [ x_{1}, y_{1}, 1 \right ] = \left[x_{0}, y_{0}, 1 \right]\begin{bmatrix} 1 & 0 & 0\\ 0 & -1 & 0 \\ 0 & h & 1 \end{bmatrix} [x1,y1,1]=[x0,y0,1] 10001h001

斜对角线镜像

同理:
[ x 1 , y 1 , 1 ] = [ x 0 , y 0 , 1 ] [ − 1 0 0 0 − 1 0 w h 1 ] \left [ x_{1}, y_{1}, 1 \right ] = \left[x_{0}, y_{0}, 1 \right]\begin{bmatrix} -1 & 0 & 0\\ 0 & -1 & 0 \\ w & h & 1 \end{bmatrix} [x1,y1,1]=[x0,y0,1] 10w01h001
综上所述,用python实现为:

def flip_image(image, flip):
    h, w = image.shape[:2]

    fliped_image = np.zeros((h, w, 3), dtype=np.uint8)
    # 矩阵的w-1和y-1是防止图片的索引值超出范围
    if flip == "x":
        flip_matrix = np.array([[-1, 0, 0], [0, 1, 0], [w - 1, 0, 1]])
    elif flip == "y":
        flip_matrix = np.array([[1, 0, 0], [0, -1, 0], [0, h - 1, 1]])
    elif flip == "x-y":
        flip_matrix = np.array([[-1, 0, 0], [0, -1, 0], [w - 1, h - 1, 1]])
    else:
        flip_matrix = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]])
    for y in range(h):
        for x in range(w):
            flip_x, flip_y, _ = np.dot([x, y, 1], flip_matrix)
            fliped_image[flip_y, flip_x] = image[y, x]

    return fliped_image
img = cv.imread("images/dog2.jpg")
h, w, c = img.shape
img = cv.resize(img, (w // 4, h // 4))
fliped_img_x = flip_image(img, "x")
fliped_img_y = flip_image(img, "y")
fliped_img_x_y = flip_image(img, "x-y")
img_up = np.hstack((img, fliped_img_x))
img_down = np.hstack((fliped_img_y, fliped_img_x_y))
img_all = np.vstack((img_up, img_down))
show_Img("img_all", img_all)

python图像镜像,图像处理,计算机视觉,python

旋转图像

图像的旋转相比平移和镜像就稍微复杂了一些

python图像镜像,图像处理,计算机视觉,python

如图可知,初始点为 ( x , y ) (x, y) (x,y)逆时针旋转 β \beta β角度后为 ( x ′ , y ′ ) (x', y') (x,y)

数学分析:
{ x = D c o s α y = D s i n α \begin{cases} x = Dcos\alpha \\y = Dsin\alpha \end{cases} {x=Dcosαy=Dsinα

{ x ′ = D c o s ( α + β ) = D ( c o s α c o s β − s i n α s i n β ) = x c o s β − y s i n β y ′ = D s i n ( α + β ) = D ( s i n α c o s β + c o s α s i n β ) = y c o s β + x s i n β \begin{cases} x'=Dcos(\alpha+\beta)=D(cos\alpha cos\beta - sin\alpha sin\beta) = xcos\beta - ysin\beta\\ y'=Dsin(\alpha+\beta)=D(sin\alpha cos\beta + cos\alpha sin\beta) = ycos\beta + xsin\beta \end{cases} {x=Dcos(α+β)=D(cosαcosβsinαsinβ)=xcosβysinβy=Dsin(α+β)=D(sinαcosβ+cosαsinβ)=ycosβ+xsinβ

用矩阵表示为:
[ x ′ , y ′ , 1 ] = [ x , y , 1 ] [ c o s β s i n β 0 − s i n β c o s β 0 0 0 1 ] \left [ x', y', 1 \right ] = \left[x, y, 1\right]\begin{bmatrix} cos\beta & sin\beta & 0\\ -sin\beta & cos\beta & 0\\ 0 & 0 & 1 \end{bmatrix} [x,y,1]=[x,y,1] cosβsinβ0sinβcosβ0001
但这并不是整个图像旋转的原理,因为还要指定旋转点,这里假设图像旋转点为图像的中心,即 ( w / 2 , h / 2 ) (w/2, h/2) (w/2,h/2),则在旋转时需要将图像的坐标系移动到原本图像的中心上:
[ x ′ , y ′ , 1 ] = [ x , y , 1 ] [ 1 0 0 0 1 0 − w / 2 − h / 2 1 ] \left [ x' , y', 1\right ] = \left [ x , y , 1 \right ] \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ -w/2 & -h/2&1 \end{bmatrix} [x,y,1]=[x,y,1] 10w/201h/2001
python图像镜像,图像处理,计算机视觉,python

由上图可知,旋转时,整个图像的大小也随之改变,新的高度与宽度为:
{ w ′ = w ∗ ∣ c o s β ∣ + h ∗ ∣ s i n β ∣ h ′ = h ∗ ∣ c o s β ∣ + w ∗ ∣ s i n β ∣ \begin{cases} w' = w*|cos\beta|+ h*|sin\beta| \\ h' = h * |cos\beta| + w * |sin\beta| \end{cases} {w=wcosβ+hsinβh=hcosβ+wsinβ
旋转完后的图像在需要平移到原来的位置:
{ △ x = ( w ′ − w ) ∗ 0.5 + ( w / 2 − 1 ) △ y = ( h ′ − h ) ∗ 0.5 + ( h / 2 − 1 ) \begin{cases} \bigtriangleup x = (w' - w) * 0.5 + (w/2 - 1) \\ \bigtriangleup y = (h'- h) * 0.5 + (h/2 - 1) \end{cases} {x=(ww)0.5+(w/21)y=(hh)0.5+(h/21)
总的矩阵为:
[ x ′ , y ′ , 1 ] = [ x , y , 1 ] [ 1 0 0 0 1 0 − w / 2 − h / 2 1 ] [ c o s β s i n β 0 − s i n β c o s β 0 0 0 1 ] [ 1 0 0 0 1 0 △ x △ y 1 ] \left [ x' , y', 1\right ] = \left [ x , y , 1 \right ] \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ -w/2 & -h/2&1 \end{bmatrix}\begin{bmatrix} cos\beta & sin\beta & 0\\ -sin\beta & cos\beta & 0\\ 0 & 0 & 1 \end{bmatrix} \begin{bmatrix} 1 & 0 & 0\\ 0 & 1 & 0\\ \bigtriangleup x & \bigtriangleup y&1 \end{bmatrix} [x,y,1]=[x,y,1] 10w/201h/2001 cosβsinβ0sinβcosβ0001 10x01y001

前向映射

import cv2 as cv
import numpy as np


def show_Img(name, img):
    cv.imshow(name, img)
    cv.waitKey(0)
    cv.destroyAllWindows()


# 前向映射旋转
def front_rotate_image(image, angle):
    # 将角度转换为弧度
    radians = np.deg2rad(angle)

    # 计算旋转矩阵
    cos_theta = np.around(np.cos(radians), decimals=4)
    sin_theta = np.around(np.sin(radians), decimals=4)
    rotation_matrix = np.array([[cos_theta, sin_theta, 0], [-sin_theta, cos_theta, 0], [0, 0, 1]])

    # 计算旋转后的图像大小
    height, width = image.shape[:2]
    new_width = int(np.round(width * abs(cos_theta) + height * abs(sin_theta)))
    new_height = int(np.round(height * abs(cos_theta) + width * abs(sin_theta)))
    print(new_width, new_height)
    # 创建新图像
    rotated_image = np.zeros((new_height, new_width, 3), dtype=np.uint8)
    # 计算旋转中心点
    center_x = width / 2
    center_y = height / 2
    # 将坐标系平移回原来的位置,加上自定义旋转点的偏移量
    x_step = (new_width - width) * (center_x / width) + (center_x - 1)
    y_step = (new_height - height) * (center_y / height) + (center_y - 1)
    translation_matrix1 = np.array([[1, 0, 0], [0, 1, 0], [-center_x, -center_y, 1]])
    translation_matrix2 = np.array([[1, 0, 0], [0, 1, 0], [x_step, y_step, 1]])
    # 遍历每个像素并进行变换
    for y in range(height):
        for x in range(width):
            # 将坐标系平移至中心点
            translated_x, translated_y, _ = np.dot([x, y, 1], translation_matrix1)

            # 计算旋转后的坐标
            rotated_x, rotated_y, _ = np.dot([translated_x, translated_y, 1], rotation_matrix)

            rotated_x, rotated_y, _ = np.dot([rotated_x, rotated_y, 1], translation_matrix2)
            # 如果旋转后的坐标在原图像范围内,则将该像素复制到新图像中
            if 0 <= rotated_x < new_width and 0 <= rotated_y < new_height:
                rotated_image[int(np.round(rotated_y)), int(np.round(rotated_x))] = image[y, x]
    return rotated_image


img = cv.imread("images/kunkun.jpg")
theta = 45
h, w, c = img.shape
img = cv.resize(img, (w // 2, h // 2))
img_rotated = front_rotate_image(img, theta)
show_Img("img_rotated", img_rotated)

原图:

python图像镜像,图像处理,计算机视觉,python

结果:

python图像镜像,图像处理,计算机视觉,python

从上面看来,使用前向映射会造成许多网格状,这是因为有原图到旋转后的图,会生成小数坐标,导致丢失一部分像素,而后面会使用后向映射加线性插值的方法解决此问题。

后向映射

学业繁忙,后面慢慢更新。。。。。文章来源地址https://www.toymoban.com/news/detail-740448.html

到了这里,关于Python实现图像的平移、镜像、旋转(不调用CV自身函数)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【C++】【Opencv】cv::warpAffine()仿射变换函数详解,实现平移、缩放和旋转等功能

    仿射变换是一种二维变换,它可以将一个二维图形映射到另一个二维图形上,保持了图形的“形状”和“大小”不变,但可能会改变图形的方向和位置。仿射变换可以用一个线性变换矩阵来表示,该矩阵包含了六个参数,可以进行平移、缩放、旋转等操作。通过原理、函数和

    2024年02月05日
    浏览(63)
  • Python图像处理丨图像缩放、旋转、翻转与图像平移

    摘要: 本篇文章主要讲解Python调用OpenCV实现图像位移操作、旋转和翻转效果,包括四部分知识:图像缩放、图像旋转、图像翻转、图像平移。 本文分享自华为云社区《[Python图像处理] 六.图像缩放、图像旋转、图像翻转与图像平移》,作者:eastmount 。 本篇文章主要讲解Pyth

    2024年02月06日
    浏览(57)
  • 二维坐标基本变换(平移、旋转、缩放、镜像、阵列)

    诸如图像、模型等的基本变换,实际上都是点坐标的变换,通过矩阵,可以非常方便的达到这个目的。在下文仅介绍二维坐标变换原理。 首先,定义点类如下: 注意,为了形式统一,变换矩阵应统一为3*3阶,同理,对于三维坐标变换矩阵应是4*4阶。关于矩阵的表示,实际上

    2024年02月04日
    浏览(79)
  • python实现两函数通过缩放,平移和旋转进行完美拟合

    前几天在工作的时候接到了一个需求,希望将不同坐标系,不同角度的两条不规则曲线,并且组成该曲线的点集数量不一致,需求是希望那个可以通过算法的平移和旋转搞到一个概念里最贴合,拟合态进行比较。 这是初步将两组数据画到图里的情况,和背景需求是一致的。其

    2024年02月15日
    浏览(36)
  • 转换矩阵、平移矩阵、旋转矩阵关系以及python实现旋转矩阵、四元数、欧拉角之间转换

    由于在平时总是或多或少的遇到平移旋转的问题,每次都是现查资料,然后查了忘,忘了继续查,这次弄明白之后干脆写一篇文章,给人方便同时于己方便,后续如有扩充或变动也方便添加。 假设有两个向量 a 1 = ( x 1 , y 1 , z 1 ) a_1 = (x_1, y_1, z_1) a 1 ​ = ( x 1 ​ , y 1 ​ , z 1 ​

    2024年02月03日
    浏览(79)
  • 【OpenCV】图像变换(缩放、平移、旋转、仿射)

    图像变换是指通过对图像进行缩放、平移、旋转、仿射、透视等变换来改变图像的形状和大小。在本篇博客中,我们将详细介绍OpenCV中的图像变换函数,并提供示例代码以帮助读者更好地理解这些函数的使用方法。 缩放变换是指通过改变图像的大小来改变图像的形状。在Op

    2024年02月07日
    浏览(61)
  • Matlab图像的平移,旋转,缩放,裁剪

    %%------------------------Matlab图像的平移,旋转,缩放,裁剪------------------------------- %-------------------头文件----------------------------- clc ; %清屏幕 clear ; %删除所有的变量 close all ; %将所有打开的图片关掉 %--------------------图像平移 imtranslate-------------------------- A = imread(\\\'1.jpg\\\') ; subplot(

    2024年02月04日
    浏览(45)
  • 三维变换矩阵实战——三维点云的旋转、缩放、镜像、错切、平移、正交投影

    旋转矩阵:右边矩阵是点云的原始坐标,左边的是旋转矩阵     可视化:绕x轴旋转90度 代码: 旋转矩阵:    可视化:绕y轴旋转180度 代码: 旋转矩阵:    可视化:绕z轴旋转90度 代码: 旋转矩阵:  线绕哪个轴转,xyz矩阵就和哪和轴的旋转矩阵先计算      可视化:先

    2024年02月04日
    浏览(93)
  • MATLAB图像处理之几何变换——平移与旋转

    可以发现,原图在原坐标基础上向X、Y方向分别平移了50和100个单位。但相应平移的部分也被遮挡了,显然这不符合一些场景的应用需求。 为此,MATLAB还提供了参数设置。在imtranslate函数中设置’OutputView’参数为’full’,即可防止遮挡平移的图像,如下图所示。 MATLAB在进行图

    2024年02月16日
    浏览(47)
  • opencv006图像处理之仿射变换(旋转,缩放,平移)

    空间变换中的仿射变换对应着五种变换,平移,缩放,旋转,翻转,错切。而这五种变化由原图像转变到变换图像的过程,可以用仿射变换矩阵进行描述。而这个变换过程可以用一个2*3的矩阵与原图进行相乘得到。关键就是这个矩阵M:  平移,旋转   透视 M: 变换矩阵 desi

    2024年01月21日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包