이미지에서 blur(블러, 흐림 현상)을 확인하는 데 사용되는 다양한 알고리즘과 지표들이 있습니다. 주로 이미지의 선명도, 엣지(경계)의 강도를 측정하여 블러를 평가합니다.

이 평가하는 방법은 2가지가 있습니다.

  1. 원본과 대비가 가능한 경우: With reference image
  2. 원본과 대비가 필요 없는 경우: without reference image

 

이 포스팅에서 without reference image(no refereince image)인 대표적인 지표 및 알고리즘들을 크게 분류하면 다음과 같습니다.

  1. Spatial domain: 방법은 이미지의 픽셀과 인접 픽셀 간의 관계를 계산하여 흐림과 선명한 이미지를 구분하는 기법입니다.
    1. Grayscale Gradient base method: 이미지를 그레이스케일로 변환하여, 인접픽셀과의 그레디언트값(변화도)를 측정합니다. 측정된 변화도가 클수록 또렷한 이미지로 간주됩니다. 대표적으로 Laplacian variance가 있습니다.
  2. Spectral-domain: 이미지의 고주파 성분과 저주파 성분을 분석하여 이미지의 선명도를 평가하는 방법입니다. 고주파 성분은 이미지의 선명한 부분과 관련이 있으며, 세부 정보와 경계 정보를 많이 포함하고 있습니다. 반면 저주파 성분은 흐릿한 부분에 해당합니다
  3. Learning: 머신러닝을 이용한 방법
  4. Combination: 2개 이상의 조합을 이용하는 방법

 

1. Laplacian Variance (라플라시안 분산)

라플라시안 분산은 라플라시안 커널을 이용해서, 이미지의 2차미분을 구해 분산을 구하는 방법입니다. 이 분산이 뜻하는 바는 픽셀의 흩어짐 정도로, 또렷한 이미지일수록 높은 분산값을 가지며, 흐릿한 이미지일수록 낮은 분산값을 가지게 됩니다. 특정한 임계점을 두어 또렷하다, 흐리다라고 판단할 수 있습니다. 

다음의 장점을 지닙니다.

  • 간단하고 빠릅니다.: 계산이 비교적 간단하여 실시간 블러 감지에도 적합합니다.
  • 효과적임: 엣지 정보를 기반으로 하므로 다양한 종류의 블러를 효과적으로 감지할 수 있습니다.
  • 수학적 직관성: 분산을 이용한 접근 방식은 통계적으로도 타당성이 있습니다.

 

2차원 이미지에서는 다음과 같이 표현합니다. 2차미분을 구하기 위해서는 Laplacian kernel을 이용해서 구합니다. 

$\nabla^2 I = \frac{\partial^2 I}{\partial x^2} + \frac{\partial^2 I}{\partial y^2}$

이를 메트릭스 연산으로 표현하면, 라플라시안 커널이 됩니다.

$$\begin{bmatrix}
0 & 1 & 0 \\
1 & -4 & 1 \\
0 & 1 & 0
\end{bmatrix}
$$

import cv2
import numpy as np


def cal_laplacian_variance(image_array: np.ndarray):
    """라플라시안 분산을 구함

    Args:
        image_array (np.ndarray): RGB image array

    Returns:
        float: Laplacian variance
    """

    gray_image = cv2.cvtColor(image_array, cv2.COLOR_RGB2GRAY)
    laplacian = cv2.Laplacian(gray_image, cv2.CV_64F)
    return laplacian.var()

라플라시안 분산은 분산이기에 항상 0또는 양의값을 갖게됩니다. 이런 경계면이 모호한 이미지를 바로 식별할 수 있습니다.

또는 경계면이 또렷한(=focal plane)에 맞게 하는 경우의 이미지도 선택할 수 있습니다.

 

2.  Wavelet-based transform

이미지도 신호기이 때문에, 이를 신호로 처리하는 방법이 있습니다. Spectral-domain에 속하는 방법으로, 이미지를 저주파 및 고주파로 나눕니다. 각각 저주파 고주파는 다시, 저저, 고고, 저고,고저로 나눌 수 있고, 저저를 제외한 나머지 신호 강도를 이용하여 이미지의 선명도를 추출할 수 있습니다.

 

Blur Detection for Digital Images Using Wavelet Transform*이 논문에서도 저저주파를 제외하고 신호강도를 측정합니다.

def cal_wavelet(image_array):
    # 이미지를 그레이스케일로 변환 (이미지가 컬러일 경우)
    if len(image_array.shape) == 3:
        image = cv2.cvtColor(image_array, cv2.COLOR_RGB2GRAY)

    # 2D 웨이브렛 변환 수행 (Haar 웨이브렛 사용)
    coeffs = pywt.dwt2(image, "haar")  # 'haar' 외에도 다양한 웨이브렛 사용 가능
    LL, (LH, HL, HH) = coeffs

    # 고주파 성분 (LH, HL, HH)의 에너지를 합산하여 선명도 측정
    high_freq_energy = (
        np.sum(np.abs(LH) ** 2) + np.sum(np.abs(HL) ** 2) + np.sum(np.abs(HH) ** 2)
    )

    return high_freq_energy
반응형

극좌표계(Polar coordinates)는 평면 위의 점을 나타내는 또 다른 방법으로, 직교좌표계(Cartesian coordinates) 대신 사용됩니다. 직교좌표계에서는 xxyy라는 두 개의 직각 축을 사용해 점의 위치를 나타내지만, 극좌표계에서는 기준점에서의 거리와 기준 방향으로부터의 각도를 사용합니다.

 

극좌표계 개요

  1. 기준점 (원점): 극좌표계에서 기준점은 거리를 측정하는 기준이 되는 점입니다. 이 점은 보통 O로 표시되며, 직교좌표계에서의 원점 (0,0)(0, 0)에 해당합니다.
  2. 거리 (r): 극좌표계의 첫 번째 요소인 r은 기준점 O에서 평면상의 점 P(x,y)까지의 거리를 나타냅니다. r은 항상 0 이상의 값을 가지며, 보통 음수는 허용되지 않습니다. 이 때, 점 P의 위치는 직교좌표계(Cartesian coordinates)에서 (x,y)에 위치해 있습니다.
  3. 각도 (α 또는 θ): 두 번째 요소는 각도 $\alpha$ (또는 $\theta$)입니다. 이는 양의 x축(기준 방향)과 점 P를 연결하는 선분이 이루는 각도를 나타냅니다. 각도는 보통 라디안(radian)으로 측정되지만, 경우에 따라 도(degree)로도 측정될 수 있습니다.

직교좌표계와 극좌표계 간의 변환

직교좌표계 (x,y)에서 극좌표계 (r,α)로 변환하려면:

  • r (반지름 또는 거리)는 다음과 같이 계산됩니다. $r = x^2 + y^2이 공식은 피타고라스 정리에서 유도됩니다.
  • α (각도)는 다음과 같이 계산됩니다:α=atan2(y,x)α . atan2(y, x) 함수는 점 가 이루는 각도를 계산합니다.

극좌표계를 직교좌표계로 변환

극좌표계 (r,α)를 다시 직교좌표계 (x,y)로 변환하려면:

  • **x**는 다음과 같이 계산됩니다:x=rcos⁡(α)x 
  • **y**는 다음과 같이 계산됩니다:y=rsin⁡(α)y 

이미지 처리에서의 활용: 픽셀유동화

이미지 처리 분야에서는 특정 픽셀의 직교좌표 (x,y)를 극좌표 (r,α)로 변환하는 것이 유용할 수 있습니다. 예를 들어, 회전, 스케일링, 또는 특정 영역에서의 왜곡 변환 등을 수행할 때 극좌표계를 사용하면 효율적입니다. 변환 작업이 끝난 후에는 다시 극좌표를 직교좌표로 변환하여 이미지를 출력합니다.

픽셀 유동화(Pixel liquify)은 포토샵에서 특정 픽셀주변을 확장시키거나 줄이는 것을 의미합니다. 알고리즘은 아래와 같습니다.

1. 유동화 알고리즘 메인: 픽셀유동화는 중심점O을 0,0이 아닌 다른 포인트로하여, 유동화를 시킬 수 있습니다. 위의 그림에서, 원의 중심을 O로 생각하고, r만큼 떨어져있는 픽셀을 O와 가까운 중심점으로 옮길 수 있습니다. 이 옮길 때의 위치는 중심점에서 $\sqrt{r}$만큼 옮깁니다.

그렇게되면, 해당픽셀은 중심점O로부터 $\sqrt{r}$ 만 큼 떨어진 픽셀이됩니다. 또는, 움직임의 강도를 c만큼 주어 $c \sqrt{r}$ 만큼 옮길수도있습니다.

2. 거리에 따른 강도조절: 원점에서 가까운점은 덜 움직이고, 가장자리부분을 크게 움직이려면 exponential 함수를 이용하면됩니다. 음수의 지수함수는 x가 커질수록 0에 (거리가 멀수록 덜움직이고), x가 작을수록 큽니다(가까울수록 많이움직임). 

 

아래는 픽셀유동화의 중심점 O을 4곳(좌상단, 중앙부 2곳, 우하단)에 적용한 예시입니다. 모두 극좌표계를 이용해서(중앙점에 상대적인 위치변화) 변경했습니다.

 

반응형

 

요약


DICE loss에서 반영하지 못하는 background의 오분류를 패널티로 반영하기위한 손실함수. Confusion matrix의 요소들을 직접 사용하여 손실함수를 만듬.

 

DICE vs MCC(Mattew's correlation coefficient, MCC)

DICE loss을 사용하든, IoU(Jaccard loss)을 사용하든 둘 다 TN(True negative)에 대한 정보가 없습니다. 

 

이 True Negative을 반영하기위해서, confusion matrix에서 각 요소를 아래와 같이 만듭니다. 즉, TP와 TN은 많이 맞추고, FP,FN은 적은 confusion matrix을 만들기를 바라며, 이를 정규화하기위한 분모로 만듭니다. 아래를 보면 각 요소들이 분모에 2번씩 사용됩니다.

 

MCC은 미분가능한가?

다행히 MCC은 segmentation에서 pixel wise로 연산하기때문에 미분가능합니다. 각 요소를 아래와 같이 표현 할 수 있기 때문입니다.

 

아래와 같이 1-MCC로 손실함수로 사용하고, 각 항목을 y예측값에 대해서 미분하면됩니다.

 

이 식을 pytorch로 구현하면 아래와 같습니다.

class MCCLosswithLogits(torch.nn.Module):
    """
    Calculates the proposed Matthews Correlation Coefficient-based loss.

    Args:
        inputs (torch.Tensor): 1-hot encoded predictions
        targets (torch.Tensor): 1-hot encoded ground truth
    
    Reference:
        https://github.com/kakumarabhishek/MCC-Loss/blob/main/loss.py
    """

    def __init__(self):
        super(MCCLosswithLogits, self).__init__()

    def forward(self, logits, targets):
        """
        
        Note:
            위의 모든 코드가 logits값을 입력값으로 받고 있어서, logtis->confidence [0,1]으로 변경
            MCC = (TP.TN - FP.FN) / sqrt((TP+FP) . (TP+FN) . (TN+FP) . (TN+FN))
            where TP, TN, FP, and FN are elements in the confusion matrix.
        
        
        """
        pred = torch.sigmoid(logits)
        tp = torch.sum(torch.mul(pred, targets))
        tn = torch.sum(torch.mul((1 - pred), (1 - targets)))
        fp = torch.sum(torch.mul(pred, (1 - targets)))
        fn = torch.sum(torch.mul((1 - pred), targets))

        numerator = torch.mul(tp, tn) - torch.mul(fp, fn)
        denominator = torch.sqrt(
            torch.add(tp, 1, fp)
            * torch.add(tp, 1, fn)
            * torch.add(tn, 1, fp)
            * torch.add(tn, 1, fn)
        )

        # Adding 1 to the denominator to avoid divide-by-zero errors.
        mcc = torch.div(numerator.sum(), denominator.sum() + 1.0)
        return 1 - mcc
반응형

딥러닝 모델에서 이미지 분할 작업의 성능을 향상시키기 위해 다양한 손실 함수가 사용됩니다. 이번 글에서는 BCE부터 MCCLoss까지 다양한 손실 함수들을 정리해보겠습니다.

순서와 간단한 요약 아래와 같습니다.

  1. BCE (Binary Cross Entropy): 기본적인 손실 함수 중 하나로, 주로 이진 분류 문제에서 사용되는 함수.
  2. DICE: 두 집합간의 유성을 측정하는 지표입니다. $ \text{DICE}= 2|AUB| / (|A|+|B|)$
  3. Jaccard loss: 두 유사성을 측정하느 또 다른 방법. $\text{Jaccard}=|A \cap B| / |A \cup B|$
  4. Tversky Loss: Jaccard 손실 함수의 가중치 버전.  $\text{Tversky}=\frac{ |A \cap B| }{ |A \cap B| + \alpha |A-B| + \beta |B-A| } $
  5. Focal loss: 클래스 불균형을 해결하기 위한 손실함수 $\text{Focal L}= -\frac{1}{N} \sum_{i=1}^{N}(1-p_{i})^{\lambda}log(p_{i})$
  6. SoftBCEWithLogitsLoss: BCE에 label smoothing이 적용
  7. MCCLoss: Confusion matrix의 각 항목을 지표화 시켜놓은 손실함

 

BCE (Binary Cross Entropy)

기본적인 손실 함수 중 하나로, 주로 이진 분류 문제에서 사용됩니다. BCE는 다음과 같은 수식으로 정의됩니다:

$\text{BCE} = - \frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right]$

여기서 $y_i$는 실제 라벨, $p_{i}$는 예측 확률입니다. BCE는 픽셀 단위로 계산되기 때문에 이미지 분할 문제에도 적용할 수 있습니다.

 

DICE

DICE 손실 함수는 분할 작업에서 자주 사용되는 또 다른 손실 함수입니다. DICE 계수는 두 집합 간의 유사성을 측정하는 지표로, 손실 함수로 사용될 때는 다음과 같이 정의됩니다:

$\text{DICE} = \frac{2|A \cap B|}{|A| + |B|}$

손실 함수로 사용할 때는 1에서 DICE 계수를 뺀 값을 사용합니다. DICE 손실 함수는 미분 가능하여 역전파 과정에서 사용할 수 있습니다. IoU랑 거의 흡사하나, IoU은 Intersection인 $ A \cap B| $에 그치지만, 분자 더 집중할 수 있도록 2배를 하였습니다.

 

Jaccard Loss

Jaccard 계수는 두 집합 간의 유사성을 측정하는 또 다른 방법입니다. Jaccard 손실 함수는 다음과 같이 정의됩니다:

Jaccard 손실 함수 역시 픽셀 단위로 계산되며, 미분 가능하여 역전파 과정에서 사용할 수 있습니다

 

Tversky Loss

Tversky 손실 함수는 Jaccard 손실 함수의 가중치 버전입니다. Tversky 지수는 다음과 같이 정의됩니다:

여기서 $\alpha$ 와 $\beta$ 는 가중치로, 두 값에 따라 민감도를 조절할 수 있습니다.

 

 

Focal Loss

Focal Loss는 클래스 불균형 문제를 해결하기 위해 제안된 손실 함수입니다. Focal Loss는 다음과 같이 정의됩니다:

$ \text{Focal Loss} = - \frac{1}{N} \sum_{i=1}^{N} (1 - p_i)^{\gamma} \log(p_i)$

여기서 $\gamma$ 는 조정 가능한 매개변수로, 일반적으로 2로 설정됩니다. Focal Loss는 특히 어려운 클레스를 학습하는 데 유리합니다.

 

 

SoftBCEWeightLogitLoss

SoftBCEWithLogitsLoss는 label smoothing 기법을 적용한 BCE 손실 함수입니다. 이는 모델이 더 일반화된 예측을 할 수 있도록 도와줍니다. 수식은 다음과 같습니다:

$\text{SoftBCEWithLogitsLoss} = - \frac{1}{N} \sum_{i=1}^{N} \left[ y_i' \log(\sigma(p_i)) + (1 - y_i') \log(1  \sigma(p_i)) \right]$

여기서 $y_i' = y_i (1 - \epsilon) + 0.5 \epsilon$이며, $ \epsilon $은 smoothing 계수, $\sigma$ 은 시그모이드 함수입니다.

 

BCE와의 차이는 라벨($y'$)을 그대로 쓰는게 아니라 [0,1]사이의 값을 사용한다는 것입니다. 이 SoftBCE을 사용하려면 통상의 라벨이 0또는 1이기 때문에, Label을 수정해서 label smoothing을 적용해야합니다.

$\text{BCE} = - \frac{1}{N} \sum_{i=1}^{N} \left[ y_i \log(p_i) + (1 - y_i) \log(1 - p_i) \right]$

 

 

MCC

MCC(Matthews Correlation Coefficient) 손실 함수는 분류 문제에서의 상관 관계를 측정하는 지표로, 다음과 같이 정의됩니다:

여기서 TP는 True Positive, TN은 True Negative, FP는 False Positive, FN은 False Negative를 의미합니다. MCCLoss는 분할 작업에서의 성능을 효과적으로 평가할 수 있습니다.

import torch
import torch.nn.functional as F

def mcc_loss(y_true, y_pred):
    y_pred_pos = torch.round(torch.clamp(y_pred, 0, 1))
    y_pred_neg = 1 - y_pred_pos
    
    y_pos = torch.round(torch.clamp(y_true, 0, 1))
    y_neg = 1 - y_pos
    
    TP = torch.sum(y_pos * y_pred_pos)
    TN = torch.sum(y_neg * y_pred_neg)
    FP = torch.sum(y_neg * y_pred_pos)
    FN = torch.sum(y_pos * y_pred_neg)
    
    numerator = TP * TN - FP * FN
    denominator = torch.sqrt((TP + FP) * (TP + FN) * (TN + FP) * (TN + FN))
    
    return 1 - (numerator / (denominator + 1e-7))  # 1e-7은 ZeroDivision 방지

# 예시 사용법
y_true = torch.tensor([1, 0, 1, 1], dtype=torch.float32)
y_pred = torch.tensor([0.9, 0.1, 0.8, 0.7], dtype=torch.float32)
loss = mcc_loss(y_true, y_pred)
print(loss)

 

반응형

DICE 손실 함수(Dice Loss)는  Sørensen–Dice coefficient 라고도 불리며 주로 의료 영상 분석과 같은 분야에서 세그멘테이션 문제에 많이 사용됩니다. 이 손실 함수는 이진 분류 작업에서 두 샘플 집합의 유사도를 측정하기 위해 사용되며, 특히 불균형한 데이터셋에서 좋은 성능을 보입니다.

DICE 계수는 두 샘플 집합의 유사도를 측정하는데 사용되며, 다음과 같이 정의됩니다:

  1. $|X \cap Y|$: 두 집합의 교집합의 크기입니다.
  2. |X|, |Y|: 각각 집합의 크기입니다.

 

DICE 손실함수

DICE 손실 함수는 1에서 DICE 계수를 뺀 값으로 정의됩니다. 이는 계수가 1에 가까울수록 손실이 작아지며, 예측과 실제 값 사이의 유사도가 높음을 의미합니다. 손실 함수는 다음과 같이 표현됩니다:

DICE Loss=1−DICE

이 손실 함수는 특히 클래스 간 불균형이 클 때 유용하며, 소수 클래스의 중요한 특징을 놓치지 않도록 도와줍니다.

import torch

class DiceLoss(torch.nn.Module):
    def __init__(self, smooth=1.):
        super(DiceLoss, self).__init__()
        self.smooth = smooth

    def forward(self, inputs, targets):
        inputs = torch.sigmoid(inputs)
        intersection = (inputs * targets).sum()
        dice = (2. * intersection + self.smooth) / (inputs.sum() + targets.sum() + self.smooth)
        return 1 - dice

 

DICE loss function의 미분 가능성(differentiable)

객체인식(Object detection)에서의 IoU(Intesection over Union)은 직접 미분이 안되어, 미분 가능한 형태로 변경하여 계산합니다[UnitBox]. Segmentation에서의 DICE score은 미분이 가능합니다. 특히, segementation은 픽셀단위로 계산하기 때문에 예측픽셀과 정답픽셀간의 차이를 직접 계산할 수 있습니다.

DICE loss은 아래와 같이 정의됩니다.

DICE loss = 1- DICE coefficient  (1)

여기서 TP, FP, FN을 아래와 같이 정의할 수 있습니다. 

  • $p_{i}$: predicted probability
  • $g_{i}$: label
  • TP= $\sum_{i} p_{i}g_{i} $ : 예측과 실제가 둘 다 1인 경우
  • FP= $\sum_{i} p_{i}(1-g_{i}) $: 실제가 0일 때, 예측이 1인 경우. $(1- g_{i})$로 indication을 넣음
  • FN= $\sum_{i} (1-p_{i})(g_{i})$: 실제가 1일 떄, 예측이 0인 경우의 합

 

(1)식에서 DICE coefficient만 구하면 loss은 구할 수 있습니다. 따라서, 위를 정의들을 이용하여, DICE coefficient을 다시 정의해보겠습니다.

$\text{DICE coefficient} = \frac{ 2 \sum_{i} p_{i}g_{i} }{\sum_{i} p_{i} + \sum_{i}g_{i} }$

이를 DICE coefficient식에 대입하고 p에 대해서 미분합니다.

$\frac{\partial L}{\partial p_{i}} = \frac{\partial}{\partial p_{i}} (1 - \frac{ 2 \sum_{i} p_{i}g_{i} }{\sum_{i} p_{i} + \sum_{i}g_{i} })$ (2)

$=-\frac{2g_{i} (\sum_{i} p_{i} + \sum_{i}g_{i}) - 2(\sum_{i}p_{i}g_{i})}{(\sum_{i} p_{i} + \sum_{i}g_{i})^{2}}$ (3)

(3)은 나눗셈의 미분으로 계산합니다. 분모는 분모의 제곱으로 들어가고, 분자는 분자미분*분모 + 분자*분모미분으로 계산됩니다. $\frac{f(x)}{g(x)}=\frac{f'(x)g(x) + f(x)g'(x)}{g(x)^{2}} $

 

(3)식을 보면 DICE loss은 예측값 $p_{i}$에 대해서의 미분값이며, gradient descent을 이용하여 최적화가 가능합니다. 이 식은 예측값 $p_{i}$을 얼마만큼 조정하냐에 따라 손실함수가 바뀐다는 것이냐는거고, 다시 딥러닝 parameter에 대해서 미분하는게 필요하니, 체인룰을 이용하여 ($\frac{\partial L }{\partial \theta } = \frac{\partial L }{\partial p_{i}} \frac{\partial p_{i} }{\partial \theta }$)해볼 수 있습니다.

 

 

반응형

 

 

 

회전변환시에 필요한 matrix을 roration matrix라고하며, 2D와 같이 표현할 수 있습니다.

$M(\theta)=
\begin{bmatrix}
    cos\theta & -sin\theta \\
    -sin\theta & cos\theta
\end{bmatrix}$

이 공식의 유도과정을 이해해보겠습니다.

그림1.

위 그림과 같이 구하고자하는 평면에 두 벡터가 있습니다. 이 그림의 요소들은 다음과 같습니다.

  • G(x, y): 회전시키기 전 벡터
  • G'(x',y'): G을 $\theta$만큼 회전시킨 벡터, 
  • r:G벡터와 G'벡터 길이
  • $\theta$: G을 G'으로 반시계방향(counter-clockwise)으로 회전한 벡터

위 그림에 따라 x, y은 아래와 같이 표현할 수 있습니다.

  • $ x=r cos v $  
  • $ y=r sin v $
  • $ x'=rcos(v+\theta)$
  • $ y'=rsin(v+\theta)$

3번 째, 4번째 식의 $ v+\theta$은 삼각함수의 덧셈정리로 풀면 아래와 같습니다.

  • $x'=rcos(v+\theta) = r(cos(v)\cdot cos (\theta) -sin(v)\cdot sin (\theta))$  (코코마사사)
  • $y'=rsin(v+\theta) = r(sin(v) \cdot cos (\theta) + cos(v) \cdot sin(\theta))$ (싸코코)

위 식에서 $cosv$ 와 $sinv$은 이미 알려져 있으니, 대입하여 알 수 있습니다. 

  • $x'=r(x \cdot cos(\theta) - y \cdot sin(\theta))$
  • $y'=r(x \cdot sin(\theta) + y \cdot cos(\theta))$  (x을 앞으로 정렬)

위 식에서 r이 1인 경우는 단순히 선형결합형태이므로, 선형결합 형태로 나타낼 수 있는 메트릭스로 표현 할 수 있습니다.

$\begin{bmatrix} x' \\ y' \end{bmatrix}= 
\begin{bmatrix}
    cos\theta & -sin\theta \\
    sin\theta & cos\theta
\end{bmatrix} \begin{bmatrix} x \\ y \end{bmatrix}$

 

Python implementation


파이썬으로 위의 방법을 구하면 아래와 같이 작성할 수 있습니다. 주의할 것은 여기서 는 각도이며, 여기서는 30도를 라디안 단위로 변환하여 사용해야 합니다.

import numpy as np

# 각도를 라디안으로 변환
theta = np.deg2rad(30)

# 회전 행렬 생성
R = np.array([[np.cos(theta), -np.sin(theta)],
              [np.sin(theta), np.cos(theta)]])

# G 벡터 생성 (임의의 값으로 설정)
G = np.array([1, 0])  # 예를 들어, G = (1, 0)으로 설정

# G' 벡터 계산
G_prime = np.dot(R, G)

print("G' 벡터:", G_prime)
print("회전 행렬:")
print(R)

 

References


https://www.cuemath.com/algebra/rotation-matrix/

반응형

+ Recent posts