검색결과 리스트
분류 전체보기에 해당되는 글 456건
- 2025.05.20 티스토리에서 카카오 로그인시 튀어나오는 팝업 광고 삭제 방법
- 2025.04.03 포항 영일만 바닷가를 옆에 두고 - 영일만항선 영일만항역(2025.04.01)
- 2025.03.17 git 사용시 오류 발생 해결 방법 - schannel: next InitializedSecurityContext failed
- 2025.02.20 Pytorch로 학습한 Image AI모델을 Torchscript로 변환 및 실행방법
- 2025.01.14 Huggingface에서 데이터셋 다운로드가 계속 끊길때 해결방법
- 2025.01.02 VirtualBox에 Ubuntu 24.04를 설치 후 해상도 확장하는 방법
- 2024.12.28 Ubuntu 24.04에서 apt 저장소를 mirror 사이트를 변경하는 방법
- 2024.12.16 2024년의 끝을 앞두고 사라지다 - 중앙선 북영천역(+화본역)
- 2024.12.06 중앙선 이설전 마지막 풍경들 - 의성역~우보역 구간(2024.12.01)
- 2024.11.23 중앙선 이설전 마지막 풍경들 - 북영천역~갑현역 구간(2024.11.22)
- 2024.10.26 Flask 라이브러리로 이미지를 업로드하고 볼 수 있는 서버 구축하기
- 2024.09.30 중앙선에 남은 마지막 아담한 간이역 - 화본역(2024.07.27)
글
티스토리에서 카카오 로그인시 튀어나오는 팝업 광고 삭제 방법
평소 PC를 사용할때 의심스러운 프로그램은 절대 설치하지 않는 것을 원칙으로 해왔으며, 프로그램 설치 과정에서 무의식적으로 광고 프로그램 설치 버튼을 누르지 않으려 단계별로 꼼꼼히 확인하며 컴퓨터를 관리해왔던 저의 습관 덕분에 지난 7년동안 단 한번도 악성코드 없는 청정한 환경의 PC를 유지해왔습니다.
그러나 그토록 악성코드를 경계하면서 살아오던 저였습니다만 허무하게도 안타까운 상황이 벌어지고 말았습니다. 언제나 그랬듯이 평소처럼 티스토리에 오랜만에 포스팅을 작성하고자 티스토리에 접속한 다음
'카카오계정으로 로그인' 버튼을 클릭했더니
난생 처음보는 팝업창이 뙇! 하고 로그인창을 가려버립니다. '온라인쇼핑/금융사기 예방방법'이라는 거창한 제목을 적어두고는 'AD'라고 적혀있는 화면에서부터 굉장히 불순한 냄새가 풀풀 풍깁니다..
처음에는 단순한 팝업 예외처리 문제로 해결할 수 있으리라 판단되어 AdBlock을 Chrome 확장프로그램으로 설치하였습니다만 같은 현상이 계속 나타는 것이었습니다. 심지어 저와 같은 현상이 발생하는 다른 블로거 분들의 해결책을 써봐도 도통 해결이 되지 않고 있던 찰나...
우연히 발견한 이 분께서 작성하신 포스팅의 내용대로 제 의도와는 하등 관계없이 컴퓨터에 악성코드가 강제로 설치되어 버렸고 이로 인해 티스토리 로그인을 시도할 때 마다 악질같은 광고창이 계속 뜨는 현상이 발생하는 것임을 알게 되었습니다.
(극강 무료 프로그램) 로그인 시, 팝업광고 노출 악성코드 멀웨어 제거 방법
어느 날, 티스토리 블로그를 하기 위해 [로그인]을 하는 순간, 갑자기 [팝업 광고]가 똭! 하니 등장했습니다. 허걱! ''이게 뭐지?' "뭔가 프로그램(앱)을 깔았나?" "별로 설치한 것도 없는데..."
reportandmore.tistory.com
위 포스팅에서 소개한 악성코드 제거 도구인 'Malware Zero'를 아래의 공식 웹페이지를 통해 바로 다운로드하였습니다.
Malware Zero - 무료 악성코드 제거 도구
악성코드 및 애드웨어 등 각종 유해 프로그램에 의한 고통에서 해방되기 위해 설치 없이 사용 가능한 무료 악성코드 제거 도구
malzero.xyz
Malware Zero를 다운로드한 다음 압축을 해제하면 'malzero'라는 이름의 폴더를 연 다음 'start'를 관리자권한으로 실행하였습니다.
아래와 같은 창들에서 '예'를 클릭하고
아래의 화면과 같이 Malware Zero가 검사를 수행합니다. 저의 경우 약 20분 정도 수행되었습니다. 한동안 백신 검사를 수행하지 않았어서 그런지 마치 내 하드디스크의 묵은 때를 벆벆 긁어내듯이 악성코드 제거 프로그램이 악성코드를 찾아내는 듯한 느낌이었습니다.
아래와 같은 화면이 나오면 검사가 완료된 것입니다.
창을 닫자마자 메모장이 열리며 검사 결과를 알려줍니다.(생각보다 너무나도 많은 악성코드들이 발견되어 놀랐습니다. 나름 주의를 기울이며 PC를 써왔음에도 이렇게 속수무책으로 당하고 있었을 줄은 생각도 못했습니다.)
검사가 끝난 후 컴퓨터를 껏다 킨 다음 티스토리 로그인을 시도해보니 다행히도 지금까지 지금껏 저를 괴롭히던 악성 팝업 광고창이 나타나지 않고 있습니다. 이 프로그램으로 원인을 찾아내고 악성코드를 말끔히 제거하니 7년 묵은 제 PC가 새 PC마냥 산뜻해진 듯한 느낌입니다.
혹시 이 글을 보고 계신 여러분들 중에도 저와 같은 현상이 반복되시는 분이 계시다면 지금 바로 Malware Zero를 다운로드하여 PC 내에 악성코드가 있는지 확인해보시기 바랍니다!
'공대생의 팁' 카테고리의 다른 글
Huggingface에서 데이터셋 다운로드가 계속 끊길때 해결방법 (0) | 2025.01.14 |
---|---|
Flask 라이브러리로 이미지를 업로드하고 볼 수 있는 서버 구축하기 (0) | 2024.10.26 |
Windows Powershell에서 python 실행시 환경변수 설정 방법 (0) | 2024.05.28 |
[mmcv] AssertionError: only one of size and size_divisor should be valid (0) | 2024.03.31 |
LabelMe로 Coco 데이터셋 변환후 MMDetection에서 학습이 안될 때 해결 방법 (0) | 2024.03.26 |
설정
트랙백
댓글
글
포항 영일만 바닷가를 옆에 두고 - 영일만항선 영일만항역(2025.04.01)
코로나 시기에 서핑이 유행하던 즈음 영일만항 인근에 있는 용한리 해수욕장에서 서핑을 도전해본 적이 있었습니다. 가던 길에 6차선 도로를 철길건널목으로 가르질러 컨테이너가 가득한 항만으로 이어지던 영일만항선 철길이 보았었습니다.
영일만항선은 10년전 포항역이 시내에서 외곽으로 이설되는 과정에서 신축 역사에서 영덕 방면 연장 구간에서 분기하여 영일만항에서 화물을 취급하기 위해 2019년에 신설된 노선으로 여객 취급이 없는 구간이다 보니 이 곳을 찾아오는 분들은 해수욕장을 방문하는 분들이 거의 대부분일겁니다.
지난 여름 서핑을 즐기며 보던 바다의 모습을 다시 한 번 보는 김에 영일만항역을 찾아가 보았습니다.
포항 시내 외곽에 위치한 영일만대로를 쭈욱 달려오면 영일만항로와 접하는 삼거리가 나오는데 바로 그 앞에 보이는 건물이 영일만항역입니다.
3년전에 왔을때엔 없던 역명판을 붙여놓았네요. 항만 내 역의 위치를 확실히 알 수 있게 되었습니다.
영일만대로 북쪽으로 가다보면 6차선을 가로지르는 영일만신항건널목이 나타납니다.
철길이 대로를 비스듬히 지나가다보니 건널목 길이가 꽤 깁니다.
항만으로 들어가는 길은 열차가 통과하지 않는 시간에는 굳건히 닫혀있습니다.
용한리 해수욕장 방향을 바라본 모습
항만 내부 방향으로 찍은 모습입니다.
건널목의 규모가 크지만 열차 통행이 빈번하지는 않아 큰 사고가 날 것 같지는 않을거같습니다.
시내와는 동떨어진 곳이어서 차량도 많이 다니지는 않다보니 건널목을 설치해도 큰 문제는 없어보입니다.
항만에서 곧 열차가 나올 시간이 다가오자 건널목 신호기가 요란한 소리를 내기 시작합니다.
워낙에 넓은 대로에 있는 건널목이어서 차단봉이 휠 정도로 길다랗습니다.
컨테이너 화물이 연결된 기관차가 항만을 빠져나오기 시작합니다.
건널목관리원이 주변 차량들을 통제하고 있습니다.
열차가 통과하는 모습을 보고 가려고 했는데 건널목관리원분께서 저에게 걸어오셔서 뭘 찍고있는지 물어보셨습니다. 열차가 나오는 시간을 어떻게 알고 찾아왔는지 저를 의심하는 질문에 대해 기차를 좋아해서 사진을 찍고 싶어 찾아왔다는 대답을 해드리니 상황을 어느정도 이해하시고 대기실로 돌아가셨습니다.
용한리 해수욕장에서 영일만항을 바라보며 하루를 마칩니다..
'좌충우돌 여행기 > 국내여행' 카테고리의 다른 글
2024년의 끝을 앞두고 사라지다 - 중앙선 북영천역(+화본역) (0) | 2024.12.16 |
---|---|
중앙선 이설전 마지막 풍경들 - 의성역~우보역 구간(2024.12.01) (0) | 2024.12.06 |
중앙선 이설전 마지막 풍경들 - 북영천역~갑현역 구간(2024.11.22) (0) | 2024.11.23 |
중앙선에 남은 마지막 아담한 간이역 - 화본역(2024.07.27) (0) | 2024.09.30 |
뒤바뀐 운명 - 중앙선 건천역과 아화역(2024.07.27) (0) | 2024.07.28 |
설정
트랙백
댓글
글
git 사용시 오류 발생 해결 방법 - schannel: next InitializedSecurityContext failed
사내에서 git으로 라이브러리를 다음과 같이 다운로드를 시도하였습니다.
$ git clone https://github.com/open-mmlab/mmcv.git
그런데, 다음과 같은 오류가 발생하였습니다.
fatal: unable to access 'https://github.com/open-mmlab/mmcv.git/': schannel: next InitializeSecurityContext failed: CRYPT_E_REVOCATION_OFFLINE (0x80092013)
위 에러는 사내 보안에 의해 SSL 관련 기능들이 차단되어 발생하는 오류였습니다. 아래와 같이 git에서 ssl체크 기능을 사용하지 않으면 git을 정상적으로 사용할 수 있습니다.
$ git -c http.sslVerify=false clone http://github.com/open-mmlab/mmcv.git/
'프로그래밍 팁' 카테고리의 다른 글
Pytorch로 학습한 Image AI모델을 Torchscript로 변환 및 실행방법 (0) | 2025.02.20 |
---|---|
VirtualBox에 Ubuntu 24.04를 설치 후 해상도 확장하는 방법 (0) | 2025.01.02 |
Ubuntu 24.04에서 apt 저장소를 mirror 사이트를 변경하는 방법 (0) | 2024.12.28 |
MMCV 라이브러리로 Custom AI모델을 만들어보자!(1) - Backbone 추가하기 (2) | 2024.08.31 |
회전 이미지를 직사각형으로 Labeling하는 방법 - roLabelImg (0) | 2024.02.25 |
설정
트랙백
댓글
글
Pytorch로 학습한 Image AI모델을 Torchscript로 변환 및 실행방법
Torchscript에 대해 검색을 하는 과정에서 제 글을 찾기까지 여러분께서는 Torchscript에 대해 많은 내용들을 배우셨으리라 생각합니다.
그럼에도 수많은 Torchscript에 다룬 글들을 끊임없이 찾다 제 블로그를 발견하신 여러분들이라면 아마도 이러한 고민을 하셨을 것으로 어림 짐작해봅니다.
"간단한 예제들을 보면서 Torchscript에 대해 이해할 수 있었습니다. 하지만 내가 학습한 AI 모델을 Torchscript로 변환하려면 어떻게 해야하죠?
저 또한 지금까지 Torchscript 이론 및 예제들을 익혀보았지만, 실무에 바로 적용하기엔 뭔가 부족한 느낌을 많이 받았습니다. 카메라 영상 데이터를 사용하여 AI모델을 만들고 있는 저에게 있어 영상 데이터를 입력값으로 하는 Torchscript 예제를 찾기가 상당히 어려웠습니다. 다행히도 수없이 많은 구글링과 ChatGPT의 도움 덕에 Torchscript모델을 현업에 적용하는데 간신히 성공하였습니다.
이 포스팅에서는 컬러 이미지를 입력으로 받는 AI모델을 Torchscript로 변환한 후 활용하는 과정들을 기록하였습니다. 혹시나 Torchscript에 대해 이론적인 지식을 필요로 하시는 분들께서는 아래의 자료를 참조해주셨으면 합니다.
https://velog.io/@dev_junseok_22/TorchScript-%EC%86%8C%EA%B0%9C
TorchScript 소개
TorchSciprt는 PyTorch 모델을 프로덕션 환경에서 쉽게 사용할 수 있도록 설계된 언어 및 컴파일러입니다. PyTorch는 주로 연구 및 개발에 사용되는 파이썬 기반의 딥러닝 프레임워크이지만, 프로덕션
velog.io
아래 코드를 통해 Vision AI모델을 TorchScript로 변환하고 실행하는 예제를 확인하실 수 있습니다.
먼저, Pytorch로 학습한 AI모델을 TorchScript로 변환합니다 여기서는 TorchVision에서 제공되는 Pretrained Model을 변환해보겠습니다.
1
2
3
4
5
6
7
8
9
10
11
12
|
import torch
import torchvision
# TorchVision에서 제공하는 모델을 로드
model = torchvision.models.resnet18(pretrained=True)
# 모델을 평가 모드로 전환
model.eval()
# Trace 방식으로 TorchScript 변환
example_input - torch.randn(1, 3, 512, 512)
traced_model = torch.jit.trace(model, example_input)
# TorchScript 모델 저장
traced_model.save('end2end.pt')
|
cs |
다음은 TorchScript로 변환된 AI모델을 Inference 하는 방법입니다.
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
|
import cv2
import numpy as np
import torch
import os
import glob
from torchvision import transforms
# AI모델을 학습하였을 때 사용한 이미지 Dataset의 정보
mean=[95.5142,114.2475,112.4564]
std=[40.0954,43.8636,38.223]
input_size=(512,512)
# 입력 데이터로 사용할 이미지 불러오기
image_path = "input_image.jpg"
img = cv2.imread(image_path)
height, width, c = img.shape
# AI모델의 Input 양식으로 변환
inputs = cv2.resize(img, input_size)
inputs = (inputs - mean) / std
# 이미지 데이터를 PyTorch 텐서로 변환
toTensor = transforms.ToTensor()
input_tensor = toTensor(inputs.astype(np.float32))
# 입력 이미지의 Tensor 차원을 추가함
# RGB 이미지 기준으로 Tensor가 (3,512,512)에서 (1,3,512,512)로 차원이 증가함
# Batch Size가 1인 입력으로 만들어 AI모델에 입력하는 것임
# to('cuda')로 Tensor값을 GPU메모리에 올림
input_batch = input_tensor.unsqueeze(0).to('cuda:1')
# 저장된 TorchScript 모델 로드
script_model = torch.jit.load('end2end.pt')
# 모델을 GPU로 이동
script_model.to('cuda:1')
# 모델을 추론 모드로 설정
script_model.eval()
# 모델 추론
with torch.no_grad():
output = script_model(input_batch)
# 추론 결과를 GPU에서 CPU 메모리로 불러옴
inference_result = output.squeeze().cpu().numpy()
# 추론 결과를 이미지의 원본 크기로 Resize하여 결과 출력
seg = cv2.resize(inference_result, (width, height), interpolation=cv2.INTER_NEAREST)
|
cs |
이번 포스팅을 작성하면서 딥러닝 AI모델을 가공하는 과정들에 대해 다시 한 번 복습할 수 있었습니다.
실무자 입장에서 오픈소스로 공개된 라이브러리들이 이미지 전처리를 포함한 전반적인 학습 과정들을 포함해 잘 갖추어져 있어 가공되지 않은 원본 이미지를 입력으로 하면 곧바로 결과를 확인할 수 있다보니 Vision AI를 연구하는 입장으로서 AI모델의 학습과정에 필요한 기초적인 내용들에 대해 어렴풋이만 알고 있었다가 Torchscript로 변환된 모델을 다루게 되면서 Low 데이터로부터 학습데이터를 가공하는 기술의 중요성을 깨닫게 되었습니다.
최신 AI 기술들의 경향을 따라가는 것은 중요하지만, 가끔은 AI의 기초를 다시 한 번 되짚어보는 것도 좋을것같습니다.
'프로그래밍 팁' 카테고리의 다른 글
git 사용시 오류 발생 해결 방법 - schannel: next InitializedSecurityContext failed (0) | 2025.03.17 |
---|---|
VirtualBox에 Ubuntu 24.04를 설치 후 해상도 확장하는 방법 (0) | 2025.01.02 |
Ubuntu 24.04에서 apt 저장소를 mirror 사이트를 변경하는 방법 (0) | 2024.12.28 |
MMCV 라이브러리로 Custom AI모델을 만들어보자!(1) - Backbone 추가하기 (2) | 2024.08.31 |
회전 이미지를 직사각형으로 Labeling하는 방법 - roLabelImg (0) | 2024.02.25 |
설정
트랙백
댓글
글
Huggingface에서 데이터셋 다운로드가 계속 끊길때 해결방법
Huggingface 라이브러리에서 제공되는 Transformer 모델을 테스트해보기 위해 PC에 실행 환경 구축을 시도해보고 있었습니다. trasforemrs, datasets 등 필요한 pip 라이브러를 설치한 후 아래와 같은 방법으로 python 스크립트를 작성하였습니다.
1
2
|
from datasets import load_dataset
ds = load_dataset('scene_parse_150', trust_remote_code=True)
|
cs |
그런데 데이터셋 다운로드가 진행되는 과정이 갑자기 중단되면서 에러가 발생합니다.
asyncio.exceptions.TimeoutError
fsspec.exceptions.FSTimeoutError
출력된 에러를 분석해보니 다운로드가 더이상 진행이 되지 않는 상황이 발생하였을 경우 datasets 라이브러리에서 다운로드를 중단시켜버립니다. 해당 라이브러리에서 다운로드 진행이 1초 이상 되지 않으면 프로그램이 종료되도록 설정되어 있는 것으로 제한시간을 넉넉하게 잡아주면 해결될 것 같아 아래와 같이 스크립트를 작성하였습니다.
1
2
3
4
5
|
from datasets import load_dataset
import aiohttp
ds = load_dataset('scene_parse_150',
trust_remote_code=True,
storage_options={'client_kwargs': {'timeout': aiohttp.ClientTimeout(total==3600)}})
|
cs |
위와 같이 설정해주었더니 다운로드가 끊기지 않고 완료되는 것을 확인할 수 있었습니다.
'공대생의 팁' 카테고리의 다른 글
티스토리에서 카카오 로그인시 튀어나오는 팝업 광고 삭제 방법 (0) | 2025.05.20 |
---|---|
Flask 라이브러리로 이미지를 업로드하고 볼 수 있는 서버 구축하기 (0) | 2024.10.26 |
Windows Powershell에서 python 실행시 환경변수 설정 방법 (0) | 2024.05.28 |
[mmcv] AssertionError: only one of size and size_divisor should be valid (0) | 2024.03.31 |
LabelMe로 Coco 데이터셋 변환후 MMDetection에서 학습이 안될 때 해결 방법 (0) | 2024.03.26 |
설정
트랙백
댓글
글
VirtualBox에 Ubuntu 24.04를 설치 후 해상도 확장하는 방법
매번 Ubuntu의 새로운 버전이 나올 때마다 평소대로 Virtualbox에 설치하여 체험을 해왔습니다만 이번 버전에서는 미묘한 변화로 인해 기존의 방식대로 설치가 되지 않는 문제가 발생하여 혹시나 저와 같은 문제가 있으신 분들을 위해 제가 설치했던 방법을 여러분들께 전달드리고자 합니다.
1. VirtualBox에 Ubuntu 24.04를 설치한 후 장치→ 게스트 확장 CD 이미지 삽입... 을 클릭하여 게스트 확장 CD를 가상머신에 삽입합니다.
2. 바탕화면에서 CD 아이콘이 생성되는 것을 확인하실 수 있습니다. 해당 아이콘을 클릭합니다.
3. 게스트 확장 설치 폴더가 열립니다. '프로그램 실행' 버튼을 눌러 설치를 진행합니다.
4. 관리자 권한 획득을 위한 비밀번호 입력 후 설치가 진행됩니다. 혹시 아래와 같은 화면이 나올 경우 Terminal에서 다음과 같은 명령어를 입력하여 bzip2를 설치합니다.
$ sudo apt install bzip2
아래와 같은 화면이 나온다면 VirtualBox Guest Addition이 정상적으로 설치되고 있는 것입니다.
이제 Ubuntu 가상머신을 껏다 키면 아래와 같이 해상도가 VirtualBox의 창 크기에 맞추어 변경되는 것을 확인하실 수 있습니다.
'프로그래밍 팁' 카테고리의 다른 글
git 사용시 오류 발생 해결 방법 - schannel: next InitializedSecurityContext failed (0) | 2025.03.17 |
---|---|
Pytorch로 학습한 Image AI모델을 Torchscript로 변환 및 실행방법 (0) | 2025.02.20 |
Ubuntu 24.04에서 apt 저장소를 mirror 사이트를 변경하는 방법 (0) | 2024.12.28 |
MMCV 라이브러리로 Custom AI모델을 만들어보자!(1) - Backbone 추가하기 (2) | 2024.08.31 |
회전 이미지를 직사각형으로 Labeling하는 방법 - roLabelImg (0) | 2024.02.25 |
설정
트랙백
댓글
글
Ubuntu 24.04에서 apt 저장소를 mirror 사이트를 변경하는 방법
지금까지 Ubuntu를 사용할 때 마다 apt를 사용시 다운로드 속도를 빠르게 하기 위해 mirror.kakao.com을 사용하고 있었습니다. 이번에 24.04에서도 미러사이트를 변경하려 하였는데 기존처럼 vi로 /etc/apt/sources.list 파일을 수정하려 했더니 이번 버전부터는 구조가 변경되어 아래 폴더에서 설정하는 것으로 변경되었습니다.
/etc/apt/sources.list.d/ubuntu.sources
위 폴더 내에 있는 파일 내에 설정된 kr.archive.ubuntu.com을 mirror.kakao.com으로 변경해주면 기존처럼 카카오 미러를 통해 apt를 설치할 수 있게 됩니다.
Ubuntu 데스크탑 버전을 사용하는 경우 아래와 같은 방법으로 좀 더 쉽게 apt저장소 사이트를 변경할 수 있습니다.
1. 데스크탑 왼쪽 윗부분을 마우스로 클릭합니다.
1. 검색창에 영어로 'soft'를 입력해주면 아래와 같은 화면이 나옵니다. '소프트웨어 및 업데이트'를 클릭합니다.
2. 설정 화면에서 '다운로드 위치' 클릭 후 '기타...'를 클릭합니다.
3. 아래와 같은 화면이 나왔다면 '대한민국→mirror.kakao.com'을 선택한 후 '서버 선택'을 클릭합니다.
4. Terminal에서 'sudo apt update' 명령어 입력시 apt가 미러사이트에 접속되는 것을 확인할 수 있습니다.
'프로그래밍 팁' 카테고리의 다른 글
Pytorch로 학습한 Image AI모델을 Torchscript로 변환 및 실행방법 (0) | 2025.02.20 |
---|---|
VirtualBox에 Ubuntu 24.04를 설치 후 해상도 확장하는 방법 (0) | 2025.01.02 |
MMCV 라이브러리로 Custom AI모델을 만들어보자!(1) - Backbone 추가하기 (2) | 2024.08.31 |
회전 이미지를 직사각형으로 Labeling하는 방법 - roLabelImg (0) | 2024.02.25 |
Windows 환경에서 MMDeploy로 TensorRT 구동(Python, C++) (0) | 2023.10.31 |
설정
트랙백
댓글
글
2024년의 끝을 앞두고 사라지다 - 중앙선 북영천역(+화본역)
일상생활 중에 언제나 여행계획을 짜보지만 날씨나 다른 일정등으로 연말까지 미루고 미루다 촉박하게 일정을 정하고 여행을 다녀오는 패턴이 매년 이어지고 있었는데 올해 또한 그렇게 되었습니다.
이번 포스팅에서는 2024년을 끝으로 영업을 마치게 되는 중앙선 북영천역을 다녀오게 되었습니다.
지난 11월말 안동에서 무궁화호를 타고 북영천역에 도착하였을 때였습니다.
선로 옆에 차후 하행선이 될 선로쪽에만 플랫폼을 만들어 둔 모습입니다.
플랫폼은 3량짜리 무궁화호가 설 만큼의 길이만큼 만들어져 있었습니다.
그래도 간이 대기 장소가 마련되어 나름 역의 구실을 하고 있었습니다.
북영천역은 동해-동대구 구간을 운행하는 무궁화호만 정차합니다.
제가 타고 온 동대구행 무궁화호 열차는 영천삼각선을 통해 바로 하양역으로 가기에 영천역을 가지 않습니다.
그래서 북영천역은 동해(구 강릉) - 동대구 구간을 운행하는 무궁화호 승객을 위해 만들어진 역입니다.
이 역은 왕복 2회(편도 4회)의 열차만 정차합니다. 동해-동대구 구간을 운행하는 무궁화호가 전부인 것이지요.
역 내부는 총 3개의 선로가 놓여져있습니다.
열차 운행 시간을 보면 평소에 이 역을 이용하기 어려운 시간대의 열차가 대부분입니다.
그래도 영천에 방문하고자 하는 승객을 위해 열차는 이 역에 정차해왔습니다.
이 곳에서 영천을 가는 열차도 이 곳을 통과하지면 이 역에 정차하지 않습니다.
왜냐하면, 이 역보다 영천역에서 더 많은 열차들이 정차를 하고
승객 입장에서 조금이나마 다양한 행선지가 있는 영천역을 더 선호할 것입니다.
그러기에 북영천역은 영천역을 경유하지 못하는 동해-동대구 구간 운행 열차의 여객취급만 합니다.
내년에는 동해-동대구 무궁화호 승객을 위해 운영되던 북영천역이 여객 취급을 중단합니다.
코레일의 공식 입장은 북영천-영천 이원화된 역 운영을 영천역으로 일원화 하는 것이 목적이라 합니다.
제 생각엔 코레일의 입장에서 북영천역 운영이 계륵같이 느껴졌으리라고 봅니다.
영천에 방문하고자 하는 고객들에게 북영천이라는 선택지를 지금껏 유지해 왔지만 실제 승객이 많지 않았고
중앙선 전구간의 복선전철화가 완료되어 지금보다 영천을 경유하는 열차편이 더 많아질테니
코레일의 입장에서는 북영천역의 여객취급을 계속 할만한 매리트가 없을만합니다.
북영천역에서 하차한 승객들이 모두 역을 빠져나가면
영천역에 있는 직원이 CCTV를 통해 모든 승객이 빠져나간 역 출입문을 폐쇄합니다.
이렇게 거대한 폴사인이 없었다면 사람들은 북영천의 존재를 알 수 있었을까요?
2024년 12월 14일. 이번에는 북영천역에서 열차를 탑승하기 위해 다시 방문하였습니다.
내일(2024년 12월 15일)을 끝으로 북영천역은 여객취급을 더이상 하지 않게 됩니다.
이제 영천역에서도 KTX를 타고 서울과 부산을 갈 수 있게 되었습니다.
결국 북영천역은 KTX는 커녕 ITX의 여객도 취급하지 못하고 더이상 승객을 받지 않게 됩니다.
열차가 정차하기 30분 전부터 출입문을 열어둡니다.
내일 오전을 끝으로 북영천역에 열차는 더이상 정차하지 않으며 한동안 임시버스가 무료로 운행됩니다.
비록 북영천역을 이용하는승객은 많지 않았지만 이 곳을 종종 쓰던 고객들은 어떤 기억을 남겼을까요?
역 입구에서 타는곳까지는 생각보다 많이 걸어야 했습니다.
여객취급을 중단하는 북영천역은 이후에도 분기 구간에서 신호장으로서의 역할을 계속 수행합니다.
신녕역 또한 이번을 끝으로 여객취급을 중단하게 됩니다.
물론 지금까지 이 곳을 들렀던 무궁화호 열차는 계속 정상운행합니다.
앞으로 영천에서 동해까지 가기 위해서는 영천역에서 하루 1회 운행하는 무궁화호를 타는 선택지만 남게됩니다.
역 주변을 둘러보다 기관차 한 대가 지나갑니다.
기관차가 멈칫하며 정지하더니 맞은편에서 열차가 나타납니다.
이 열차를 타고 저는 동대구역으로 이동할 것입니다.
그렇게 열차가 들어오고
열차는 요란한 소리를 내며 가던 길을 멈추어섭니다.
아래 사진은 같은날 오전 화본역을 둘러보다 몇장 찍어본것들입니다.
'좌충우돌 여행기 > 국내여행' 카테고리의 다른 글
포항 영일만 바닷가를 옆에 두고 - 영일만항선 영일만항역(2025.04.01) (0) | 2025.04.03 |
---|---|
중앙선 이설전 마지막 풍경들 - 의성역~우보역 구간(2024.12.01) (0) | 2024.12.06 |
중앙선 이설전 마지막 풍경들 - 북영천역~갑현역 구간(2024.11.22) (0) | 2024.11.23 |
중앙선에 남은 마지막 아담한 간이역 - 화본역(2024.07.27) (0) | 2024.09.30 |
뒤바뀐 운명 - 중앙선 건천역과 아화역(2024.07.27) (0) | 2024.07.28 |
설정
트랙백
댓글
글
중앙선 이설전 마지막 풍경들 - 의성역~우보역 구간(2024.12.01)
중앙선 전구간 이설이 완료되기 약 3주 정도 남은 시점에 곧 사라지게 될 풍경들을 사진에 남겨보고자 한 번 더 다녀와보았습니다. 이번에는 의성역~우보역 구간을 돌아다녀 보았습니다.
이화건널목
시간표를 확인하지 않고 오는 바람에 2시간 정도 기다리게 되었습니다. 남는 시간동안 동네를 돌아다녀봅니다.
군위가 귀산 박씨 집성촌인듯 보입니다.
낮선 외지인을 반기는 강아지
우보역
철길을 둘러보던 도중 길가 한복판에 우보역을 발견하였습니다.
역내에 상주하는 직원이 있는지 출입문이 막혀있지는 않았습니다.
우보역 시비
플랫폼은 영업하던 시절 그대로 유지되는듯 보입니다.
승강장으로 진입하는 건널목은 철거되어 있습니다.
역 구내를 둘러보고 바로 옆에 있는 건널목으로 이동합니다.
금천건널목
철길이 도로 바로 옆에 붙어있어 구도가 잘 나올거같습니다.
대리건널목
탑리역에서 의성역 방면으로 가면 처음으로 볼 수 있는 대리건널목
마을길 바로 옆을 따라가는 철길
만천건널목
'좌충우돌 여행기 > 국내여행' 카테고리의 다른 글
포항 영일만 바닷가를 옆에 두고 - 영일만항선 영일만항역(2025.04.01) (0) | 2025.04.03 |
---|---|
2024년의 끝을 앞두고 사라지다 - 중앙선 북영천역(+화본역) (0) | 2024.12.16 |
중앙선 이설전 마지막 풍경들 - 북영천역~갑현역 구간(2024.11.22) (0) | 2024.11.23 |
중앙선에 남은 마지막 아담한 간이역 - 화본역(2024.07.27) (0) | 2024.09.30 |
뒤바뀐 운명 - 중앙선 건천역과 아화역(2024.07.27) (0) | 2024.07.28 |
설정
트랙백
댓글
글
중앙선 이설전 마지막 풍경들 - 북영천역~갑현역 구간(2024.11.22)
다음달(2024년 12월 21일) 중앙선의 모든 구간 이설이 완공되어 KTX가 서울 청량리역에서부터 부산 부전역까지 달릴 예정입니다. 즉, 현재 마지막으로 남은 기존선 구간(안동 - 북영천) 또한 다음달부터는 열차가 더이상 달리지 않을 예정입니다.
차후 이설되어 볼 수 없게될 풍경들을 사진으로 남기고자 날씨가 화창하던날 마지막으로 남은 중앙선 기존구간을 다녀왔습니다.
첫 번째로 방문한 곳은 북영천역에서 출발한 열차가 처음으로 건널목을 통과하는 호당4건널목입니다.
호당4건널목
운좋게 도착하자마자 열차가 지나가는 것을 사진으로 남기는군요.
호당3건널목
호당2건널목
삼부건널목
화산역
화산역 광장에서 바라본 입구길. 역 바로 옆에 붉은 철문의 구 역세권 집이 인상적이었습니다.
역 내부를 보니 꽤 오래전 폐쇄된 흔적들을 볼 수 있었습니다.
유성1건널목
유성1건널목에서 바라본 화산역 구내
화남건널목
완전3건널목
주변에 건널목밖에 없는 이 곳에 새마을운동 기념 공원이 있었습니다.
왕복 4차선 도로가 이 건널목에서만 2차선으로 줄어듭니다. 아마도 선로이설 후 추가 공사를 하겠죠
공원에서 쉬다가 기차 구경하기는 딱 좋은 곳이었습니다.
하지만 내년부터는 이 곳에서 더이상 열차를 볼 수 없게 됩니다.
내년이면 이 곳도 4차선으로 확장되어 지금의 흔적은 볼 수 없을 것으로 보입니다.
신덕2건널목
한적한 시골 입구에 위치한 신덕2건널목입니다
마을 주변을 돌아다니던 도중 요란한 소리가 울려퍼지고
신녕역을 출발한 열차가 들어옵니다.
열차가 떠난 직후 모습
용천건널목
가일1건널목
왠지 침목으로 만든것으로 추정됩니다.
석촌2건널목
건널목 인근 회사에서 키우는 강아지가 일을 열심히 하는군요.
'좌충우돌 여행기 > 국내여행' 카테고리의 다른 글
2024년의 끝을 앞두고 사라지다 - 중앙선 북영천역(+화본역) (0) | 2024.12.16 |
---|---|
중앙선 이설전 마지막 풍경들 - 의성역~우보역 구간(2024.12.01) (0) | 2024.12.06 |
중앙선에 남은 마지막 아담한 간이역 - 화본역(2024.07.27) (0) | 2024.09.30 |
뒤바뀐 운명 - 중앙선 건천역과 아화역(2024.07.27) (0) | 2024.07.28 |
추운 겨울 한적한 마을에 역이 다시 들어서다 - 경의선 운천역[2022.12.18] (0) | 2022.12.23 |
설정
트랙백
댓글
글
Flask 라이브러리로 이미지를 업로드하고 볼 수 있는 서버 구축하기
※ 이 프로젝트는 ChatGPT로 생성된 코드를 사용하였습니다.
프로그래밍을 생업으로 일하시는 분들이라면 한 번 즈음은 자신이 사용해보지 못했던 프로그래밍 언어를 사용해야 할 수 밖에 없는 경험이 있으셨을 것입니다. 저 또한 Python을 위주로 개발을 하다보니 간혹 C/C++를 사용할 일이 있을 때엔 버벅거리면서 코딩을 간신히 해내곤 합니다.
그런 와중에 프로그램 시연을 해야 하는 상황이 되었는데 막상 준비하려 하니 1주일이라는 시간을 갖고는 GUI 프로그램을 뚝딱 만드는건 사실상 불가능한 상황이었습니다. 그러한 고민을 하던 상황에서 혹시나 Chat GPT에게 이러한 고민을 털어놨더니 Web프로그래밍으로 짧은 시간 내에 시각화를 할 수 있는 프로젝트를 만들 수 있다는 답변을 하는 것이었습니다!
지금까지 Web프로그래밍 관련 지식은 20년전 개인 홈페이지 제작을 위해 제로보드를 다루었던 경험밖에 없는 저에게 직접 Web프로그래밍을 하는 것은 불가능했습니다. 하지만 우리는 언제나 그랬듯이 방법을 찾아내왔지요?
이번 포스팅에서는 Web프로그래밍 경험이 없는 사람의 입장에서 ChatGPT에게 다음과 같은 질문을 하였고 아래와 같은 질문을 통해 매우 훌륭한 Web프로그램을 완성하였습니다.
Python을 사용해서 다음과 같은 프로그램을 만들어줘.
- 이미지를 웹사이트에 업로드 하고, 이를 볼 수 있는 웹사이트 제작
- 이미지를 볼 때 마우스의 휠로 이미지의 축소/확대 기능 적용
- 마우스로 드래그하여 확대된 이미지를 이동하며 볼 수 있도록함
- 이미지 뷰어의 아래쪽에는 Thumbnail 방식으로 업로드된 이미지를 클릭하여 볼 수 있도록 함
- 클립보드에 복사된 이미지를 웹페이지에 붙여넣기를 하는 방법으로 이미지를 업로드
- 업로드된 이미지는 OpenCV를 사용하여 grayscale 이미지를 생성하고, 원본 및 변환된 이미지를 볼 수 있도록 함
프롬프트의 전반적인 구조는 위와 같이 하여 질문을 하였고 몇몇 부분은 추가로 프롬프트를 작성하였으며, 부족한 부분은 직접 다듬었을 뿐인데 다행히도 원하는 대로 동작하는 웹사이트가 완성되었습니다!
아래는 ChatGPT가 Flask를 사용하여 만들어낸 프로젝트입니다. 아래는 프로젝트의 파일 구조입니다. app.py가 html을 제어하여 웹페이지를 동작시키는 것으로 이해하면 얼추 맞을 겁니다.
templates/index.html
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Drag and Drop Image Upload</title>
<style>
body {
display: flex;
flex-direction: column;
align-items: center;
justify-content: flex-start;
height: 100vh;
margin: 0;
background-color: #f5f5f5;
overflow: hidden;
/* Hide scrollbars */
}
#drop-area {
border: 2px dashed #ccc;
padding: 80px;
width: 100%;
height: 80px;
/* Increased height */
box-sizing: border-box;
/* Include padding and border in the element's total width and height */
text-align: center;
background-color: #fff;
position: fixed;
top: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
/* Center the text */
}
#drop-area p {
margin: 0;
font-size: 24px;
font-weight: bold;
/* Bold text */
}
#loading {
display: none;
/* Hide loading initially */
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: rgba(128, 128, 128, 0.7);
/* Gray with 70% opacity */
color: white;
padding: 40px;
/* Increased padding */
border-radius: 10px;
/* Increased border-radius */
text-align: center;
z-index: 1000;
/* Ensure loading screen overlaps all content */
font-size: 32px;
/* Larger font size for loading text */
font-weight: bold;
/* Bold text for loading */
}
#gallery {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: calc(100vh - 280px);
/* Full height minus drop area height, thumbnails, and border */
margin-top: 95px;
/* Adjusted to match drop-area height and border */
overflow: hidden;
position: relative;
/* Keep positioned relative to viewport */
border-bottom: 1px solid black;
/* Add bottom border for separation */
}
#thumbnails {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100px;
margin: 5px;
overflow-x: auto;
background-color: #f5f5f5;
position: fixed;
bottom: 0;
left: 0;
}
#thumbnails img {
height: 80px;
margin: 10px;
cursor: pointer;
transition: transform 0.25s ease;
}
#thumbnails img:hover {
transform: scale(1.1);
}
img {
max-width: 100%;
max-height: 100%;
transition: transform 0.25s ease;
/* Smooth transition for transform */
cursor: grab;
/* Cursor shows grab icon */
}
img:active {
cursor: grabbing;
/* Cursor shows grabbing icon */
}
</style>
</head>
<body>
<div id="loading">Loading...</div>
<h2>Drag and Drop Image Upload</h2>
<div id="drop-area">
<p>Drag & drop image files here<br>Or paste image from clipboard</p>
</div>
<div id="gallery"></div>
<div id="thumbnails"></div>
<script>
let dropArea = document.getElementById('drop-area');
let gallery = document.getElementById('gallery');
let thumbnails = document.getElementById('thumbnails');
let loading = document.getElementById('loading');
let currentImage;
let scale = 1;
let translateX = 0;
let translateY = 0;
dropArea.addEventListener('dragover', (event) => {
event.preventDefault();
dropArea.style.borderColor = 'green';
});
dropArea.addEventListener('dragleave', () => {
dropArea.style.borderColor = '#ccc';
});
dropArea.addEventListener('drop', (event) => {
event.preventDefault();
dropArea.style.borderColor = '#ccc';
thumbnails.innerHTML = ''; // Clear existing thumbnails on each drop
let files = event.dataTransfer.files;
handleFiles(files);
});
function handleFiles(files) {
([...files]).forEach(uploadFile);
}
async function uploadFile(file) {
// Show loading screen before starting upload
loading.style.display = 'block';
let url = '/upload';
let formData = new FormData();
formData.append('file', file);
try {
const response = await fetch(url, {
method: 'POST',
body: formData
});
const data = await response.json();
// Hide loading screen after upload is successful
displayImage(data.images[0]);
loading.style.display = 'none';
// Add the uploaded image to the thumbnails
data.images.forEach(imgUrl => addThumbnail(imgUrl))
} catch (error) {
console.error('Upload failed');
loading.style.display = 'none';
}
}
function displayImage(imageUrl) {
// Clear previous image
gallery.innerHTML = '';
// Create new image
const img = document.createElement('img');
img.src = imageUrl;
gallery.appendChild(img);
// Update current image reference
currentImage = img;
// Reset scale and position
scale = 1;
translateX = 0;
translateY = 0;
img.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
// Add drag-to-pan functionality
let isDragging = false;
let startX, startY;
img.addEventListener('mousedown', (event) => {
event.preventDefault();
isDragging = true;
startX = event.clientX - translateX;
startY = event.clientY - translateY;
img.style.cursor = 'grabbing';
});
document.addEventListener('mousemove', (event) => {
if (isDragging) {
event.preventDefault();
translateX = event.clientX - startX;
translateY = event.clientY - startY;
// Restrict movement within the boundaries
const rect = img.getBoundingClientRect();
const galleryRect = gallery.getBoundingClientRect();
// Calculate overflows
const overflowX = Math.max(0, rect.width * scale - galleryRect.width);
const overflowY = Math.max(0, rect.height * scale - galleryRect.height);
// Clamp translateX and translateY within allowed bounds
translateX = Math.min(overflowX / 2, Math.max(-overflowX / 2, translateX));
translateY = Math.min(overflowY / 2, Math.max(-overflowY / 2, translateY));
img.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
}
});
document.addEventListener('mouseup', () => {
if (isDragging) {
isDragging = false;
img.style.cursor = 'grab';
}
});
}
function addThumbnail(imageUrl) {
const thumb = document.createElement('img');
thumb.src = imageUrl;
thumb.addEventListener('click', () => {
displayImage(imageUrl);
});
thumbnails.appendChild(thumb);
}
// Zoom in/out handlers
gallery.addEventListener('wheel', (event) => {
if (currentImage) {
event.preventDefault();
if (event.deltaY > 0) {
// Scroll down - zoom out
scale *= 0.9;
} else {
// Scroll up - zoom in
scale *= 1.1;
}
scale = Math.min(Math.max(.125, scale), 4); // Restrict scale
// Restrict movement within the boundaries
const rect = currentImage.getBoundingClientRect();
const galleryRect = gallery.getBoundingClientRect();
// Calculate overflows
const overflowX = Math.max(0, rect.width * scale - galleryRect.width);
const overflowY = Math.max(0, rect.height * scale - galleryRect.height);
// Clamp translateX and translateY within allowed bounds
translateX = Math.min(overflowX / 2, Math.max(-overflowX / 2, translateX));
translateY = Math.min(overflowY / 2, Math.max(-overflowY / 2, translateY));
currentImage.style.transform = `translate(${translateX}px, ${translateY}px) scale(${scale})`;
}
});
// Add click event to hide loading screen in case of manual reset
loading.addEventListener('click', () => {
loading.style.display = 'none';
});
// Handle image paste from clipboard
window.addEventListener('paste', (event) => {
const items = event.clipboardData.items;
for (const item of items) {
if (item.type.startsWith('image/')) {
const file = item.getAsFile();
thumbnails.innerHTML = ''; // Clear existing thumbnails on paste
handleFiles([file]);
}
}
});
</script>
</body>
</html>
|
cs |
app.py
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
|
from flask import Flask, request, url_for, render_template, send_from_directory, jsonify
from time import time
import os
import cv2
app = Flask(__name__)
UPLOAD_FOLDER = r'D:\server\static\uploads'
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['MAX_CONTENT_PATH'] = 16 * 1024 * 1024
# Ensure the upload directory exists
if not os.path.exists(app.config['UPLOAD_FOLDER']):
os.makedirs(app.config['UPLOAD_FOLDER'])
@app.route('/')
def index():
return render_template('index.html')
@app.route('/upload', methods=['POST'])
def upload_file():
if 'file' not in request.files:
return 'No file part'
file = request.files['file']
if file.filename == '':
return 'No selected file'
if file:
image_paths = []
input_image_path = 'input_image.jpg'
filepath = os.path.join(app.config['UPLOAD_FOLDER'], input_image_path)
file.save(filepath)
image_paths.append(url_for('uploaded_file', filename=input_image_path) + '?' + str(int(time())))
img = cv2.imread(filepath)
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
gray_filepath = os.path.join(app.config['UPLOAD_FOLDER'], 'gray_' + os.path.basename(filepath))
cv2.imwrite(gray_filepath, gray_img)
image_paths.append(url_for('uploaded_file', filename='gray_' + os.path.basename(filepath)) + '?' + str(int(time())))
# Return the URL to access the uploaded file
return jsonify(images=image_paths)
return 'File not uploaded correctly'
@app.route('/uploads/<filename>')
def uploaded_file(filename):
return send_from_directory(app.config['UPLOAD_FOLDER'], filename)
if __name__ == '__main__':
# 모든 외부 접속 허용시 host='0,0,0,0' 설정
app.run(debug=True, host='0,0,0,0', port=5000)
|
cs |
- 결과
저는 지금까지 제 블로그에는 제가 직접 작성한 소스코드를 업로드 해왔었습니다. 그러했던 제가 최근에는 ChatGPT에게 원하는 시스템의 전반적인 내용을 작성 시키고, 저는 그 코드에서 제가 원하는 기능들을 덮붙이는 식으로 일을 수행하고 있습니다. AI를 연구하는 입장에서 어느덧 AI와 함께 협업을 하며 일을 하는 세상이 되었다는 것이 참으로 놀라운 세상이네요. 앞으로도 ChatGPT를 사용해 업무 효율을 높일수 있는 기회들이 이번처럼 많아진다면 앞으로는 지금보다 업무 생산성이 많이 높아질 것이라 기대를 해봅니다.
'공대생의 팁' 카테고리의 다른 글
티스토리에서 카카오 로그인시 튀어나오는 팝업 광고 삭제 방법 (0) | 2025.05.20 |
---|---|
Huggingface에서 데이터셋 다운로드가 계속 끊길때 해결방법 (0) | 2025.01.14 |
Windows Powershell에서 python 실행시 환경변수 설정 방법 (0) | 2024.05.28 |
[mmcv] AssertionError: only one of size and size_divisor should be valid (0) | 2024.03.31 |
LabelMe로 Coco 데이터셋 변환후 MMDetection에서 학습이 안될 때 해결 방법 (0) | 2024.03.26 |
설정
트랙백
댓글
글
중앙선에 남은 마지막 아담한 간이역 - 화본역(2024.07.27)
1939년 4월 처음으로 개통한 중앙선은 1942년 4월 청량리-경주 전구간이 개통되었을 당시 많은 승객들이 각 지역을 잇는 구불구불한 철로를 따라 서있던 간이역들을 통해 열차를 이용해왔었습니다. 중앙선 개통 이라 86년의 세월동안 많은 것이 변하였는데 특히 청량리에서 부전까지 비둘기호가 반나절 넘게 달려야 완주하던 중앙선 철길은 직선화되면서 소요시간이 점점 줄어들었고 이제는 무궁화호를 타고 무려 6시간 남짓이면 될 정도로 소요시간이 무려 절반이나 줄었습니다. 심지어 전철화까지 완료되어 KTX-이음이 달리게 되면 시간을 이보다 더 줄어들 예정이니 말 그대로 격세지감이라는 어르신들의 말의 의미가 이런 경우에 쓰임을 깨닫습니다.
2005년 청량리-덕소 구간 복선화 및 직선화를 시작으로 양평, 원주, 제천, 단양, 영주, 안동, 의성까지 차례차례 진행되었고 어느덧 이러한 변화는 의성-북영천 구간을 제외한 전 구간이 완공되었습니다. 이러한 변화를 아는지 모르는지 내년부로 더이상 열차가 다니지 않게될 화본역은 오늘도 무궁화호를 타고 찾아온 승객들을 맞이하고 있었습니다.
아화역에서 무궁화호를 타고 화본역에 도착하였습니다.
전역과 다음역인 두 역은 여객 영업을 하지 않고 있습니다.
내년 선로가 이설되면 두 역은 승객 없이 쓸쓸히 마지막 열차를 보내겠지요.
퇴역한 새마을호 객차가 역 인근에서 카페로 사용되고 있는 듯 합니다.
화본역에도 기관차가 다니던 시절 사용되었던 급수탑이 있습니다.
역 구내는 올해 마지막 영업하는 역 치고는 상당히 잘 관리되고 있습니다.
옛날 양식의 역명판도 그대로 재현해 두었군요.
이전에는 이 곳에서 강릉역에도 갈 수 있었지요?
어느덧 열차 문이 닫히고
열차는 청량리역을 향히 달려갑니다.
역사안으로 들어가봅니다.
역의 유명세 덕에 현대 양식이 아닌 옛모습으로 리모델링된 역사의 모습입니다.
승차권이 없는 방문객의 경우 기념권 성격의 입장권을 구매후 역무원의 안내에 따라 승강장에 입장할 수 있습니다.
열차는 하루에 총 6회 정차하네요.
그러고보니 저는 화본역 방문으로 군위는 처음 방문해보네요.
역광장은 상당히 넓습니다.
치즈냥 한 마리가 더운날 휴식을 취하고 있습니다.
군위군이 대구광역시에 편입됨에 따라 경상북도라고 적혀있어야 할 부분을 가렸네요.
무더웠던 2024년 7월말이었어서 열차카페에서 오미자에이드 한잔 샀습니다.
멀리서 바라본 화본역 역명판
삼국유사 군위를 형상화한 듯 한 캐릭터들일까요?
인근에 화본역에 대한 정보를 설명하는 비석이 보입니다.
한적한 시골 간이역 치고는 광장이 나름 넓습니다.
진입로에서 바라본 화본역
역세권에 무려 식당도 있습니다!
다음 열차가 들어오기 전 역앞 마을 구경을 잠시 하다가
아화역으로 돌아가기 위해 다시 승강장으로 들어옵니다.
요 역명판도 철도청 시절에 쓰던 것으로 보이는데?
역 주변 구경에 정신이 팔려있던 찰나에 벌써 열차가 들어옵니다.
새로운 철로로 이설되면 이 구간에서 디젤기관차를 볼 기회기 많지는 않겠죠?
잠시 짬을 내어 찾아온 간이역 여행을 마치고 다시 일상으로 돌아가봅니다!
'좌충우돌 여행기 > 국내여행' 카테고리의 다른 글
중앙선 이설전 마지막 풍경들 - 의성역~우보역 구간(2024.12.01) (0) | 2024.12.06 |
---|---|
중앙선 이설전 마지막 풍경들 - 북영천역~갑현역 구간(2024.11.22) (0) | 2024.11.23 |
뒤바뀐 운명 - 중앙선 건천역과 아화역(2024.07.27) (0) | 2024.07.28 |
추운 겨울 한적한 마을에 역이 다시 들어서다 - 경의선 운천역[2022.12.18] (0) | 2022.12.23 |
열차가 멈추지 않는 정원속 간이역 - 경전전 남평역[2022.06.01] (0) | 2022.06.14 |