Heviside step function $\theta(t)$은 높이가 1인 계단형 함수로 다음과 같이 정의된다.

$$ \theta (t) = \left\{ \begin{matrix}  1 & t\ge 0  \\ 0 & t <0\end{matrix}\right.$$

이 함수의 fourier transform을 구하려 할 때 이 정의 그대로 대입해서는 올바른 결과를 얻을 수 없다. 이를 위해서 $\theta$를 미분하면 delta 함수를 얻을 수 있고, $\delta (t)$를 다음과 같은 Fourier transform 형태로 쓸 수 있음을 이용하자.

$$ \delta (t) = \frac{1}{2 \pi} \int_{-\infty}^\infty e^{- i \omega t} d \omega = \frac{d}{dt} \theta(t) $$ 따라서 적분을 해서 다음과 같이 생각할 수 있다.

$$\theta (t)  \overset{?}{=} \frac{i}{2\pi }  \int_{-\infty}^\infty \frac{e^{-i \omega t}}{ \omega} d \omega$$

그러나 이 적분은 $\omega=0$에서 제대로 정의가 안되므로 이를 회피하는 방법을 고안해야 한다. 이를 위해서 복소평면으로 확장을 한 후 pole의 위치를  $\omega=0$에서 조금 이동해서 $\omega = - i\epsilon~(\epsilon \to 0^+)$이 되도록 하자. 물론 $\omega = +i \epsilon$ 쪽으로도 옮기는 경우도 고려할 수 있지만 이 경우에는 $\theta(-t)$가 된다. 이제 확인해 보도록 하자: $$ \theta(t) = \lim_{\epsilon\to 0^+} \frac{i}{2\pi} \int_{-\infty}^\infty \frac{e^{-i \omega t}}{\omega +i \epsilon} d\omega$$

$t>0$인 경우는 복소평면의 아랫부분을 시계방향으로 도는 경로를 잡아서 적분하면 원호 부분에서는 기여가 없고 residue 정리에 의해서

$$ \frac{i}{2\pi} \oint_\text{lower half} \frac{e^{-i\omega t}}{\omega+i \epsilon}d \omega = (-2\pi i) \frac{i}{2\pi}e^{-it (-i\epsilon)} = e^{- \epsilon t}$$ 

$t<0$일 때는 복소평면 위쪽을 반시계방향으로 회전하는 경로를 잡아서 적분하면 

$$ \frac{i}{2\pi} \oint_\text{upper half} \frac{e^{-i\omega t}}{\omega+i \epsilon}d \omega = 0$$

정리하면 $$  \theta (t) = \lim_{ \epsilon\to 0^+}\left\{ \begin{matrix}   e^{-\epsilon t} & t \ge 0 \\ 0 & t < 0  \end{matrix}\right. $$

따라서 위의 적분이 제대로 된 $\theta(t)$의 한 표현을 제공함을 확인할 수 있다(Note, for $\epsilon>0$, $ \int_{-\infty}^\infty |\theta_\epsilon (t)| < \infty$이어서  Dirichlet condition을 만족시킴). 그런데 이 적분 표현은 Fourier transform의 형태를 가지므로 $\theta(t)$의 Fourier transform은 $\theta(t)=\frac{1}{2\pi}\int \tilde{\theta}(\omega)e^{-i\omega t} d\omega$와 비교하면

\begin{align} \tilde { \theta}(\omega) &=  \lim_{\epsilon\to 0^+ }\frac{i}{\omega + i \epsilon} \\ &=\lim_{\epsilon\to0^+} \frac{ \epsilon+ i \omega}{\omega^2 + \epsilon^2} \\ &=  \lim_{\epsilon\to0^+} \frac{\epsilon}{\omega^2 + \epsilon^2 } - \frac{1}{i\omega} \\ &=\pi \delta (\omega) - \frac{1}{i \omega} \end{align}을 얻는다. 여기서 Lorentzian를 이용한 delta 함수를 표현을 사용했다.

시간 변수에 대한 Fourier transform의 정의로

$$ f(t) = \frac{1}{2\pi} \int_{-\infty}^\infty  {\tilde f}(\omega) e^{i \omega t} d \omega$$

을 사용하는 경우에는 앞의 결과에서 $\omega \to - \omega$를 해서, 

$$ \tilde{\theta}(\omega) = \pi \delta(\omega) + \frac{1}{i \omega}$$

가 된다. 물리적으로는 에너지 연산자가 $i\hbar \partial/\partial t$이므로 시간 변수의 Fourier 변환은 전자의 정의를 사용하고, 운동량 연산자가 $-i \hbar \nabla$이므로 공간 변수에 대한 Fourier 변환은 후자를 사용한다. 그리고 $1/\omega$ 부분의 적분은 Cauchy의 pricipal value prescription을 써서 적분을 해야 한다.

\begin{align} \frac{1}{2\pi} \text{P} \int_{-\infty}^\infty \frac{e^{-i \omega t}}{-i\omega}d\omega &=\frac{1}{2\pi} \lim_{\delta \to 0} \left( \int_{-\infty}^{-\delta} + \int_\delta ^\infty  \right) \frac{e^{-i \omega t}}{- i\omega}d\omega  \\ &= \frac{1}{ \pi }\lim_{\delta\to 0}  \int_\delta ^\infty \frac{\sin (\omega t)}{ \omega }d\omega \\ &=\frac{1}{2} \text{sgn}(t) \end{align}이므로 다음을 얻는다.

$$\frac{1}{2}\left(1 + \text{sgn}(t) \right) = \theta(t)$$

728x90

'Mathematics' 카테고리의 다른 글

Snell's law and Brachistochrone Curve  (0) 2023.01.25
Tautochrone Curve(등시곡선)  (0) 2023.01.16
Integration along a branch cut-015  (0) 2022.12.17
Gibbs Phenomenon  (0) 2022.05.06
Catenary: Rolling Parabolas  (0) 2022.02.03
Posted by helloktk
,

Canny 알고리즘은 영상에서 edge을 찾을 수 있게 설계된 알고리즘으로 여러 단계의 영상 처리 과정으로 구성되어 있다. 일반적으로 edge 검출기는 노이즈에 매우 민감하기 때문에 low pass filter인 Gaussian filter를 적용하여 영상의 노이즈를 제거한다. edge에 해당하는 위치에서는 edge에 수직인 방향으로 gray 값의 변동이 크다는 사실을 이용해서 edge를 찾을 수 있다. 이를 위해서 영상의 gradient field $\nabla g=(g_x, g_y)~$를 구하고, 이를 이용해서 gradient의 크기$\left( |\nabla g|=\sqrt{g_x^2 + g_y^2}\right)$와 방향 정보$\left(\theta = \tan^{-1}(g_y/g_x)\right)$를 얻는다. 대부분의 경우 edge 근방에서 gradient의 크기는 연속적으로 변하므로 edge가 두꺼운 형태가 된다. edge를 한 픽셀 두께로 줄이기 위해서는 gradient 크기의 극대점들을 찾는 추가적인 과정을 거쳐야 한다. 이 추가 처리를 non-maximal suppression이라 하는데, 이는 극대점에서 gradient 방향 또는 그 반대 방향으로 움직이는 경우 gradient 크기가 감소한다는 점을 이용한다. 아래 그림에서 1번 지점이 edge 위에 있으면 gradient 방향(edge 방향에 수직임)의 앞/뒤 지점인 2와 3에서 크기보다 커야 한다.

$$ \text{edge 조건}:~~|\nabla g|_1 > |\nabla g|_2  ~\text{and}~ |\nabla g|_1 > |\nabla g|_3$$

보통 gradient field의 방향을 수평(0, 180도), 수직(90도, 270도), 45도(225도), 135도(325도)로 나누고, 해당 방향의 인접 픽셀에서 gradient 크기를 비교하여 극대점을 판별한다. 주어진 픽셀의 8 방향 근방에서의 gradient  세기는 각각 nn, nw, ww, sw, ss, se, ee, ne로 정의했다. 예를 들면 gradient field의 방향이 거의 수평인 경우(방향이 -22.5~22.5, -180~-157.5, 157.5~180 범위에 들어가는 경우다. 이 경우 edge 방향은 거의 수직) 극대가 되려면  수평 방향의 최근방에서 크기 ee나 ww 보다 더 커야 한다.

void NonmaxSuppress(int radius, int width, int height, 
    std::vector<double> &gradx, std::vector<double> &grady,
    std::vector<int> &edgemap) {
    const double rad2deg = 45.0 / atan(1.0);
    std::vector<double> mag(width * height, 0);
    std::vector<double> dir(width * height, 0);
    int startx = radius, endx = width - radius;
    int starty = width * radius, endy = width * (height - radius); 
    for (int x = startx; x < endx; x++) 
        for (int y = starty; y < endy; y += width) {
            int pos = x + y;
            double gx = gradx[pos, gy = grady[pos];
            mag[pos] = hypot(gx, gy);
            dir[pos] = rad2deg * atan2(gy, gx);
        }
    for (int x = startx; x < endx; x++) { // non-maximal supression
        for (int y = starty; y < endy; y += width) {
            int pos = x + y;            
            double gmag = mag[pos];
            double ang = dir[pos];
            double ww = mag[pos-1];
            double ee = mag[pos+1];
            double nn = mag[pos-width];
            double ss = mag[pos+width];
            double ne = mag[pos-width+1];
            double se = mag[pos+width+1];
            double sw = mag[pos+width-1];
            double nw = mag[pos-width-1];          
            bool bedge = false;
            if ((0 <= ang && ang < 22.5) || (157 <= ang && ang <= 180)
                || (-22.5 <= ang && ang < 0) || ( -180 <= ang < -157.5))
                bedge = (gmag >= ee) && (gmag >= ww); // 수평;
            else if ((22.5 <= ang && ang < 67.5) || (-157.5 <= ang && ang > -112.5))
                bedge = (gmag >= se) && (gmag >= nw); // 45도
            else if ((67.5 <= ang && ang < 112.5) || (-112.5 <= ang && ang > -67.5))
                bedge = (gmag >= nn) && (gmag >= ss); // 수직
            else 
                bedge = (gmag >= sw) && (gmag >= ne); // 135도
            edgemap[pos] = bedge ? int(MAG_SCALE * gmag): 0;
        }
    }
}

gradient field의 방향 정보를 이용한 non-maximal suppression은 atan() 함수의 호출로 인해서 연산 비용이 많이든다. 이를 해소하기 위해서 gradient 방향을 양자화하지 말고 직접 gradient  방향으로 한 픽셀 근방에서 gradient의 크기를 주변 8개 픽셀에서의 gradient 값(nn, nw, ww, sw, ss, se, ee, nw)을 이용해서 구하는 방법을 사용하자. 이 방법을 사용하면 atan()를 호출할 필요가 없어진다. 예를 들면 gradient의 방향이 0에서 45도 사이에 있다고 하자. 그러면 A 점이 극대가 되려면 A에서  gradient 방향의 연장선 상에 있는 한 픽셀 정도 떨어진 지점 B와 C에서 gradient 크기보다 더 커야 한다. B와 C에서 gradient 크기는 주변 8 방향 중에서 가장 가까이 있는 픽셀에서의 크기 ee와 se를 선형보간을 사용해서 얻을 수 있다.

\begin{align} \tt |\nabla g|_B &\approx \tt se* \tan \theta + ee* (1-\tan \theta)~~~(\text{linear interpolation}) \\  &=  \tt se*\frac{gy}{gx} + ee* \left( 1-\frac{gy}{gx} \right)  \\  \tt |\nabla g|_C &\approx \tt nw* \tan \theta + ww* (1-\tan \theta) \\  &= \tt nw*\frac{gy}{gx} + ww* \left( 1-\frac{gy}{gx} \right) \end{align}

극대점 판별을 다음과 같이 쓰면 나눗셈 연산도 피할 수 있다.

$$ \tt |\nabla g|_A \ge  |\nabla g|_B ~~\Leftrightarrow~~  gx * |\nabla g|_A \ge se* gy  + ee*(gx - gy) \\ \tt |\nabla g|_A \ge  |\nabla g|_C ~~\Leftrightarrow~~  gx * |\nabla g|_A \ge nw* gy  + ww*(gx - gy) $$ 

void NonmaxSuppress(int radius, int width, int height, 
    std::vector<double> &gradx, std::vector<double> &grady,
    std::vector<int> &edgemap) {
    std::vector<double> mag(width * height, 0);
    int startx = radius, endx = width - radius;
    int starty = width * radius, endy = width * (height - radius);
    for (int x = starx; x < endx; x++) 
        for (int y = 0; y < endy; y += width) {
            int pos = x + y;
            mag[pos] = hypot(gradx[pos], grady[pos]);
        }
    for (int x = startx; x < endx; x++) { // non-maximal supression
        for (int y = starty; y < endy; y += width) {
            int pos = x + y;            
            double gx = gradx[pos];
            double gy = grady[pos];
            double gmag = mag[pos];
            double ww = mag[pos-1];
            double ee = mag[pos+1];
            double nn = mag[pos-width];
            double ss = mag[pos+width];
            double ne = mag[pos-width+1];
            double se = mag[pos+width+1];
            double sw = mag[pos+width-1];
            double nw = mag[pos-width-1];
            bool bedge = false;
            if (gx * gy > = 0) {//1,3 분면
                if (abs(gx) >= abs(gy)) {//0~45,180~225;
                    double tmp = abs(gx*gmag);
                    bedge = (tmp >= abs(gy*se + (gx-gy)*ee)) && (tmp > abs(gy*nw + (gx-gy)*ww));
                } else {//45~90,225~270;
                    double tmp = abs(gy*gmag);
                    bedge = (tmp >= abs(gx*se + (gy-gx)*ss)) && (tmp > abs(gx*nw + (gy-gx)*nn));
                }
            } else {//2,4 분면
                if (abs(gx) >= abs(gy)) {//135~180, 315~360;
                    double tmp = abs(gx*gmag);
                    bedge = (tmp >= abs(gy*ne - (gx+gy)*ee)) && (tmp > abs(gy*sw - (gx+gy)*ww));
                } else {//90~135, 270~315;
                    double tmp = abs(gy*gmag);
                    bedge = (tmp >= abs(gx*ne - (gy+gx)*nn)) && (tmp > abs(gx*sw - (gy+gx)*ss)); 
                }   
            }
            edgemap[pos] = bedge ? int(MAG_SCALE * gmag): 0;
        }
    }
}

728x90

'Image Recognition > Fundamental' 카테고리의 다른 글

Bilateral Filter  (0) 2024.02.18
영상에서 Impulse Noise 넣기  (2) 2023.02.09
Statistical Region Merging  (0) 2022.06.11
Moment-preserving Thresholding  (0) 2022.05.29
Minimum Cross Entropy Thresholding  (0) 2022.05.29
Posted by helloktk
,

전기 외발 자전거를 타고 반지름 30 미터인 원형 트랙을 일정한 속력 10 m/s로 돌고 있다. 넘어지지 않으려면 수직 방향에 대해 몸을 얼마나 기울여야 하는가?(어느 방향인가?). 

 

  1. 9.65°
  2. 9.79°
  3. 18.8°
  4. 19.9°
  5. 70.1°

풀이:  https://kipl.tistory.com/484의 하단

728x90
Posted by helloktk
,

점성이 없는 유체를 내부에 채운 반지름  $R$인 공이 경사면 위에 올려져 있다. 유체와 공의 질량은 같다. 공이 운동을 시작할 때 가속도는? 단, 물체는 미끄러짐이 없이 경사면을 구르면서 내려간다.

 

 

  1. $g \sin \alpha$
  2. $\frac{3}{4} g \sin \alpha$
  3. $\frac{1}{2} g \sin \alpha$
  4. $\frac{3}{8} g \sin \alpha$
  5. $\frac{3}{5} g \sin \alpha$

풀이는 https://kipl.tistory.com/483 하단

728x90
Posted by helloktk
,

고유길이가 $L$인 열차가 일정한 속도 $v$로 왼쪽에서 오른쪽으로 움직인다. 열차의 앞과 뒤에는 벽시계가 있고 밖에서 볼 수 있다. 철로변 모든 지점에 사진을 찍을 수 있도록 카메라가 일렬로 설치되어 있다고 하자. 이들 카메라가 동시에 사진을 찍었을 때 사진 속에 보이는 열차 앞과 뒤의 시계 바늘은?

1. 앞과 뒤 시계의 바늘은 동일하게 가리킨다.

2. 앞 시계 바늘이 뒷 시계 바늘보다 앞선다.

3. 뒤 시계 바늘이 앞 시계 바늘보다 앞선다.

728x90
Posted by helloktk
,