連載「デジタル画像処理 -OpenCV/Python」(41) 画像の回転

連載「デジタル画像処理 -OpenCV/Python」(41) 画像の回転


本書の JD 割引購入リンク: https://item.jd.com/14098452.html
本書の CSDN 独占連載コラム: https://blog.csdn.net /youcans/category_12418787.html

ここに画像の説明を挿入します


第6章 画像の幾何学的変換


幾何変換は等角変換、相似変換、アフィン変換、投影変換に分けられます。投影変換とは、画像の位置、サイズ、形状、投影を変換し、元の平面から新しい表示平面に画像を投影することを指します。 OpenCV イメージの幾何学的変換は、基本的に、マッピング関係を通じて多次元配列を別の多次元配列に変換することです。


この章の概要

  • アフィン変換を紹介し、アフィン変換行列を使用して画像のアフィン変換を実現する方法を学びます。
  • 画像を移動、拡大縮小、回転、反転、傾斜させる関数の使用方法を学びます。
  • 射影変換を紹介し、射影変換行列を使用して画像の射影変換を実装する方法を学びます。
  • 画像の再マッピングを紹介し、マッピング関数を使用して画像のカスタム変換と動的変換を実装する方法を学びます。

6.1 画像の回転

回転変換は等角変換であり、変換後も画像の長さと面積は変わりません。
画像は、左上隅 (0,0) を回転中心として時計回りに回転し、回転角度 θ を指定します。回転変換行列 MAR が構築でき、回転変換画像は次のように計算されます。関数 cv.warpAffine。

[ x ~ y ~ 1 ] = M A R [ x y 1 ] , M A R = [ cos θ − sin θ 0 sin θ cos θ 0 0 0 1 ] \begin{bmatrix} \tilde{x}\\ \tilde{y}\ \ 1 \end{bmatrix} = M_{AR} \begin{bmatrix} x\\ y\\ 1 \end{bmatrix} ,\hspace{1em} M_{AR} = \begin{bmatrix} cos \theta & -sin \theta &0\\ sin \theta &cos \theta &0\\ 0 &0 &1 \end{bmatrix} バツそして~ 1 =MAR バツそして1 MAR = cosθsinθ0 sinθcosθ0 001

画像は任意の点 (x, y) を回転中心として取り、回転角度に従って時計回りに回転します。最初に原点を回転中心 (x, y) に移動し、次に原点を回転し、最後に逆平行移動して戻すことができます。座標の原点。

OpenCV の関数 cv.getRotationMatrix2D は、任意の点を中心とした回転変換行列を計算できます。

関数プロトタイプ

cv.getRotationMatrix2D(中心、角度、スケール) → M

関数 cv.getRotationMatrix2D は、回転中心と回転角度に基づいて回転変換行列 M を計算できます。

M = [ α β ( 1 − α ) x − β y − β α β x + ( 1 − α ) y ] M = \begin{bmatrix} \alpha & \beta &(1-\alpha)x-\beta y\\ -\beta &\alpha &\beta x +(1-\alpha)y \end{bmatrix}M=[あるβ bα (1α)xβyβx+(1α)y ]

パラメータの説明

  • center: タプル (x, y) の形式での回転中心の座標。
  • 角度: 回転角度、角度システム、反時計回りの回転。
  • スケール: スケーリング係数、浮動小数点データ。
  • M: 回転変換行列。形状 (2,3) とタイプ np.float32 の Numpy 配列です。

問題に注意してください

  • (1) この関数は、追加の平行移動変換を行わずに、任意の点を中心とする回転変換行列を直接取得できます。

  • (2) 回転後の画像のサイズが元の画像のサイズと同じ場合、四隅のピクセルが切り取られます(図 6-3(2) 参照)。元の画像の内容を保持するには、回転中に画像を拡大縮小するか、回転した画像のサイズを次のように変更する必要があります。

W r o t = w cos θ + h sin θ H r o t = h cos θ + w sin θ W_{rot} = w cos \theta+ h sin \theta \\ H_{rot} = h cos \theta+ w sin \theta =wcosθ+hsinθH =hcosθ+wsinθ
式中の w 、 h はそれぞれ元のイメージの幅と高さ、 、 はそれぞれ回転されたイメージの幅と高さです。

  • (3) 拡大率スケールは回転しながら拡大縮小できますが、水平方向と垂直方向で同じ拡大率を使用する必要があります。

関数 cv.rotate は直角回転に使用され、回転角度は 90 度、180 度、270 度です。このメソッドは行列転置によって実装され、非常に高速に実行されます。

関数プロトタイプ

cv.rotate(src,rotateCode[,dst]) → dst

パラメータの説明

  • src: 入力画像。Numpy 配列です。
  • dst: 出力画像。タイプは src と同じです。画像サイズは回転角度によって決まります。
  • rotateCode: 回転識別子。
    • ROTATE_90_CLOCKWISE: 時計回りに 90 度回転します。
    • ROTATE_180: 時計回りに 180 度回転します。
    • ROTATE_90_COUNTERCLOCKWISE: 時計回りに 270 度回転します。

問題に注意してください

回転角度が 180 度の場合、出力画像のサイズは入力画像のサイズと同じになります。回転角度が 90 度または 180 度の場合、出力画像の高さと幅は入力画像の幅と高さと同じになります。それぞれ入力画像の。


[Routine 0603] 画像の回転

このルーチンは、原点を回転中心として使用する画像の回転、任意の点を回転中心として使用する画像の直角回転を導入します。


# 【0603】图像的旋转
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

if __name__ == '__main__':
    img = cv.imread("../images/Fig0301.png")  # 读取彩色图像(BGR)
    height, width = img.shape[:2]  # 图像的高度和宽度

    # (1) 以原点为旋转中心
    x0, y0 = 0, 0  # 以左上角顶点 (0,0) 作为旋转中心
    theta, scale = 30, 1.0  # 逆时针旋转 30 度,缩放系数 1.0
    MAR0 = cv.getRotationMatrix2D((x0,y0), theta, scale)  # 旋转变换矩阵
    imgRot1 = cv.warpAffine(img, MAR0, (width, height))  

    # (2) 以任意点为旋转中心
    x0, y0 = width//2, height//2  # 以图像中心作为旋转中心
    angle = theta * np.pi/180  # 弧度->角度
    wRot = int(width * np.cos(angle) + height * np.sin(angle))  # 调整宽度
    hRot = int(height * np.cos(angle) + width * np.sin(angle))  # 调整高度
    scale = width/wRot  # 根据 wRot 调整缩放系数
    MAR1 = cv.getRotationMatrix2D((x0,y0), theta, 1.0)  # 逆时针旋转 30 度,缩放系数 1.0
    MAR2 = cv.getRotationMatrix2D((x0,y0), theta, scale)  # 逆时针旋转 30 度,缩放比例 scale
    imgRot2 = cv.warpAffine(img, MAR1, (height, width), borderValue=(255,255,255))  # 白色填充
    imgRot3 = cv.warpAffine(img, MAR2, (height, width))  # 调整缩放系数,以保留原始图像的内容
    print(img.shape, imgRot2.shape, imgRot3.shape, scale)

    # (3) 图像的直角旋转
    imgRot90 = cv.rotate(img, cv.ROTATE_90_CLOCKWISE)  # 顺时针旋转 90度
    imgRot180 = cv.rotate(img, cv.ROTATE_180)  # 顺时针旋转 180度
    imgRot270 = cv.rotate(img, cv.ROTATE_90_COUNTERCLOCKWISE)  # 顺时针旋转 270度

    plt.figure(figsize=(9, 6))
    plt.subplot(231), plt.title("1.Rotate around the origin"), plt.axis('off')
    plt.imshow(cv.cvtColor(imgRot1, cv.COLOR_BGR2RGB))
    plt.subplot(232), plt.title("2.Rotate around the center"), plt.axis('off')
    plt.imshow(cv.cvtColor(imgRot2, cv.COLOR_BGR2RGB))
    plt.subplot(233), plt.title("3.Rotate and resize"), plt.axis('off')
    plt.imshow(cv.cvtColor(imgRot3, cv.COLOR_BGR2RGB))
    plt.subplot(234), plt.title("4.Rotate 90 degrees"), plt.axis('off')
    plt.imshow(cv.cvtColor(imgRot90, cv.COLOR_BGR2RGB))
    plt.subplot(235), plt.title("5.Rotate 180 degrees"), plt.axis('off')
    plt.imshow(cv.cvtColor(imgRot180, cv.COLOR_BGR2RGB))
    plt.subplot(236), plt.title("6.Rotate 270 degrees"), plt.axis('off')
    plt.imshow(cv.cvtColor(imgRot270, cv.COLOR_BGR2RGB))
    plt.tight_layout()
    plt.show()


プログラムの説明:
実行結果と画像の回転を図 6-3 に示します。
(1) 図 6-3(1)~(3) 関数 cv.getRotationMatrix2D を使用して回転変換行列を計算した後、関数 cv.warpAffine を使用して回転変換画像を計算します。図 6-3(1) は画像の原点、つまり左上隅を中心に回転し、図 6-3(2) と図 6-3(3) は画像の中心点を中心に回転します。
(2) 画像サイズはそのままで、中心を回転した後、四隅のピクセルが切り取られます(図 6-3(2) 参照)。スケーリング係数は、回転変換行列を計算するときに使用され、回転された画像が元の画像の内容を保持するようになります (図 6-3(3) を参照)。
(3) 図 6-3 (4) ~ (6) はいずれも直角回転であり、関数 cv.rotate を用いた行列転置により実現されています。


ここに画像の説明を挿入します

*図 6-3 画像の回転


著作権に関する声明:
youcans@xupt のオリジナル作品、再版にはオリジナルのリンクを付ける必要があります: (https://blog.csdn.net/youcans/article/details/134317103) ) 作成日:2023-11-11
Copyright 2023 youcans, XUPT

本書の CSDN 限定連載コラムをフォローしてください。
「デジタル画像処理 - OpenCV/Python」連載: https://blog.csdn.net/youcans/category_12418787.html< /a a>

おすすめ

転載: blog.csdn.net/youcans/article/details/134317103