sticky header와 sticky footer 만들기(html과 css으로)

프로그래밍/웹코딩|2020. 6. 1. 13:01

안녕하세요. 비스카이비전입니다. ;D 오늘은 html과 css만으로 sticky header와 sticky footer를 만들어보도록 하겠습니다. 우선 결과물로 sticky header와 sticky footer가 무엇인지 설명드리도록 하겠습니다.

 

클릭해서 보세요.^^

 

보시는 것처럼 스크롤을 내리더라도 화면의 상단에 고정되어 있는 것을 sticky header라고 하고, 화면의 하단에 고정되어 있는 것을 sticky footer라고 합니다. sticky는 "달라붙는" 이런 뜻을 가진 단어입니다. 

 

위와 같이 레이아웃을 만드시려면 html과 css를 각각 다음과 같이 작성하시면 됩니다. 

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <link rel="stylesheet" href="style.css">
</head>
<body>
    <div id="header">
        sticky header
    </div>

    <p>시작!! 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 안녕하세요. 비스카이비전입니다. 끝!!</p>
    
    <div id="footer">
        sticky footer
    </div>

</body>
</html>

 

style.css

#header, #footer {
    background-color: skyblue;
    padding: 8px;
    height: 40px;
    font-size: 20px;
}

#header {
    position: sticky;
    top:0;
}

#footer {
    position: fixed;
    bottom:0;
    width: 100%;
}

body {
    margin: 0;
}

p {
    margin: 8px;
    padding-bottom: 60px;
}

 

sticky header와 sticky footer를 만드는데 있어서 핵심은 css의 position 속성을 사용하는 것입니다. 저는 sticky header를 만들 때는 position 속성의 값을 sticky로 해줬고, sticky footer를 만들 때는 fixed로 해줬습니다. 그리고 top: 0과 bottom:0으로 각각 상단과 하단에 위치할 것을 명령해줬습니다. 

 

sticky header와 sticky footer는 웹페이지 뿐만아니라 웹앱(Web App)을 만들 때 활용해도 좋을 것 같습니다. 

  1. BlogIcon IT's me 2020.06.01 15:17 신고 댓글주소  수정/삭제  댓글쓰기

    그냥 고정 헤더, 고정 푸터라고 말했었는데 스티키 헤더와 스티키 푸터 용어 잘 알아갑니다. ^^.

  2. BlogIcon 동네공대형 2020.06.01 15:37 신고 댓글주소  수정/삭제  댓글쓰기

    제가 쓰는 스킨도 헤더가 고정되는 형태더라구요. fixed로 되어 있어서 sticky하고 fixed 차이 찾다가 뷰포트가 나오고 스크롤박스가 나오고.. 점점 혼미해지다가... 갑니다. 그래도 동작 원리(개념)은 알고 갑니다. 감사합니다. ^^

선형보간법(linear interpolation)과 삼차보간법(cubic interpolation), 제대로 이해하자


선형보간법(linear interpolation)에 대해서는 잘 설명된 자료가 많지만, 삼차보간법(cubic interpolation)에 대해서는 읽을 만한 괜찮은 자료를 찾기가 쉽지 않습니다. 아마도 삼차보간법에 대해 글을 쓰신 분들도 완벽하게 원리를 이해하고 쓴 것이 아닌 것 같습니다. 아인슈타인이 이렇게 말했죠. "만약 당신이 무엇인가를 쉽게 설명할 수 없다면, 그것을 제대로 이해한 것이 아니다." 이 글이 삼차보간법과 쌍삼차보간법을 이해하는데 있어 여러분들께 통찰력을 제공하길 바랍니다. 

 

우선 보간법(interpolation)이라는 것이 무엇인지 간략히 설명하고 넘어가겠습니다. 보간법이란 알려진 값을 가진 두 점 사이 어느 지점의 값이 얼마일지를 추정하는 기법을 의미합니다. 아래 그림을 보시면 a와 b사이에 위치한 x의 값, 즉 f(x)가 무엇인지를 추정하는 것이 바로 보간법입니다. 

 

보간법이란?

 

선형보간법(linear interpolation)

보간법에는 여러가지 접근법이 있는데, 그중 비교적 간단한 선형보간법은 두 점 사이에 직선을 그립니다. 그리고 그 선을 이용해서 f(x)를 추정합니다. 다음 그림과 같이 말이죠. 

 

선형 보간법(linear interpolation)

 

두 점의 좌표를 알면 1차 함수식을 만들 수 있죠? y = mx + n에 두 좌표값을 대입시키면 그 1차 함수식을 찾아낼 수 있습니다. 그러면 결과적으로 다음과 같은 함수식이 도출됩니다. 

 

$y = \frac{f(a)-f(b)}{a-b}x+\frac{af(b)-bf(a)}{a-b}$

 

식이 복잡해보인다고 겁먹지 마세요.^^ 어려운 것 아닙니다. 중요한 것은 일차함수식을 찾아냈다는 것입니다. 일차함수식을 찾아냈기 때문에, a와 b 사이의 어떤 점 x의 함수값, 즉 f(x)도 그 식에 대입함으로써 알아낼 수 있습니다. 이것이 바로 선형보간법의 핵심입니다. 기억해야할 것은 선형보간법에서는 값을 추정할 때 두 개의 점을 참조했다는 점입니다.  

 

삼차보간법(cubic interpolation)

보간법에는 다양한 접근법이 존재한다고 했습니다. 그 중 하나가 방금 설명한 선형보간법이었습니다. 선형보간법은 1차 함수를 활용한 것이었죠? 이제 설명드릴 삼차보간법은 3차(cubic) 함수를 활용합니다. 삼차보간법은 우리가 알고 있는 두 점 a, b가 삼차함수 그래프 위에 있다고 가정합니다. 다음과 같이 말이죠. 

 

3차 보간법(cubic interpolation)

 

이렇게 3차 함수를 이용해서 미지의 값을 추정하면 일차 함수를 통해 찾는 것보다 훨씬 더 부드러운 결과를 만들어낼 수 있습니다. 직선이 아닌 곡선을 이용하기 때문이죠. 문제는 이 3차 함수 $f(x) = mx^3 + nx^2 + jx + k$를 알아내야 한다는 점입니다. m, n, j, k를 찾아내야 한다는 뜻이죠.

 

문제를 간단하게 만들기 위해서 $a = 0$, $b =1$이라고 가정하고 출발하겠습니다. 그리고 $f(0) = y_0$, $f(1) = y_1$로 놓겠습니다. 

 

 

자, 그럼 함께 m, n, j, k를 계산해봅시다. 우선 k는 쉽게 구할 수 있겠네요. f(x)에 0을 대입하면, f(0) = k가 나옵니다. k는 이미 알고 있는 값인 $y_0$입니다. 

 

$k = y_0$   ...(1)

 

이제 네 개 중에 하나 구했습니다. 이번엔 f(x)에 1을 대입해볼까요? 그러면 다음과 같은 식을 얻을 수 있습니다. 

 

$f(1) = m + n + j + k = y_1$

 

여기서 k는 아까 $y_0$임을 알았으니 대입해서 정리하면 미지수가 세 개인 방정식을 하나 얻게 됩니다.

 

$m + n + j = y_1 - y_0$   ...(2)

 

미지수가 세 개인 방정식이 세 개 있으면 연립해서 그 미지수들을 모두 구할 수 있죠? 그것을 위해 f(x)를 x에 대해 미분한 후에 0과 1을 각각 대입시켜보겠습니다. 그러면 방정식을 두 개 얻을 수 있겠죠? 우선 f(x)를 미분하면, 다음과 같이 됩니다. 

 

$f'(x) = 3mx^2 + 2nx + j$

 

그 다음에 0과 1을 각각 대입하면, 

 

$f'(0) = j$  ...(3)

$f'(1) = 3m + 2n + j$  ...(4)

 

과 같은 방정식들이 도출됩니다. 이제 세 개의 방정식이 생겼으니 연립해서 풀면 됩니다. 그런데 연립방정식을 풀기 위해서는 먼저 f'(0)과 f'(1)을 알아야합니다. 우리가 다루는 데이터가 연속적(continuous)인 경우라면 미분해서 값을 넣어주면 되지만, 이산적(discrete)인 경우에는 다음과 같이 미분값들을 구할 수 있습니다. 기울기(미분값)는 y의 증가량을 x의 증가량으로 나눠준 것임을 중학생 때 배웠던 것 같습니다.  

 

$f'(0) = \frac{y_1 - y_{-1}}{2}$

$f'(1) = \frac{y_2 - y_0}{2}$

 

따라서 우리는 $(0, y_0)$, $(1, y_1)$말고도, 추가적으로 두 점 $(-1, y_{-1}), (2, y_2)$도 참조해야합니다. 그래서 삼차보간법은 이웃한 두 개를 참조하는 선형보간법과 달리 네 개의 점을 참조합니다.  

 

삼차보간법은 4개의 이웃점을 필요로 한다.

 

이제 f'(0)과 f'(1)을 방정식 (3), (4)에 각각 대입하겠습니다.

 

$j = \frac{y_1 - y_{-1}}{2}$   ...(3)

$3m + 2n + j = \frac{y_2 - y_0}{2}$   ...(4)

 

이 과정에서 j도 알게 되었네요. 방정식 (2)와 (4)에 j를 대입해서 나머지 m, n을 구해봅시다. 먼저 j를 대입하면 방정식 (2), (4)가 다음과 같이 정리됩니다. 

 

$m + n = \frac{y_{-1} - 2y_0 + y_1}{2}$   ...(2)-1

$3m + 2n = \frac{y_{-1} - y_0 - y_1 + y_2}{2}$   ...(4)-1

 

이 친구들을 연립해서 풀면, m과 n을 구할 수 있습니다. 구했더니 이렇게 나오네요. 

 

$m = - \frac{y_{-1}}{2} + frac{3}{2}y_0 - \frac{3}{2}y_1 + \frac{y_2}{2}$   ...(2)-2 

$n = y_{-1} - \frac{5}{2}y_0 + 2y_1 - \frac{y_2}{2}$   ...(4)-2

 

드디어 우리가 알아야할 m, n, j, k를 모두 찾아냈습니다. $f(x) = mx^3 + nx^2 + jx + k$를 찾아낸 것이죠. 0과 1사이에 존재하는 어떤 x의 함수값, f(x)도 우리는 이제 이 함수를 이용해서 추정할 수 있습니다. 이것이 바로 삼차보간법입니다. 다시 한번 말하지만 수식은 중요하지 않습니다. 이렇게 전개된다는 것 정도만 알고 계시면 됩니다. 

 

쌍선형보간법(bilinear interpolation)과 쌍삼차보간법(bicubic interpolation)

선형보간법을 2차원으로 확장시킨 것이 바로 쌍선형보간법이고, 삼차보간법을 2차원으로 확장시킨 것이 쌍삼차보간법입니다. 2차원으로 확장시킨 것 외에 원리상 달라진 것은 없습니다. 쌍선형보간법은 이웃한 4(=2x2)개의 점을 참조하고, 쌍삼차보간법은 16(=4x4)개의 점을 참조합니다. 

 

 

이제 마무리 인사를 드릴 시간이네요. 끝까지 읽고 생각하시느라 수고하셨습니다. 블로그를 운영하면서 알게된 진리는 "힘들게 쓴 글은 독자들이 알아준다"는 것입니다. 이 글도 꽤 어렵게 썼습니다. 따라서 이 글도 누군가 알아주실 것을 기대하며 글을 마칩니다.^^ 항상 질문과 지적은 환영입니다. 댓글로 남겨주시면 빠르게 답변드리도록 하겠습니다. 

 

 

이 글도 한번 읽어보세요 ☞

초해상화(Super-resolution)란? 저화질 영상을 고화질로 바꿔주는 기술

[MATLAB] 이미지 크기 조정하기, imresize 함수

[python] opencv-python 패키지 유용한 함수 10개 정리

 

 

<참고자료>

[1] https://dsp.stackexchange.com/questions/18265/bicubic-interpolation, stackexchange, "bicubic interpolation"

[2] https://darkpgmr.tistory.com/117, 다크프로그래머, "선형 보간법"

[MATLAB] 이미지 크기 조정하기, imresize 함수

프로그래밍/MATLAB|2020. 5. 29. 12:21

안녕하세요. 비스카이비전입니다. ;D 오늘은 매트랩을 이용해서 이미지 크기를 확대시키거나 축소시키는 것에 대해서 다우도록 하겠습니다. 이를 위해서는 imresize라는 함수를 사용하시면 됩니다. 

 

imresize 함수로 이미지의 크기를 조정하는 것은 크게 두 가지 방법으로 할 수 있습니다. 

 

1. 구체적인 사이즈를 설정하기

2. 배율을 설정하기

 

자, 그럼 예시를 통해 하나씩 어떻게 하는지 살펴보도록 하겠습니다. 

 

 

1. 구체적인 사이즈를 정해주기

265 x 400 크기의 이미지를 200 x 200, 800 x 600 사이즈로 바꿔보겠습니다. 필요한 코드는 다음과 같습니다. 

 

clc, clear, close all

img = imread('test.JPG');

figure(1)
imshow(img);

img1 = imresize(img, [200, 200]);
img2 = imresize(img, [800, 600]);

figure(2)
imshow(img1)
figure(3)
imshow(img2)

  

실행결과 다음과 같이 이미지 크기가 조정되었습니다. 원본이미지부터 200 x 200으로 사이즈가 조정된 이미지, 800 x 600으로 조정된 이미지 순입니다. 

 

 

 

2. 배율을 정해주기

이번에는 동일한 테스트 이미지를 가지고 2배만큼 축소 또는 확대해보겠습니다. 구체적인 사이즈를 정하는 대신에 배율을 정해줌으로 사이즈를 조정할 수도 있습니다. 필요한 코드는 다음과 같습니다. 

 

clc, clear, close all

img = imread('test.JPG');

figure(1)
imshow(img);

img1 = imresize(img, 1/2); % 2배만큼 축소
img2 = imresize(img, 2); % 2배만큼 확대

figure(2)
imshow(img1)
figure(3)
imshow(img2)

 

코드를 실행하시면 다음과 같은 결과가 나타납니다. 2배만큼 잘 축소되고, 또 잘 확대되었죠? 

 

 

끝까지 읽어주셔서 감사합니다! 

 

 

 

지각(perception)과 인지(cognition)의 차이 이해하기


컴퓨터비전과 영상처리는 기본적으로 사람이 눈을 통해 본 것을 뇌가 어떻게 처리하는지를 모방하는 연구분야이기 때문에 사람의 눈과 뇌에 대해 이해하는 것은 매우 중요합니다. 그러다보니 해부학, 심리학, 신경과학, 인지과학 등과 관련된 논문도 종종 읽곤 합니다. 이 분야들 같은 경우 다른 것을 떠나서 용어가 너무 어렵습니다. 사전 찾아보기 바쁘다고 해야할까요. 

 

오늘은 제가 자주 접했지만 정확하게 개념을 내리지 못했던 두 용어에 대해 정리하고자 합니다. 바로 지각(perception)과 인지(cognition)입니다. 저는 거의 두 단어를 혼용했는데, 분명히 차이가 있는 단어라는 것을 최근에야 알게 되었습니다. 

 

지각은 주변 환경으로부터 받아들인 감각 정보를 식별하고 해석하는 것을 의미합니다. 즉, 지각이란 보거나 듣거나 만지거나 냄새맡거나 함을 통해 얻은 감각 정보를 해석함을 통해 주변 세상을 이해하는 것을 뜻합니다. "바다가 보이네!", "BTS 노래가 들리네.", "이건 흙의 질감이야", "짜장면 냄새가 나는군!"

 

반면 인지는 모든 정신적인 활동을 포함하는 개념입니다. 무언가에 집중하고, 무언가를 기억하고, 무언가를 지각하고, 언어를 사용하고, 문제를 해결하고, 이런 것들이 모두 인지 활동에 포함됩니다. 따라서 지각은 인지의 부분집합이라고 할 수 있겠습니다. 

 

지각은 인지의 하위 개념이다.

 

지각과 인지를 이해하시는데 이 글이 통찰력과 힌트를 제공했길 바라며 글을 마치도록 하겠습니다. 항상 질문과 지적은 환영합니다. 댓글로 남겨주시면 최대한 빠르게 답변드리도록 하겠습니다. 감사합니다.^^  

반응형 웹페이지 기본 틀 만들기(그리드, 미디어쿼리 활용)

프로그래밍/웹코딩|2020. 5. 26. 16:05

안녕하세요. 비스카이비전을 방문해주신 모든 분들을 환영합니다. 오늘은 반응형 웹페이지의 기본 틀을 만들어보겠습니다. 동기부여를 위해 우선 결과물을 보여드리고 시작하겠습니다. 화면의 크기를 줄이다보면 어느 순간 사이드바 영역이 본문 영역 아래로 내려가는 형태의 반응형 웹페이지입니다.  

 

클릭해서 보세요.^^

 

위와 같은 웹페이지를 만드려면 html 코드와 css 코드가 필요합니다. 이 둘은 같은 폴더 내에 있어야 합니다. 먼저 html 코드는 다음과 같습니다.

 

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <link rel="stylesheet" type="text/css" href="./style.css">
</head>
<body>
    <h1>bskyvision</h1>
    
    <div id="main">
        <div id="contents">본문 영역입니다.</div>
        <div id="sidebar">사이드바 영역입니다.</div>
    </div>

    <div id="footer">푸터 영역입니다.</div>
</body>
</html>

 

또한 css 코드는 다음과 같습니다. 

 

style.css

h1 {
    text-align:center;
}

div {
    font-size: 30px;
    text-align: center;
}

#main {
    display: grid;
    grid-template-columns: 3fr 1fr;    
}

#main #contents {
    min-height: 500px; 
    background-color:#00ffff; 
    margin-right: 10px;
}

#main #sidebar {
    min-height: 500px; 
    background-color: #00bfff;
}

#footer {
    margin-top: 10px; 
    background-color: #00bfff;
}


@media (max-width:600px){ /*가로 너비가 600px 이하일 때 아래 스타일 적용*/
    #main {
        display: block;    
    }

    #main #contents {  
        margin-bottom: 10px; 
        margin-right: 0px;
    }
    #main #sidebar {
        min-height: 0;
    }

}

 

여기서 핵심은 미디어 쿼리라는 것을 사용하는 점입니다. 미디어 쿼리는 보통 반응형 웹을 만들 때 사용하는 기술입니다. 위 css 코드에서 @media 로 시작하는 부분을 의미합니다. 미디어 쿼리를 사용함을 통해서 "가로 너비가 600px 이하일 때 사이드바가 본문 아래로 내려오게 한다"와 같은 기능을 실현시킬 수 있습니다. 즉, 반응하는 웹을 만들 수 있는 것이죠. 

 

이것을 기본틀로 해서 나름대로 유용한 웹사이트를 만들 수도 있겠죠? 웹페이지 만드는 것 독학해가는 재미가 쏠쏠하네요. ㅎㅎ

 

 

<참고자료>

[1] https://aboooks.tistory.com/368?category=516604, 지구별 안내서, "CSS로 반응형 웹사이트 (소스) 만들기: 사이드바가 본문 아래로 떨어지게"

[2] https://ccuram.tistory.com/30, yucalip, "[HTML/CSS] 화면의 크기와 환경을 감지하는 기술, 미디어 쿼리 (Media Queries)"

 

 

최소식별차(just-noticeable-difference)와 영상압축


안녕하세요. 비스카이비전입니다.^^ 오늘은 최소식별차가 무엇인지, 그것이 영상압축에 왜 활용이 가능한지에 대해 이야기하도록 하겠습니다. 

 

우리가 감지할 수 있는 최소한의 차이를 최소식별차(JND, just-noticeable-difference)라고 부릅니다. 예를 들어, 초록색이 있고 그것보다 조금 더 진한 초록색이 있습니다. 너무 차이가 없으면 우리는 같은 색으로 인지합니다. 그런데 어느 정도 차이가 생기면 우리는 차이가 있다고 느낍니다. 딱 바로 차이를 느끼는 그 순간의 차이를 바로 JND라고 합니다.

 

 

JND의 이해를 돕기 위해 다른 예를 하나 더 들어보겠습니다. 음식을 만들고 있습니다. 간이 맞지 않아서 소금을 더 넣었습니다. 그런데 차이가 느껴지지 않습니다. 그래서 소금을 좀 더 넣었습니다. 이제 차이가 느껴집니다. 짭짤함의 차이가 느껴지기 시작하는 그 순간의 차이가 바로 JND인 것입니다. 

 

그러니까 우리의 오감은 꽤 민감하지만, 아주 작은 차이를 다 느낄 정도로 민감하진 않다는 뜻입니다. 자극의 세기가 어느 정도 차이가 생겨야 그 차이를 느낄 수 있습니다. 이럴 때 보면 마치 사람도 디지털 기계와 같이 이산적(discrete)으로 작동하는 시스템같습니다. 

 

어떤 연구자들은 이러한 JND를 영상 압축(compression) 기술에 적용했습니다[1]. 영상 내 모든 픽셀의 JND가 동일하지는 않다는 점에 착안한 것입니다. 다른 말로, 영상 내에 각 부분의 JND가 모두 다르다는 것을 이용한 것입니다. 예를 들어, 하늘과 같은 비교적 평탄한 부분에서는 JND가 매우 작은 반면, 질감이 센 부분에서는 JND가 상대적으로 큽니다. 따라서 JND가 큰 부분의 정보는 손실시켜도 사람이 쉽게 인지하지 못합니다. 그러한 부분의 정보를 그렇지 않은 부분보다 좀 더 손실시킴으로써 용량을 줄이는 것이죠. 

 

기존의 JPEG와 같은 손실압축방식은 영상 내 모든 부분을 동일하게 압축합니다. 따라서, 유독 하늘과 같은 평탄한 부분의 손실이 잘 느껴졌죠. 아래 사진은 JPEG 방식으로 심하게 손상된 사진입니다. 자유의 여신상 위에 존재하는 손실은 쉽게 인지되지 않지만, 하늘 부분의 손실은 쉽게 인지됨을 알 수 있습니다.  

 

JPEG 압축으로 손상된 이미지, 출처: [2]

 

만약 JND를 고려해서 영상을 압축시킨다면, 하늘과 같이 평탄한 부분은 조금 덜 손상시키고, 자유의 여신상 부분과 같이 질감이 센 부분은 좀 더 손상시킬 수 있겠죠. 그러면 위 JPEG 압축의 경우보다는 사람들이 영상 품질에 대해 괜찮게 느낄 것입니다. 

 

bskyvision.com에 방문해 주시고, 이 글을 끝까지 읽어주셔서 감사합니다. 항상 질문과 지적은 환영합니다.^^ 

 

 

<참고자료>

[1] Chen, Zhenzhong, and Christine Guillemot. "Perceptually-friendly H. 264/AVC video coding based on foveated just-noticeable-distortion model." IEEE Transactions on Circuits and Systems for Video Technology 20.6 (2010): 806-819.

[2] http://vision.eng.shizuoka.ac.jp/mod/page/view.php?id=23, CSIQ 데이터베이스

[python] 메모장에 데이터 쓰고, 추가하고, 읽기

프로그래밍/python|2020. 5. 23. 15:16

메모장에 글을 쓰려면(write), 우선 텍스트 파일을 쓰기 모드("w")로 열어야합니다. 그 다음에 print 함수를 이용해서 쓰고자 하는 내용을 그 열려있는 텍스트 파일에 써줍니다. 그리고 마지막에는 파일을 닫아줍니다. 다음과 같이 코딩하시면 됩니다. 

 

 

그리고 메모장에 글을 추가하려면(append), 텍스트 파일을 추가 모드("a")로 열어야합니다. 그리고 print 함수를 이용해서 추가하고자 하는 내용을 그 텍스트 파일에 써주면 파일의 마지막 부분에 추가됩니다. 

 

 

또한 메모장에 쓰여져 있는 글을 읽으려면(read), 텍스트 파일을 읽기 모드("r")로 연 후에, readlines 함수를 사용해서 파일 내 모든 줄을 읽어냅니다. 그러면 각 줄이 리스트의 요소로 하나씩 담깁니다.

 

 

끝까지 읽어주셔서 감사합니다. 항상 질문과 지적에는 열려 있으니, 댓글 남겨주세요.^^ 

[python] 파이썬 유용한 내장 함수들 10개 정리

프로그래밍/python|2020. 5. 23. 14:34

파이썬에는 어떤 패키지나 모듈을 설치하지 않아도 사용할 수 있는 함수들이 매우 많이 있습니다. 그 중 유용하다고 생각되는 것들을 정리해보도록 하겠습니다. 예제만으로도 충분하게 설명된다고 생각하는 함수들에 대해서는 따로 설명을 덧붙이진 않겠습니다. 

 

 

1. 리스트 내 원소 갯수, 크기 반환: len()

 

 

2. 자료형 확인: type()

 

 

3. 문자형 자료형 숫자형으로 변환: int()

 

 

str 형이 int 형으로 바뀌었죠? 

 

4. 숫자형 자료형 문자형으로 변환: str()

 

 

이번엔 반대로 int 형이 str 형으로 바뀌었습니다.

 

5. 반올림: round()

 

 

보시는 것처럼 소숫점 아래 첫번째 자리까지 반올림도 가능하고, 두번째 자리까지 반올림도 가능하고, 소숫점 위 첫번째 자리, 두번째 자리 등으로 반올림하는 것도 가능합니다. 

 

6. 절대값: abs()

 

 

7. 최대값, 최소값: max(), min()

 

 

8. 크기 순으로 정렬: sorted()

 

 

보시는 것처럼 내림차순 정렬도 가능합니다. 

 

9. 리스트 원소의 합: sum()

 

 

10. for 문에 자주 사용되는 range()

 

 

0부터 시작해서 1씩 늘어나서 10개의 숫자를 순차적으로 출력해줌을 알 수 있습니다. 2씩 증가시킬 수도 있습니다. 

 

끝까지 읽어주셔서 감사합니다. 질문과 지적은 항상 환영합니다. 댓글로 남겨주세요.^^ 

 

 

이 글도 한번 읽어보세요 ☞

[python] numpy 패키지 유용한 함수들 10개 정리

[python] numpy 다차원배열 클래스 객체 유용한 메소드 20개 정리

[python] opencv-python 패키지 유용한 함수 10개 정리

 

 

<참고자료>

[1] https://data36.com/python-built-in-functions-methods-python-data-science-basics-3/, data36, "Python Built-in FUnctions and Methods (Pyton for Data Science Basics #3)"

[python] 함수(function)와 메서드(method)의 차이, 간단 설명

프로그래밍/python|2020. 5. 22. 20:32

프로그래밍 언어에 있어서 함수(function)라는 것은 어떠한 기능을 수행하는 친구입니다. 각 함수마다 나름의 기능을 가지고 있습니다. 두 수를 입력받아 덧셈을 수행하는 함수가 있을 수 있고, 소요된 시간을 측정하는 기능을 담당하는 함수도 있을 수 있고, 수많은 남자와 여자 중에 어울리는 한쌍을 찾아주는 함수도 있을 수 있습니다. 코딩의 세계에는 수억개, 수조개의 함수가 있습니다. 현존하는 함수의 수는 절대 셀 수 없습니다. 지금도 누군가는 열심히 함수를 만들어내고 있기 때문입니다. 

 

또한 함수와 헷갈리기 쉬운 메서드(method)라는 친구도 있습니다. 메서드도 함수처럼 어떠한 기능을 수행하는 친구입니다. 차이가 있다면 메서드는 클래스 및 객체(object)와 연관되어 있는 함수라는 것입니다. 클래스 내에 선언되어 있는 함수가 바로 메서드입니다. 즉, 클래스 및 객체와 연관되어 있는 것이라면 메서드고, 그것들과 상관없이 독립적으로 존재하는 것은 함수입니다. 함수가 메서드보다 더 큰 개념이라고 생각할 수 있습니다. 그래서 메서드를 부를 때 포괄적으로 함수로 지칭하기도 합니다. 

 

 

함수는 sum(), abs() 같이 독립적으로 사용되는 반면, 메서드는 a라는 객체가 존재할 때 a.upper(), a.lower()와 같은 형태로 사용됩니다. 

 

 

<참고자료>

[1] https://www.geeksforgeeks.org/difference-method-function-python/, GeeksforGeeks, "Difference between Method and Function in Python"

[MATLAB] 숫자와 문자의 조합으로 구성된 문자열에서 숫자와 문자를 각각 추출하려면? (질문에 대한 답변)

프로그래밍/MATLAB|2020. 5. 22. 11:50

예전에 작성한 글인 "[MATLAB] 문자열에서 필요한 데이터만 추출하기, sscanf 함수"에 김진성님께서 질문을 남기셨는데 댓글로 설명하긴 조금 길어서 글을 하나 작성합니다. 

 

질문은 바로 이것이었습니다. 

 

"혹시 53423초보자4536 같은 숫자문자숫자 조합 데이터를 53423/초보자/4536 와 같이 숫자/문자/숫자로 나눌 수 있는 방법이 있을까요?"

 

질문을 요약하자면, 숫자와 문자의 조합으로 구성된 문자열에서 숫자와 문자를 각각 나눠서 추출하는 방법에 대한 질의입니다. 

 

이를 가능케 하는 코드를 작성해봤습니다. 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
clc, clear, close all
 
str = '53423초보자4536';
 
len = strlength(str);
 
TF = isstrprop(str'digit');
 
check = TF(1);
starts = [];
for i = 1:len
    if TF(i) ~= check
        starts = [starts, i];
        check = TF(i);
    end
end
 
ends = [starts - 1len];
 
ends_nums = size(ends, 2);
 
begin = 1;
for i = 1:ends_nums
    divided_str{i, 1= str(begin:ends(i));
    begin = 1 + ends(i);
end
cs

 

 

제대로 분리해서 추출해내는지 확인해보도록 하겠습니다. 

 

 

제대로 추출되었죠? 그러면 또다른 문자열에 대해서도 테스트해보겠습니다. 

 

이번에는 문자열을 '1저는23초보자456입니다78' 으로 바꿔서 코드를 실행해보겠습니다.  

 

 

역시 잘 되는 것을 확인할 수 있습니다. 김진성님께 도움이 되었으면 좋겠네요.^^ 

SQLite3와 PHP 연결하고 데이터 쓰고 읽기

프로그래밍/웹코딩|2020. 5. 21. 17:21

SQL이라는 친구가 있습니다. 이 친구도 일종의 프로그래밍 언어인데, 관계형 데이터베이스를 관리하는데 사용되는 언어입니다. 관계형 데이터베이스에는 MySQL, MariaDB, SQLite 등이 있습니다. 저는 그 중에서 가장 심플한 SQLite를 사용해서 데이터베이스를 관리해보도록 하겠습니다. 

 

SQL, 너는 데이터베이스를 관리하는데 사용되는 코딩 언어구나! [출처: Photo by  Tobias Fischer  on  Unsplash]

 

저는 SQLite를 이용해서 database.db라는 이름의 데이터베이스 파일을 만들었다고 가정하고 설명을 시작하도록 하겠습니다. 이 database.db 안에는 Person이라는 테이블이 있고, 그 안에는 ID라는 필드와 Name이라는 필드가 존재합니다.  

 

 

1. SQLite3과 PHP 연결하기

PHP를 이용해서 SQLite3의 데이터베이스를 연결하려면 다음과 같이 코드를 작성하시면 됩니다. 

 

<?php

$DB = new SQLite3('database.db');

if($DB->lastErrorCode() == 0){
	echo "Database connection succeed!";
}
else {
	echo "Database connection failed";
    echo $DB->lastErrorMsg();
}

?>

 

위 코드에서 데이터베이스가 제대로 연결되었다면 lastErrorCode()는 0을 반환합니다. 따라서 if 문의 명령이 실행되죠. 제대로 연결되지 않았을 때는 0이 아닌 다른 수가 나오기 때문에 else 문의 명령이 실행됩니다. lastErrorMsg()는 가장 최근에 실패한 SQLite 요청을 반환합니다. 

 

2. 데이터 쓰기

주어진 데이터베이스에 쿼리를 실행하려면 exec()를 사용합니다. 테이블 내의 특정 필드에 데이터를 쓰려면 INSERT를 사용합니다. (참고로 데이터를 갱신하려면 UPDATE, 삭제하려면 DELETE를 사용합니다.) 저의 경우에는 ID는 자동적으로 하나씩 커지게 autoincrement로 설정해놨으므로 Name 필드에 대한 데이터만 써주면 됩니다. bskyvision이라는 이름을 추가하도록 코드를 짜보겠습니다. 

 

<?php

$DB = new SQLite3('database.db');

$DB->exec("INSERT INTO 'Person' ('Name') VALUES ('bskyvision');");

?>

 

3. 데이터 읽기

SQL 쿼리를 실행하는 함수에는 query()도 있습니다. 위에서 언급한 exec()는 데이터를 쓰고 갱신하고 지울 때 사용하고, 읽을 때는 query()를 사용합니다. 두 함수에 대한 소개를 자세히 보면 조금 차이가 있습니다. 

 

SQLite3::exec - Executes a result-less query against a given database [5]

SQLite3::query - Executes an SQL query [6]

 

데이터를 읽을 때는 SELECT 구문을 사용합니다. 그러면 Person 테이블의 행들을 한 줄씩 읽은 후 그중 Name 필드에 저장되어 있는 데이터만 출력하는 코드를 작성해보도록 하겠습니다. 

 

<?php

$DB = new SQLite3('database.db');

$result = $DB->query("SELECT * FROM 'Person';");

while($row = $result->fetchArray(SQLITE3_ASSOC)){         
        echo $row["Name"];
}

?>

 

위 코드를 실행시키면 Name 필드에 저장되어 있던 데이터들을 순차적으로 읽어서 출력시켜줍니다. 

 

혹시 질문이 있으시거나 제 설명이 잘못된 부분이 있다면 댓글을 남겨주시길 바랍니다. 끝까지 읽어주셔서 감사합니다! 

 

 

<참고자료>

[1] https://wikidocs.net/book/1530, 최용, "SQLite로 가볍게 배우는 데이터베이스"

[2] http://codelala.net/php-sqlite3-%ec%97%b0%eb%8f%99%ed%95%98%ea%b8%b0/, lala, "PHP - SQLite3 연동"

[3] https://www.php.net/manual/en/sqlite3.lasterrorcode.php, php.net, "SQLite3::lastErrorCode"

[4] https://www.php.net/manual/en/sqlite3.lasterrormsg, php.net, "SQLite3::lastErrorMsg"

[5] https://www.php.net/manual/en/sqlite3.exec, php.net, "SQLite3::exec"

[6] https://www.php.net/manual/en/sqlite3.query, php.net, "SQLite3::query"

  1. BlogIcon DNA구너 2020.05.22 00:39 신고 댓글주소  수정/삭제  댓글쓰기

    쿼리 날릴때 인덱스 타는게 중요하다는데 그건 어떻게 확인이 가능한가요?

사람들이 자연 풍광 사진을 실내 및 도시 사진보다 선호하는 이유는?


대개 많은 사람들이 야외 자연 풍광 사진을 실내 사진 및 도시 사진보다 더 좋아합니다. 저도 그런 편입니다. 그런 자연 사진을 찍기 위해 많은 사람들이 해외로, 휴양지로 여행을 가기도 하죠. 왜 우리에게 그런 경향이 있는지, 그 이유에 대해 수많은 연구자들이 연구해왔습니다. 

 

어떤 사진이 가장 마음에 드시나요? 제가 순위를 매긴 것과 같으신가요? 

 

하나는 진화론적 관점에서의 분석입니다. 사람들은 오랜 기간동안 사람이 만든 건축물이 많지 않은, 즉 개발되지 않은 자연적 환경에서 살아왔고, 결과적으로 자연 풍광 이미지에 적응되도록 우리의 시각시스템이 진화해왔다는 것입니다.

 

또한 자연 사진이 실내, 도시에 비해 긴장을 푸는데 도움이 된다고 합니다. 그 이유로 뇌 속에 있는 스트레스를 경감시키는 역할을 하는 수용체(receptor)들이 자연 풍광 이미지를 볼 때 활성화되도록 진화해 온 것으로 추정하고 있습니다. 우리가 마음이 답답할 때, 스트레스가 많을 때 바다를 보러 떠나는 것을 보면 어느 정도 일리가 있는 주장인 것 같습니다.

 

그리고 사람에게는 자연 이미지를 실내, 도시 이미지보다 더 빨리 범주화(categorization)하는 능력을 갖고 있다고 합니다. 무슨 뜻인가 하면, 바다 사진을 보고 "어! 바다네", 산을 보고, "이건 산!" 이렇게 범주화하는 하는데 소요되는 시간이 아주 짧다는 것입니다. 반면 실내 사진을 봤을 때는 그것을 범주화하는데 좀 더 오랜 시간이 걸린다고 합니다. "음... 이건 도서관인가?", "이것은... 런던아이?" 이런 식으로 좀 더 시간이 소요된다고 합니다. 그만큼 우리의 시각시스템이 자연 이미지를 더 쉽게 처리한다는 뜻이겠죠. 빨리 처리한다는 것은 뇌가 힘을 덜 써도 된다는 뜻이므로, 우리가 느끼는 부담이 적다고 볼 수 있습니다. 우리는 어려운 과제를 수행하는 것보단 쉬운 과제를 수행하는 것을 좋아하죠. 

 

이러한 이유들로 사람들은 자연 풍광 이미지를 좀 더 선호한다고 합니다. 

 

 

<참고자료>

[1] Mullin, Caitlin, et al. "The gist of beauty: an investigation of aesthetic perception in rapidly presented images." Electronic Imaging 2017.14 (2017): 248-256. 

php 변수값을 javascript 변수에 대입하려면?

프로그래밍/웹코딩|2020. 5. 20. 13:39

웹코딩을 하다보면 php 변수에 대입되어 있는 값을 javascript에서 활용해야하는 경우가 종종 있습니다. php 변수값을 자바스크립트 변수에 대입하려면 다음과 같이 코딩하면 됩니다. 

 

<script>

var a = "<?php echo $x; ?>";

</script>

 

$x라는 php 변수에 대입되어 있는 값을 a라는 이름의 자바스크립트 변수에 대입시켰습니다.  

 

 

<참고자료>

[1] https://www.xul.fr/javascript/php.php, XUL, Exchanging variables between JavaScript and PHP

등방성(isotropic) 이미지와 이방성(anisotropic) 이미지란?


영상처리 관련 논문을 읽다보면 isotropic, anisotropic 두 단어를 종종 보곤 합니다. 두 단어는 서로 반의어입니다.

isotropic <-> anisotropic

isotropic은 사전적으로 "등방성의"라는 뜻을 갖고, anisotropic은 "이방성의"라는 뜻을 지닙니다. 뜻을 풀어보면 등방성은 "같은 방향 성질을 갖는"이고, 이방성은 "다른 방향 성질을 갖는"이 됩니다. 이렇게 풀어봐도 전혀 이해가 안되죠. 이해가 안되는 것이 어쩌면 당연합니다. 

 

일단 넘어가서, 영상처리 분야에서 이 단어들이 사용되는 경우에 대해 생각해보겠습니다. 등방성이 강한 이미지와 이방성이 강한 이미지는 어떤 이미지를 뜻하는 것일까요??

 

특정 방향에 대한 정보를 다른 방향에 대한 정보보다 유독 더 많이 담고 있는 이미지는 이방성이 강하다(=등방성이 약하다)고 말할 수 있습니다. 반면, 모든 방향에 대한 정보가 고루게 분포되어 있는 이미지라면 등방성이 강하다(=이방성이 약하다)고 말할 수 있습니다. 

 

 

 

기본적으로 자연 경관 이미지는 등방성이 강합니다. 다양한 방향의 엣지들이 골고루 존재합니다. 반면 건물, 도시경관 등 사람이 만든 구조물 이미지는 이방성이 강합니다. 수직 방향, 수평 방향 등 특정 방향의 엣지 정보가 다른 방향의 엣지보다 많습니다. 

 

예를 들어, 아래 두 이미지를 비교해보겠습니다. 왼쪽 이미지가 오른쪽 이미지보다 이방성이 더 강하다고 말할 수 있습니다. 왜냐하면 왼쪽 이미지에는 건물들로 인해 특정 방향의 엣지 정보가 많이 포함되어 있기 때문입니다. 

 

 

이미지 분야에 있어서 등방성, 이방성이 어떤 의미를 갖는지 이해 되셨나요? 도움이 되셨길 바라며 글을 마칩니다. 

[IQA] 넷플릭스 영상의 품질 모니터링의 핵심 알고리즘, VIF


오늘은 VIF(visual information fidelity)라고 불리는 이미지 품질 평가(image quality assessment, IQA) 알고리즘을 소개해드리도록 하겠습니다. VIF는 SSIM과 함께 매우 유명한 IQA 알고리즘 중에 하나입니다. 특히, VIF는 넷플릭스에서 개발한 비디오 품질 평가 알고리즘인 VMAF(video multimethod assessment fusion)에서 중요한 역할을 하는 IQA 알고리즘입니다. 넷플릭스와 같이 엄청난 수익을 창출해내는 기업에서 비디오 품질의 모니터링을 위해 VIF를 채택했다는 것은 이 알고리즘이 그만큼 신뢰할 만하다는 뜻이겠죠. 

 

그럼 지금부터 VIF의 작동 원리에 대해 간략하게 설명해드리도록 하겠습니다. VIF의 original 논문은 2006년에 TIP에서 게재한 "Image Information and Visual Quality"입니다. 저자는 H.R. Sheikh와 A.C. Bovik인데, 모두 텍사스 대학의 LIVE 연구실 소속입니다. 참고로 LIVE 연구실은 IQA 분야에 있어서 가장 영향력있는 곳입니다. 

 

VIF는 원본 이미지에 존재하는 정보량과 왜곡 이미지에 존재하는 원본 이미지에 대한 정보량을 비교함으로서 품질을 평가합니다. 아래 그림을 함께 보실까요? 

 

출처: original paper

 

이 그림에서 원본 이미지, 즉 어떠한 왜곡(distoriton)도 존재하지 않는 깨끗한 이미지 신호가 C입니다. 이것이 사람시각시스템(human visual system, HVS)에 의해 인지된 신호는 E입니다. 그리고 C가 왜곡 채널에 의해 손상된 이미지 신호가 D입니다. 그것이 HVS에 의해 인지된 신호는 F가 됩니다. 

 

VIF는 C와 E간의 상호정보량(mutual information), 즉 둘이 공유하는 엔트로피를 계산합니다. 엔트로피란 평균 불확실성, 평균 정보량을 의미합니다. 또한 D와 F간의 상호정보량을 계산합니다. 그런 다음에 다음과 같이 둘의 비를 계산해줌으로써 왜곡된 이미지의 품질을 예측합니다. 

 

출처: original paper

 

이 식에서 I(C; F)와 I(C; E)가 상호정보량을 계산하는 기호입니다. 

 

우리 함께 생각해봅시다. 만약 왜곡이 적게 된 이미지라면 I(C; F)와 I(C; E)는 거의 비슷한 값을 갖겠죠? 그러면 결국 VIF는 1에 가까운 값을 갖게 될 것입니다. 만약 왜곡이 많이 된 이미지라면 I(C; F)와 I(C; E) 간 차이가 꽤 크겠죠? 결과적으로 VIF는 1에서 멀어지고 0에 가까운 값을 갖게 될 것입니다.

 

이런 식으로 VIF는 작동합니다. VIF의 핵심은 정보이론의 상호정보량을 활용한다는 점에 있습니다. 참고로 VIF의 전신은 IFC(information fidelity criterion)라는 알고리즘입니다. 도움이 되셨길 바라며 이 글을 마치도록 하겠습니다. :D 

 

 

<참고자료>

[1] https://en.wikipedia.org/wiki/Visual_Information_Fidelity, 위키피디아(영문), visual information fidelity