- 지도 기반 나침반(노스업, 현재위치, 시야 역삼각형): 호버 확대·휠 줌·클릭 위성전환, OSM/Esri 타일 서버 프록시(/api/tile) - 스테이션 검색: 실제 측점(chain) 기준 이동, 없으면 '측점 없음' 안내 - 역 마커: 직교 투영 측점 일치 시에만 표시, 미도착 종점은 추가 방식 - POI 팝업 겹침/재등장·라벨 정합 수정 - 영상 fps 데이터 기반 자동 산출 - 기술/발표/쉬운설명 문서 추가 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
508 lines
33 KiB
HTML
508 lines
33 KiB
HTML
<!DOCTYPE html>
|
|
<html xmlns="http://www.w3.org/1999/xhtml" lang xml:lang>
|
|
<head>
|
|
<meta charset="utf-8" />
|
|
<meta name="generator" content="pandoc" />
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes" />
|
|
<title>쉬운설명_GhiVideo_기술이야기</title>
|
|
<style>
|
|
code{white-space: pre-wrap;}
|
|
span.smallcaps{font-variant: small-caps;}
|
|
span.underline{text-decoration: underline;}
|
|
div.column{display: inline-block; vertical-align: top; width: 50%;}
|
|
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
|
ul.task-list{list-style: none;}
|
|
.display.math{display: block; text-align: center; margin: 0.5rem auto;}
|
|
</style>
|
|
<style type="text/css">@page {
|
|
size: A4;
|
|
margin: 18mm 16mm 16mm 16mm;
|
|
@bottom-center {
|
|
content: counter(page) " / " counter(pages);
|
|
font-family: "Malgun Gothic", sans-serif;
|
|
font-size: 9pt;
|
|
color: #999;
|
|
}
|
|
}
|
|
html { font-size: 11pt; }
|
|
body {
|
|
font-family: "Malgun Gothic", "Hancom Gothic", sans-serif;
|
|
color: #23272e;
|
|
line-height: 1.65;
|
|
max-width: 920px;
|
|
margin: 0 auto;
|
|
padding: 24px;
|
|
}
|
|
h1 {
|
|
font-size: 1.7rem;
|
|
color: #b45309;
|
|
border-bottom: 3px solid #f59e0b;
|
|
padding-bottom: 8px;
|
|
margin: 0 0 4px;
|
|
}
|
|
h2 {
|
|
font-size: 1.25rem;
|
|
color: #b45309;
|
|
border-bottom: 1px solid #e5d3b3;
|
|
padding-bottom: 5px;
|
|
margin-top: 1.6em;
|
|
}
|
|
h3 { font-size: 1.05rem; color: #92400e; margin-top: 1.1em; }
|
|
a { color: #b45309; }
|
|
hr { border: none; border-top: 1px solid #e2e2e2; margin: 1.6em 0; }
|
|
ul { padding-left: 1.25em; }
|
|
li { margin: 0.18em 0; }
|
|
strong { color: #1f2937; }
|
|
code {
|
|
font-family: "D2Coding", Consolas, monospace;
|
|
background: #f4f1ea;
|
|
border: 1px solid #e7e0d2;
|
|
border-radius: 3px;
|
|
padding: 0.5px 5px;
|
|
font-size: 0.92em;
|
|
}
|
|
table {
|
|
border-collapse: collapse;
|
|
width: 100%;
|
|
margin: 0.8em 0;
|
|
font-size: 0.95em;
|
|
}
|
|
th, td { border: 1px solid #d8d2c4; padding: 6px 10px; text-align: left; vertical-align: top; }
|
|
th { background: #fdf3df; color: #7c2d12; }
|
|
blockquote {
|
|
border-left: 4px solid #f59e0b;
|
|
margin: 0.8em 0;
|
|
padding: 0.2em 0 0.2em 14px;
|
|
color: #555;
|
|
background: #fffbf2;
|
|
}
|
|
|
|
h1, h2, h3 { break-after: avoid; }
|
|
</style>
|
|
<!--[if lt IE 9]>
|
|
<script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
|
|
<![endif]-->
|
|
</head>
|
|
<body>
|
|
<header id="title-block-header">
|
|
<h1 class="title">쉬운설명_GhiVideo_기술이야기</h1>
|
|
</header>
|
|
<h1 id="ghivideo-쉽게-풀어쓴-기술-이야기-그림판">GhiVideo, 쉽게 풀어쓴 기술 이야기 (그림판)</h1>
|
|
<blockquote>
|
|
<p>이 문서는 <strong>수학을 잘 몰라도, 중학생이 읽어도</strong> 이해할 수 있게 쓴 설명서입니다. 어려운 공식 대신 <strong>비유와 그림</strong>으로 "이 프로그램이 무슨 일을, 왜, 어떻게 하는지"를 풀어 씁니다. (더 깊은 기술/수식은 같은 폴더의 <code>기술명세_GhiVideo_종합기술문서.pdf</code> 참고.)</p>
|
|
</blockquote>
|
|
<style>
|
|
figure.fig{margin:20px 0;text-align:center;page-break-inside:avoid;break-inside:avoid;}
|
|
figure.fig svg{width:100%;max-width:640px;height:auto;border:1px solid #e7e0d2;border-radius:8px;background:#fffdf8;}
|
|
figure.fig figcaption{font-size:0.9em;color:#777;margin-top:6px;}
|
|
text{font-family:'Malgun Gothic','Hancom Gothic',sans-serif;}
|
|
</style>
|
|
|
|
<hr />
|
|
<h2 id="0-한-문장으로-말하면">0. 한 문장으로 말하면</h2>
|
|
<p><strong>드론이 철길 위를 날며 찍은 영상</strong>을 보면서, 화면 속 다리·터널·역·선로 위에 <strong>"여기는 어디, 저건 무슨 다리"</strong> 같은 정보를 <strong>자동으로 딱 붙여서</strong> 보여주는 프로그램입니다.</p>
|
|
<p>마치 <strong>포켓몬GO</strong>나 <strong>내비게이션의 증강현실(AR) 길안내</strong>처럼, 실제 영상 위에 정보가 떠 있는 거예요.</p>
|
|
<hr />
|
|
<h2 id="1-가장-큰-그림-먼저">1. 가장 큰 그림 먼저</h2>
|
|
<p>우리가 가진 재료는 딱 두 가지입니다.</p>
|
|
<ol type="1">
|
|
<li><strong>드론이 찍은 영상</strong> — 매 순간 "드론이 <strong>어디에</strong> 있었고 <strong>어느 방향을</strong> 보는지"가 같이 기록돼 있어요.</li>
|
|
<li><strong>지도 정보</strong> — 다리·터널·역·측점이 지구상 <strong>어디에 있는지</strong>(위도·경도) 적힌 데이터.</li>
|
|
</ol>
|
|
<p>이 둘을 합치면 <strong>"저 다리는 화면의 어느 위치에 보일까?"</strong> 에 답할 수 있어요. 그게 핵심 기술입니다.</p>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 210" role="img" aria-label="큰 그림 흐름도">
|
|
<defs><marker id="f1a" markerWidth="9" markerHeight="9" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#b45309"></path></marker></defs>
|
|
<rect x="20" y="25" width="180" height="55" rx="8" fill="#fff" stroke="#2563eb" stroke-width="1.5"></rect>
|
|
<text x="110" y="48" text-anchor="middle" font-size="15" font-weight="bold" fill="#1e3a8a">드론 영상</text>
|
|
<text x="110" y="68" text-anchor="middle" font-size="12" fill="#555">(위치 · 보는 방향 기록)</text>
|
|
<rect x="20" y="125" width="180" height="55" rx="8" fill="#fff" stroke="#16a34a" stroke-width="1.5"></rect>
|
|
<text x="110" y="148" text-anchor="middle" font-size="15" font-weight="bold" fill="#14532d">지도 정보</text>
|
|
<text x="110" y="168" text-anchor="middle" font-size="12" fill="#555">(다리·터널·측점 위치)</text>
|
|
<rect x="270" y="75" width="150" height="55" rx="8" fill="#fff7e6" stroke="#f59e0b" stroke-width="2"></rect>
|
|
<text x="345" y="98" text-anchor="middle" font-size="15" font-weight="bold" fill="#b45309">합치기</text>
|
|
<text x="345" y="118" text-anchor="middle" font-size="12" fill="#7c2d12">(투영 계산)</text>
|
|
<rect x="470" y="75" width="150" height="55" rx="8" fill="#fff" stroke="#b45309" stroke-width="1.5"></rect>
|
|
<text x="545" y="100" text-anchor="middle" font-size="14" font-weight="bold" fill="#23272e">화면에</text>
|
|
<text x="545" y="119" text-anchor="middle" font-size="14" font-weight="bold" fill="#23272e">정보 표시</text>
|
|
<line x1="200" y1="52" x2="266" y2="92" stroke="#b45309" stroke-width="1.5" marker-end="url(#f1a)"></line>
|
|
<line x1="200" y1="152" x2="266" y2="114" stroke="#b45309" stroke-width="1.5" marker-end="url(#f1a)"></line>
|
|
<line x1="420" y1="102" x2="466" y2="102" stroke="#b45309" stroke-width="1.5" marker-end="url(#f1a)"></line>
|
|
</svg>
|
|
<figcaption>그림 1. 드론 영상 + 지도 정보 → "투영 계산"으로 합쳐 → 화면에 정보 표시</figcaption>
|
|
</figure>
|
|
|
|
<hr />
|
|
<h2 id="2-영상-위에-글자를-정확히-붙이는-마법">2. 영상 위에 글자를 정확히 붙이는 마법</h2>
|
|
<h3 id="2-1-먼저-위치를-숫자로-바꿔요">2-1. 먼저, 위치를 '숫자'로 바꿔요</h3>
|
|
<p>지구 위 위치는 보통 위도·경도(각도)로 말하는데, 거리 계산이 불편해요. 그래서 <strong>"기준점에서 동쪽 몇 m, 북쪽 몇 m"</strong> 처럼 <strong>미터(m)</strong> 로 바꿉니다.</p>
|
|
<blockquote>
|
|
<p>🧭 <strong>비유</strong>: 학교 정문을 (0,0)으로 정하고 "동쪽 50m, 북쪽 30m 지점"이라 말하는 것과 같아요.</p>
|
|
</blockquote>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 240" role="img" aria-label="좌표 예시">
|
|
<defs><marker id="f2a" markerWidth="9" markerHeight="9" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#6b7280"></path></marker></defs>
|
|
<!-- grid -->
|
|
<g stroke="#eee" stroke-width="1">
|
|
<line x1="90" y1="40" x2="90" y2="200"></line><line x1="170" y1="40" x2="170" y2="200"></line><line x1="250" y1="40" x2="250" y2="200"></line><line x1="330" y1="40" x2="330" y2="200"></line>
|
|
<line x1="90" y1="200" x2="610" y2="200"></line><line x1="90" y1="160" x2="610" y2="160"></line><line x1="90" y1="120" x2="610" y2="120"></line><line x1="90" y1="80" x2="610" y2="80"></line>
|
|
</g>
|
|
<!-- axes -->
|
|
<line x1="90" y1="200" x2="610" y2="200" stroke="#6b7280" stroke-width="2" marker-end="url(#f2a)"></line>
|
|
<line x1="90" y1="200" x2="90" y2="35" stroke="#6b7280" stroke-width="2" marker-end="url(#f2a)"></line>
|
|
<text x="600" y="222" font-size="13" fill="#6b7280">동쪽(m) →</text>
|
|
<text x="60" y="45" font-size="13" fill="#6b7280">북쪽(m) ↑</text>
|
|
<!-- origin -->
|
|
<circle cx="90" cy="200" r="5" fill="#16a34a"></circle>
|
|
<text x="98" y="218" font-size="12" fill="#14532d">학교 정문 (0,0)</text>
|
|
<!-- point: east 50m (->x 290), north 30m (->y 80) -->
|
|
<line x1="290" y1="200" x2="290" y2="80" stroke="#f59e0b" stroke-width="1.5" stroke-dasharray="4 3"></line>
|
|
<line x1="90" y1="80" x2="290" y2="80" stroke="#f59e0b" stroke-width="1.5" stroke-dasharray="4 3"></line>
|
|
<circle cx="290" cy="80" r="6" fill="#b45309"></circle>
|
|
<text x="300" y="76" font-size="13" font-weight="bold" fill="#b45309">건물</text>
|
|
<text x="300" y="95" font-size="12" fill="#7c2d12">(동 50m, 북 30m)</text>
|
|
</svg>
|
|
<figcaption>그림 2. 위치를 "기준점에서 동/북 몇 m"로 바꾸면 거리·계산이 쉬워집니다.</figcaption>
|
|
</figure>
|
|
|
|
<h3 id="2-2-드론이-어디서-어느-쪽을-보는지-알아요">2-2. 드론이 '어디서, 어느 쪽을' 보는지 알아요</h3>
|
|
<p>영상의 각 순간마다 드론은 <strong>위치</strong>(어디 떠 있나)와 <strong>자세</strong>(어느 쪽을 보나)를 기록합니다. 이 둘을 알면, 카메라가 <strong>무엇을</strong> 보는지 계산할 수 있어요.</p>
|
|
<blockquote>
|
|
<p>🎥 <strong>비유</strong>: 친구가 어디 서서 어느 쪽을 가리키는지 알면, 손가락이 무엇을 가리키는지 알 수 있죠.</p>
|
|
</blockquote>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 210" role="img" aria-label="드론 위치와 방향">
|
|
<defs><marker id="f3a" markerWidth="9" markerHeight="9" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#2563eb"></path></marker></defs>
|
|
<!-- view cone -->
|
|
<path d="M120,120 L470,55 L470,165 Z" fill="#dbeafe" opacity="0.6"></path>
|
|
<!-- drone -->
|
|
<circle cx="120" cy="120" r="9" fill="#2563eb"></circle>
|
|
<text x="105" y="150" font-size="13" font-weight="bold" fill="#1e3a8a">드론</text>
|
|
<text x="80" y="168" font-size="11" fill="#555">(여기 있고, 이쪽을 봄)</text>
|
|
<!-- building target -->
|
|
<rect x="500" y="70" width="60" height="70" fill="#fde68a" stroke="#b45309"></rect>
|
|
<rect x="512" y="84" width="12" height="12" fill="#fff"></rect><rect x="536" y="84" width="12" height="12" fill="#fff"></rect><rect x="512" y="110" width="12" height="12" fill="#fff"></rect><rect x="536" y="110" width="12" height="12" fill="#fff"></rect>
|
|
<text x="530" y="158" text-anchor="middle" font-size="12" fill="#7c2d12">건물</text>
|
|
<!-- ray -->
|
|
<line x1="130" y1="118" x2="496" y2="105" stroke="#2563eb" stroke-width="1.5" stroke-dasharray="5 4" marker-end="url(#f3a)"></line>
|
|
<text x="250" y="100" font-size="12" fill="#1e3a8a">"저건 화면 어디에 보일까?" 계산</text>
|
|
</svg>
|
|
<figcaption>그림 3. 드론의 위치 + 보는 방향을 알면, 대상이 화면 어디에 보일지 계산됩니다.</figcaption>
|
|
</figure>
|
|
|
|
<h3 id="2-3-3d-세상을-납작한-화면2d에-그려요--원근법">2-3. 3D 세상을 납작한 화면(2D)에 그려요 — '원근법'</h3>
|
|
<p>입체(3D)를 화면(2D)에 그릴 때 쓰는 게 <strong>원근법</strong>입니다. 규칙은 누구나 알아요: <strong>가까운 건 크게, 먼 건 작게.</strong></p>
|
|
<blockquote>
|
|
<p>📷 <strong>비유</strong>: 바늘구멍 사진기처럼, 카메라는 3D를 2D로 눌러 담습니다.</p>
|
|
</blockquote>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 230" role="img" aria-label="원근법">
|
|
<!-- ground -->
|
|
<line x1="40" y1="195" x2="620" y2="195" stroke="#9ca3af" stroke-width="1.5"></line>
|
|
<!-- eye -->
|
|
<circle cx="70" cy="150" r="7" fill="#111"></circle>
|
|
<text x="42" y="172" font-size="12" fill="#333">눈/카메라</text>
|
|
<!-- screen -->
|
|
<line x1="210" y1="60" x2="210" y2="195" stroke="#2563eb" stroke-width="2"></line>
|
|
<text x="170" y="52" font-size="12" fill="#1e3a8a">화면</text>
|
|
<!-- near pole (same real height as far) at x=360, top y=70 bottom y=195 -->
|
|
<line x1="360" y1="70" x2="360" y2="195" stroke="#16a34a" stroke-width="4"></line>
|
|
<text x="330" y="215" font-size="12" fill="#14532d">가까운 기둥</text>
|
|
<!-- far pole at x=560 same height -->
|
|
<line x1="560" y1="70" x2="560" y2="195" stroke="#16a34a" stroke-width="4"></line>
|
|
<text x="530" y="215" font-size="12" fill="#14532d">먼 기둥</text>
|
|
<text x="350" y="58" font-size="11" fill="#777">(실제로는 둘 다 같은 크기)</text>
|
|
<!-- rays from eye to near top/bottom -->
|
|
<line x1="70" y1="150" x2="360" y2="70" stroke="#f59e0b" stroke-width="1" stroke-dasharray="3 3"></line>
|
|
<line x1="70" y1="150" x2="360" y2="195" stroke="#f59e0b" stroke-width="1" stroke-dasharray="3 3"></line>
|
|
<!-- rays to far -->
|
|
<line x1="70" y1="150" x2="560" y2="70" stroke="#b45309" stroke-width="1" stroke-dasharray="3 3"></line>
|
|
<line x1="70" y1="150" x2="560" y2="195" stroke="#b45309" stroke-width="1" stroke-dasharray="3 3"></line>
|
|
<!-- projected segments on screen: near ~111..169, far ~127..161 -->
|
|
<line x1="210" y1="111" x2="210" y2="169" stroke="#16a34a" stroke-width="6"></line>
|
|
<line x1="218" y1="127" x2="218" y2="161" stroke="#15803d" stroke-width="6" opacity="0.8"></line>
|
|
<text x="226" y="120" font-size="11" fill="#166534">화면엔 가까운 게 더 크게</text>
|
|
</svg>
|
|
<figcaption>그림 4. 실제 크기가 같아도, 화면에는 가까운 것이 크게·먼 것이 작게 찍힙니다(원근법).</figcaption>
|
|
</figure>
|
|
|
|
<h3 id="2-4-높이에는-함정이-있어요-지오이드-이야기">2-4. '높이'에는 함정이 있어요 (지오이드 이야기)</h3>
|
|
<p>높이를 재는 기준이 <strong>두 가지</strong>라서 헷갈려요.</p>
|
|
<ul>
|
|
<li><strong>GPS 높이</strong>: 지구를 매끈한 타원으로 본 기준</li>
|
|
<li><strong>지도 해발고도</strong>: 평균 바닷물 높이 기준(지오이드)</li>
|
|
</ul>
|
|
<p>둘은 지역마다 <strong>수십 m</strong> 차이 나요(대전 약 25.8m). 안 맞추면 글자가 엉뚱한 데로 갑니다.</p>
|
|
<blockquote>
|
|
<p>🌊 <strong>비유</strong>: "1층 바닥 기준"과 "지하 바닥 기준"으로 잰 높이는 같은 건물인데 숫자가 다르죠.</p>
|
|
</blockquote>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 200" role="img" aria-label="높이 기준 차이">
|
|
<defs><marker id="f5a" markerWidth="9" markerHeight="9" refX="3" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#dc2626"></path></marker><marker id="f5b" markerWidth="9" markerHeight="9" refX="3" refY="3" orient="auto"><path d="M6,0 L0,3 L6,6 Z" fill="#dc2626"></path></marker></defs>
|
|
<!-- ground hill -->
|
|
<path d="M40,170 Q200,120 360,150 T620,135" fill="none" stroke="#8b5e34" stroke-width="3"></path>
|
|
<text x="46" y="188" font-size="11" fill="#7c5a3a">실제 땅(굴곡)</text>
|
|
<!-- GPS reference line -->
|
|
<line x1="40" y1="55" x2="620" y2="55" stroke="#2563eb" stroke-width="2" stroke-dasharray="6 4"></line>
|
|
<text x="430" y="48" font-size="12" fill="#1e3a8a">GPS 기준 (타원체)</text>
|
|
<!-- geoid reference line -->
|
|
<line x1="40" y1="105" x2="620" y2="105" stroke="#0ea5e9" stroke-width="2" stroke-dasharray="6 4"></line>
|
|
<text x="400" y="122" font-size="12" fill="#0369a1">지도 해발 기준 (지오이드)</text>
|
|
<!-- gap arrow -->
|
|
<line x1="160" y1="56" x2="160" y2="104" stroke="#dc2626" stroke-width="1.5" marker-start="url(#f5a)" marker-end="url(#f5b)"></line>
|
|
<text x="170" y="84" font-size="12" font-weight="bold" fill="#dc2626">약 25.8m 차이</text>
|
|
<text x="170" y="100" font-size="11" fill="#b91c1c">→ 맞춰줘야 함</text>
|
|
</svg>
|
|
<figcaption>그림 5. 높이 기준이 둘이라 수십 m 차이. 이걸 맞춰줘야 글자가 제자리에 붙습니다.</figcaption>
|
|
</figure>
|
|
|
|
<p>또 영리한 점: 우리 데이터엔 <strong>측점마다 실제 측량한 높이</strong>가 있어서, 비싼 3D 지형 데이터를 안 사고 <strong>가장 가까운 측점의 높이</strong>를 가져다 쓰면 선로 굴곡까지 자연스럽게 반영됩니다. (특허 후보 — 6장)</p>
|
|
<h3 id="2-5-화각-맞추기--줌렌즈-vs-광각렌즈">2-5. '화각' 맞추기 — 줌렌즈 vs 광각렌즈</h3>
|
|
<p>같은 자리에서도 <strong>광각</strong>은 넓게, <strong>줌</strong>은 좁게 보이죠. 이 "얼마나 넓게 보나"가 <strong>화각(FOV)</strong> 입니다. 화각이 안 맞으면 글자가 위아래로 어긋나는데, 사용자가 글자 하나를 제자리로 끌어주면 프로그램이 화각을 <strong>스스로 맞춥니다.</strong></p>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 200" role="img" aria-label="화각 비교">
|
|
<!-- apex -->
|
|
<circle cx="80" cy="100" r="7" fill="#111"></circle>
|
|
<text x="55" y="122" font-size="12" fill="#333">카메라</text>
|
|
<!-- wide cone -->
|
|
<path d="M80,100 L600,25 L600,175 Z" fill="#fef3c7" opacity="0.7" stroke="#f59e0b"></path>
|
|
<text x="470" y="40" font-size="13" font-weight="bold" fill="#b45309">광각: 넓게 봄</text>
|
|
<!-- narrow cone -->
|
|
<path d="M80,100 L600,80 L600,120 Z" fill="#bfdbfe" opacity="0.85" stroke="#2563eb"></path>
|
|
<text x="470" y="150" font-size="13" font-weight="bold" fill="#1e3a8a">줌: 좁게 봄</text>
|
|
</svg>
|
|
<figcaption>그림 6. 화각(FOV) = 얼마나 넓게 보는지. 광각은 넓게, 줌은 좁게.</figcaption>
|
|
</figure>
|
|
|
|
<h3 id="2-6-흔들림-잡기--평균-내기">2-6. 흔들림 잡기 — '평균 내기'</h3>
|
|
<p>GPS·자세 기록엔 미세한 <strong>떨림</strong>이 있어 글자가 부르르 떨려요. 여러 순간을 <strong>평균</strong> 내면 부드러워집니다. 단, 방향을 휙 트는 순간까지 섞으면 늦게 따라오니까 — <strong>곧게 갈 땐 많이, 틀 땐 적게</strong> 평균 내요.</p>
|
|
<blockquote>
|
|
<p>✏️ <strong>비유</strong>: 떨면서 그은 선을 옆 점들과 평균 내어 매끈하게 다듬는 것.</p>
|
|
</blockquote>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 200" role="img" aria-label="평활 전후">
|
|
<text x="40" y="40" font-size="12" fill="#b91c1c">원래 (GPS 떨림)</text>
|
|
<polyline points="40,60 80,52 110,70 140,50 175,72 205,54 240,68 275,50 310,70 345,55 380,66 420,52 455,70 490,54 525,66 560,52 600,62" fill="none" stroke="#dc2626" stroke-width="2"></polyline>
|
|
<text x="40" y="135" font-size="12" fill="#166534">평균 낸 후 (부드러움)</text>
|
|
<polyline points="40,155 110,153 175,156 240,154 310,156 380,154 455,156 525,154 600,155" fill="none" stroke="#16a34a" stroke-width="3"></polyline>
|
|
</svg>
|
|
<figcaption>그림 7. 떨리는 값(빨강)을 평균 내면 부드러운 선(초록)이 됩니다.</figcaption>
|
|
</figure>
|
|
|
|
<h3 id="2-7-손으로-끌어서-위치-고치기--거꾸로-계산">2-7. 손으로 끌어서 위치 고치기 — '거꾸로 계산'</h3>
|
|
<p>지도 위치가 가끔 틀려요. 화면에서 글자를 <strong>제자리로 끌면</strong>, 프로그램이 그 화면 위치를 <strong>거꾸로 따라가</strong> 실제 위치를 찾아 고칩니다. (2-3을 반대로 돌리는 것!) 고친 위치는 저장돼 다음에도 적용돼요.</p>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 210" role="img" aria-label="역투영 보정">
|
|
<defs><marker id="f8a" markerWidth="10" markerHeight="10" refX="7" refY="3.5" orient="auto"><path d="M0,0 L7,3.5 L0,7 Z" fill="#7c3aed"></path></marker></defs>
|
|
<!-- screen -->
|
|
<rect x="40" y="35" width="200" height="130" rx="6" fill="#0b1020" stroke="#444"></rect>
|
|
<text x="140" y="28" text-anchor="middle" font-size="12" fill="#333">영상 화면</text>
|
|
<circle cx="160" cy="80" r="6" fill="#f59e0b"></circle>
|
|
<text x="100" y="105" font-size="11" fill="#fde68a">여기로 끌었다</text>
|
|
<!-- ground -->
|
|
<line x1="300" y1="175" x2="620" y2="175" stroke="#8b5e34" stroke-width="3"></line>
|
|
<text x="300" y="195" font-size="11" fill="#7c5a3a">실제 땅</text>
|
|
<!-- ray from screen point to ground point -->
|
|
<line x1="166" y1="82" x2="540" y2="170" stroke="#7c3aed" stroke-width="2" stroke-dasharray="5 4" marker-end="url(#f8a)"></line>
|
|
<circle cx="540" cy="170" r="6" fill="#7c3aed"></circle>
|
|
<text x="470" y="160" font-size="12" font-weight="bold" fill="#6d28d9">진짜 위치!</text>
|
|
<text x="250" y="60" font-size="12" fill="#6d28d9">화면의 점 → 거꾸로 따라가 → 실제 위치 계산</text>
|
|
</svg>
|
|
<figcaption>그림 8. 화면에서 끈 점을 거꾸로 따라가 실제 위치를 찾아 자동 보정합니다.</figcaption>
|
|
</figure>
|
|
|
|
<hr />
|
|
<h2 id="3-측점測點--우리-영상의-km-표지판">3. 측점(測點) — 우리 영상의 'km 표지판'</h2>
|
|
<h3 id="3-1-측점이-뭐예요">3-1. 측점이 뭐예요?</h3>
|
|
<p>고속도로의 <strong>"서울 기점 158km"</strong> 표지판처럼, 철도도 <strong>시작점에서 몇 m 떨어졌는지</strong>를 나타내는 표지가 있어요. 이게 <strong>측점(체이니지)</strong> 입니다. 예: <code>158k200</code> = 시작점에서 158,200m 지점.</p>
|
|
<p>이 프로그램은 영상의 매 순간을 <strong>"지금 측점 몇을 보고 있다"</strong> 로 바꿔, <strong>시간이 아니라 위치로</strong> 영상을 탐색합니다.</p>
|
|
<h3 id="3-2-드론-위치를-측점으로-바꾸기">3-2. 드론 위치를 측점으로 바꾸기</h3>
|
|
<p>드론은 철길 바로 위가 아니라 <strong>비스듬히 옆/위</strong>에서 날아요. 그래서 드론 위치를 <strong>철길 선 위로 수직으로 내려찍어</strong> 측점을 읽습니다.</p>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 210" role="img" aria-label="측점 수직투영">
|
|
<!-- route line with ticks -->
|
|
<polyline points="40,150 180,140 330,135 480,140 600,150" fill="none" stroke="#06a4c8" stroke-width="4"></polyline>
|
|
<g font-size="11" fill="#0369a1">
|
|
<line x1="110" y1="138" x2="110" y2="160" stroke="#0369a1"></line><text x="92" y="176">157k</text>
|
|
<line x1="255" y1="132" x2="255" y2="155" stroke="#0369a1"></line><text x="237" y="171">158k</text>
|
|
<line x1="405" y1="134" x2="405" y2="157" stroke="#0369a1"></line><text x="387" y="173">159k</text>
|
|
</g>
|
|
<text x="46" y="135" font-size="12" fill="#0369a1">선로(측점 표지)</text>
|
|
<!-- drone -->
|
|
<circle cx="330" cy="60" r="9" fill="#2563eb"></circle>
|
|
<text x="345" y="58" font-size="13" font-weight="bold" fill="#1e3a8a">드론</text>
|
|
<text x="345" y="74" font-size="11" fill="#555">(옆/위에서 비스듬히)</text>
|
|
<!-- perpendicular drop -->
|
|
<line x1="330" y1="68" x2="330" y2="133" stroke="#f59e0b" stroke-width="2" stroke-dasharray="5 4"></line>
|
|
<circle cx="330" cy="135" r="6" fill="#b45309"></circle>
|
|
<text x="338" y="128" font-size="12" font-weight="bold" fill="#b45309">158k170</text>
|
|
</svg>
|
|
<figcaption>그림 9. 드론 위치를 선로로 수직으로 내려 "지금 보는 측점"을 10m 단위로 읽습니다.</figcaption>
|
|
</figure>
|
|
|
|
<h3 id="3-3-왜-같은-측점이-여러-군데-보일까">3-3. 왜 같은 측점이 여러 군데 보일까?</h3>
|
|
<p>조차장·종점에선 드론이 <strong>같은 곳을 앞뒤로 여러 번</strong> 지나가요. 그러면 같은 측점이 여러 번 찍힙니다.</p>
|
|
<blockquote>
|
|
<p>🚂 <strong>비유</strong>: 운동장 트랙을 두 바퀴 돌면 "출발선"을 두 번 지나죠. 잘못된 게 아니라 정말 두 번 지난 거예요.</p>
|
|
</blockquote>
|
|
<h3 id="3-4-왜-시간-막대가-아니라-거리-막대일까">3-4. 왜 '시간 막대'가 아니라 '거리 막대'일까?</h3>
|
|
<p>드론은 <strong>가만히 떠 있기(호버)</strong> 도 하고 <strong>앞뒤로 왔다 갔다</strong> 해요. 시간 막대면 드론이 멈춰도 커서가 계속 흘러가 어긋납니다. 그래서 <strong>실제 움직인 거리</strong> 기준으로 막대를 만들었어요 — <strong>멈추면 커서도 멈추고, 움직인 만큼만 이동.</strong></p>
|
|
<blockquote>
|
|
<p>🥾 <strong>비유</strong>: 등산 앱이 "몇 시간째"가 아니라 "<strong>몇 km 걸었는지</strong>"를 보여주는 것. 쉬면 점이 안 움직이죠.</p>
|
|
</blockquote>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 220" role="img" aria-label="시간 막대 vs 거리 막대">
|
|
<!-- time bar -->
|
|
<text x="40" y="42" font-size="13" font-weight="bold" fill="#b91c1c">시간 막대 ✗</text>
|
|
<rect x="40" y="55" width="500" height="16" rx="8" fill="#e5e7eb"></rect>
|
|
<rect x="40" y="55" width="380" height="16" rx="8" fill="#fca5a5"></rect>
|
|
<circle cx="420" cy="63" r="10" fill="#dc2626"></circle>
|
|
<text x="200" y="95" font-size="12" fill="#b91c1c">드론이 멈춰(호버) 있어도 커서가 계속 흘러감 → 위치와 어긋남</text>
|
|
<!-- distance bar -->
|
|
<text x="40" y="150" font-size="13" font-weight="bold" fill="#166534">거리 막대 ✓</text>
|
|
<rect x="40" y="163" width="500" height="16" rx="8" fill="#e5e7eb"></rect>
|
|
<rect x="40" y="163" width="250" height="16" rx="8" fill="#86efac"></rect>
|
|
<circle cx="290" cy="171" r="10" fill="#16a34a"></circle>
|
|
<text x="200" y="203" font-size="12" fill="#166534">호버(정지) 중엔 커서도 멈춤 → "지금 보는 위치"와 일치</text>
|
|
</svg>
|
|
<figcaption>그림 10. 시간 막대는 멈춰도 커서가 흐르지만, 거리 막대는 움직인 만큼만 이동합니다.</figcaption>
|
|
</figure>
|
|
|
|
<p>진행 방향(앞으로/뒤로)은 막대의 <strong>색</strong>(주황=정방향, 청록=역방향)으로 구분합니다.</p>
|
|
<h3 id="3-5-측점을-검색하면-빙글빙글-순환-이동">3-5. 측점을 검색하면 빙글빙글 (순환 이동)</h3>
|
|
<p>측점값을 입력하고 <strong>Enter</strong>를 치면 그 지점으로 이동, 또 치면 <strong>다음 지점</strong>, 마지막이면 <strong>처음으로</strong> 돌아와요.</p>
|
|
<blockquote>
|
|
<p>🔁 <strong>비유</strong>: 워드의 "다음 찾기"를 반복하면 같은 단어를 차례로 돌다가 처음으로 돌아오죠.</p>
|
|
</blockquote>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 170" role="img" aria-label="측점 검색 순환">
|
|
<defs><marker id="f11a" markerWidth="9" markerHeight="9" refX="6" refY="3" orient="auto"><path d="M0,0 L6,3 L0,6 Z" fill="#b45309"></path></marker></defs>
|
|
<rect x="40" y="95" width="560" height="14" rx="7" fill="#e5e7eb"></rect>
|
|
<g>
|
|
<circle cx="150" cy="102" r="11" fill="#f59e0b"></circle><text x="150" y="106" text-anchor="middle" font-size="11" font-weight="bold" fill="#fff">1</text><text x="120" y="135" font-size="11" fill="#7c2d12">162k080</text>
|
|
<circle cx="330" cy="102" r="11" fill="#f59e0b"></circle><text x="330" y="106" text-anchor="middle" font-size="11" font-weight="bold" fill="#fff">2</text><text x="300" y="135" font-size="11" fill="#7c2d12">162k080</text>
|
|
<circle cx="510" cy="102" r="11" fill="#f59e0b"></circle><text x="510" y="106" text-anchor="middle" font-size="11" font-weight="bold" fill="#fff">3</text><text x="480" y="135" font-size="11" fill="#7c2d12">162k080</text>
|
|
</g>
|
|
<path d="M162,90 Q240,60 318,90" fill="none" stroke="#b45309" stroke-width="1.5" marker-end="url(#f11a)"></path>
|
|
<path d="M342,90 Q420,60 498,90" fill="none" stroke="#b45309" stroke-width="1.5" marker-end="url(#f11a)"></path>
|
|
<path d="M510,118 Q330,165 150,118" fill="none" stroke="#b45309" stroke-width="1.5" stroke-dasharray="5 4" marker-end="url(#f11a)"></path>
|
|
<text x="270" y="52" font-size="12" fill="#b45309">Enter → 다음</text>
|
|
<text x="290" y="160" font-size="12" fill="#b45309">끝나면 처음으로</text>
|
|
</svg>
|
|
<figcaption>그림 11. 같은 측점이 여러 곳이면, Enter를 누를 때마다 다음으로·끝나면 처음으로 순환합니다.</figcaption>
|
|
</figure>
|
|
|
|
<h3 id="3-6-진짜-측점과-근처라서-찍힌-것-구분-kmexists">3-6. '진짜 측점'과 '근처라서 찍힌 것' 구분 (kmExists)</h3>
|
|
<p>어떤 역 <strong>근처를</strong> 지나가면 동그라미가 찍히는데, 그 자리 실제 측점값이 역의 값과 <strong>다를 수도</strong> 있어요. 그러면 <strong>동그라미는 남기고, 측점값 숫자만 숨깁니다.</strong></p>
|
|
<blockquote>
|
|
<p>🏷️ <strong>비유</strong>: "이 근처에 우체국 있음"은 표시하되, 정확한 주소가 아니면 주소 숫자는 안 붙이는 것.</p>
|
|
</blockquote>
|
|
<hr />
|
|
<h2 id="4-아주-큰-영상을-끊김-없이-트는-법">4. 아주 큰 영상을 끊김 없이 트는 법</h2>
|
|
<p><strong>2GB 넘는 영상</strong>을 통째로 읽으면 컴퓨터가 멈춰요. 그래서 <strong>보는 부분만 조금씩</strong>(약 10MB) 잘라 받고, 또는 <strong>몇 초짜리 조각들</strong>로 나눠 이어 붙여 재생합니다(유튜브 방식).</p>
|
|
<figure class="fig">
|
|
<svg viewBox="0 0 640 150" role="img" aria-label="스트리밍 조각">
|
|
<rect x="40" y="45" width="560" height="55" rx="6" fill="#eef2ff" stroke="#6366f1"></rect>
|
|
<g stroke="#a5b4fc" stroke-dasharray="4 3">
|
|
<line x1="120" y1="45" x2="120" y2="100"></line><line x1="200" y1="45" x2="200" y2="100"></line><line x1="280" y1="45" x2="280" y2="100"></line><line x1="360" y1="45" x2="360" y2="100"></line><line x1="440" y1="45" x2="440" y2="100"></line><line x1="520" y1="45" x2="520" y2="100"></line>
|
|
</g>
|
|
<rect x="280" y="45" width="80" height="55" fill="#f59e0b" opacity="0.85"></rect>
|
|
<text x="320" y="78" text-anchor="middle" font-size="11" font-weight="bold" fill="#fff">지금 보는</text>
|
|
<text x="320" y="118" text-anchor="middle" font-size="11" fill="#b45309">필요한 조각만 조금씩</text>
|
|
<text x="46" y="36" font-size="12" fill="#4338ca">큰 영상 (2GB+)</text>
|
|
</svg>
|
|
<figcaption>그림 12. 큰 영상을 통째로가 아니라, 보는 만큼 조각으로 잘라 받아 끊김을 막습니다.</figcaption>
|
|
</figure>
|
|
|
|
<p>오래 보면 데이터가 쌓여 메모리가 터질 수 있어, <strong>"지나간 30초치만 남기고 버리도록"</strong> 해 뒀습니다. 프레임(사진 한 장) 단위로 정확히 뽑을 땐 <strong>FFmpeg</strong>라는 전문 도구가 그 장면을 잘라 줍니다.</p>
|
|
<hr />
|
|
<h2 id="5-분명히-고쳤는데-화면이-그대로예요-꼭-알아둘-점">5. "분명히 고쳤는데 화면이 그대로예요?" (꼭 알아둘 점)</h2>
|
|
<p>우리가 보는 화면은 <strong>"차린 음식(빌드 결과물)"</strong> 을 보여줍니다. <strong>"날재료(코드)"</strong> 를 고쳐도 <strong>다시 요리(빌드)</strong> 하지 않으면 식탁은 그대로예요.</p>
|
|
<blockquote>
|
|
<p>🍳 <strong>비유</strong>: 레시피를 고쳐도 다시 요리해 차리기 전엔 식탁 음식은 안 바뀝니다.</p>
|
|
</blockquote>
|
|
<p>그래서 코드를 고치면 ① <strong>다시 빌드</strong> → ② 브라우저 <strong>새로고침</strong>(Ctrl+Shift+R) → ③ <strong>폴더 다시 선택</strong> 해야 바뀐 내용이 보입니다.</p>
|
|
<hr />
|
|
<h2 id="6-이게-왜-특별한특허감-기술일까">6. 이게 왜 '특별한(특허감)' 기술일까?</h2>
|
|
<ol type="1">
|
|
<li><strong>측량 측점 높이로, 비싼 3D 지형 없이 정합</strong> (2-4) + 두 높이 기준 자동 맞춤.</li>
|
|
<li><strong>한 번 끌어서 가로·세로·거리 동시 보정</strong> (2-7) — 보통은 깊이 측정 장비가 필요한 일을 장비 없이.</li>
|
|
<li><strong>상황 봐가며 조절하는 흔들림 잡기</strong> (2-6) — 부드러움과 빠른 반응을 동시에.</li>
|
|
<li><strong>시간이 아니라 '위치(측점)'로 영상을 다루기</strong> (3장) — 거리 막대·검색 순환·진짜/근처 구분 등.</li>
|
|
</ol>
|
|
<blockquote>
|
|
<p>⚠️ 단, 특허는 <strong>이미 비슷한 게 있는지(선행기술) 전문 검색</strong>을 꼭 해봐야 확정됩니다. (아직 미완)</p>
|
|
</blockquote>
|
|
<hr />
|
|
<h2 id="7-쉬운-용어-사전">7. 쉬운 용어 사전</h2>
|
|
<table>
|
|
<thead>
|
|
<tr class="header">
|
|
<th>용어</th>
|
|
<th>쉬운 뜻</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr class="odd">
|
|
<td><strong>측점(체이니지)</strong></td>
|
|
<td>노선 시작점에서 몇 m 떨어졌는지 나타내는 '철길 km 표지판'</td>
|
|
</tr>
|
|
<tr class="even">
|
|
<td><strong>위도·경도</strong></td>
|
|
<td>지구 위 위치를 나타내는 두 숫자</td>
|
|
</tr>
|
|
<tr class="odd">
|
|
<td><strong>yaw / pitch / roll</strong></td>
|
|
<td>카메라가 좌우로 돈 / 아래로 숙인 / 옆으로 기운 정도</td>
|
|
</tr>
|
|
<tr class="even">
|
|
<td><strong>투영(projection)</strong></td>
|
|
<td>입체(3D)를 납작한 화면(2D)에 그리는 것 (원근법)</td>
|
|
</tr>
|
|
<tr class="odd">
|
|
<td><strong>역투영</strong></td>
|
|
<td>그 반대 — 화면의 한 점이 실제 어디인지 거꾸로 찾는 것</td>
|
|
</tr>
|
|
<tr class="even">
|
|
<td><strong>화각(FOV)</strong></td>
|
|
<td>카메라가 얼마나 넓게 보는지 (광각=넓게, 줌=좁게)</td>
|
|
</tr>
|
|
<tr class="odd">
|
|
<td><strong>지오이드</strong></td>
|
|
<td>'해발고도'의 기준(평균 바닷물 높이). GPS 높이와 기준이 달라 변환 필요</td>
|
|
</tr>
|
|
<tr class="even">
|
|
<td><strong>DEM</strong></td>
|
|
<td>땅의 높낮이를 담은 3D 지형 데이터(보통 비쌈)</td>
|
|
</tr>
|
|
<tr class="odd">
|
|
<td><strong>평활(스무딩)</strong></td>
|
|
<td>떨리는 값을 주변과 평균 내어 부드럽게 만드는 것</td>
|
|
</tr>
|
|
<tr class="even">
|
|
<td><strong>호버</strong></td>
|
|
<td>드론이 한자리에 떠서 멈춰 있는 상태</td>
|
|
</tr>
|
|
<tr class="odd">
|
|
<td><strong>스테이션바</strong></td>
|
|
<td>화면 아래의 측점(위치) 기반 진행 막대</td>
|
|
</tr>
|
|
<tr class="even">
|
|
<td><strong>빌드</strong></td>
|
|
<td>코드를 컴퓨터가 실행할 형태로 '요리'하는 과정</td>
|
|
</tr>
|
|
<tr class="odd">
|
|
<td><strong>스트리밍</strong></td>
|
|
<td>영상을 통째로 안 받고 보는 만큼 조금씩 받아 트는 것</td>
|
|
</tr>
|
|
</tbody>
|
|
</table>
|
|
<hr />
|
|
<h2 id="8-마치며">8. 마치며</h2>
|
|
<blockquote>
|
|
<p><strong>"드론이 어디서 어느 쪽을 보는지"</strong> 와 <strong>"지도에 무엇이 어디 있는지"</strong> 를 합쳐서, 영상 위에 정보를 정확히 붙이고, <strong>시간이 아니라 '측점(위치)'으로</strong> 영상을 탐색하게 해주는 도구.</p>
|
|
</blockquote>
|
|
<p>복잡해 보여도, 사실은 일상의 생각들 — <em>친구가 가리키는 곳 알아채기, 원근법, km 표지판, 등산 앱의 걸은 거리, 떨리는 선 다듬기</em> — 을 컴퓨터로 정밀하게 구현한 것뿐입니다. 🙂</p>
|
|
</body>
|
|
</html>
|