일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- TFT Touch
- ubuntu
- 양자역학
- Raspberry Pi
- 30pin
- 우분투
- wxWidgets
- 카카오맵
- 카카오맵GPX
- 리차드 도킨스
- 반스앤노블
- nook
- 우주론
- 크롬
- Waveshare
- nook HD
- 리눅스
- nook HD+
- 라즈베리파이
- 뉴스포티지
- micro usb
- 연료필터 카트리지
- 파인만
- jessie
- CyanogenMod
- GUI Programming
- 이기적인 유전자
- Cross-platform
- 이 FTP 사이트는 Windows 탐색기에서 볼 수 없습니다
- C++
- Today
- Total
언덕에 누워 생각하기
(개선)2025 설악그란폰도 사진 찾기 위한 여정(파이썬,AI,ChatGPT) 본문
순서
사진(썸네일) 다운로드 - 헬멧 학습 시키기 - 헬멧 찾은 뒤 파란색인지 확인 - 파란색 헬멧 중 파란 옷 입었는지 확인 - 사람이 확인 후 원본 사진 다운로드 - 배번호 지정
설악그란폰도는 참가 인원도 엄청나서 사진을 모두 찾기란 많이 힘들다.
거의 포기 상태였다가 명색이 그래도 컴퓨터로 먹고 사는 사람인지라 컴퓨터의 힘을 빌리기로 했다.
프로그래밍을 안한지 엄청 오래되었고, 그마저도 C++이 주특기였기에 파이썬은 익숙하지가 않다.
그렇다면? ChatGPT에게 물어보면... ㅎㅎ
1. 사진 다운로드 받기
- 공식 사이트? - 기록 보는 사이트
우선 사진을 다운로드 받아야 한다. 그래야 더 빠르다. 당연. 다른 곳은 그냥 다운로드 받을 수 있는데, 공식 홈페이지는 좀 다르다. 엄청나게 많은 파일을 페이지별로 넘어가며 찾아서 다운로드 해야 한다. 미쳤어... 총 61,281장의 사진이 있다. 페이지 몇 개와 사진 몇 개를 보니 주소가 이렇다.
https://photo2.spct.kr/2025/2025051702
페이지의 썸네일은 https://photo2.spct.kr/2025/2025051702Thumb 이다.
https://photo2.spct.kr/2025/2025051702 에서 사진을 모두 다운로드 받으면 된다. --> Thumb에서 다운로드 받는 것으로 수정. 그래야 훨씬 더 빠르다.
ChatGPT에게 물어봤다.
BeautifulSoup으로 파싱해서 이미지 링크를 알아내고 다운로드 받는 코드를 알려줬다. 당연하지.
파이썬 소스가 실행되는 디렉토리에서 spct 폴더를 만들고 거기에 다운로드 받는다.
무지 막지 느리다. 하루 이상 걸림.Thumb에서 받으니 많이 빨라짐. 그나마 멀티쓰레드이고 다운로드 실패하면 재시도 한다.
- 공식 사이트2(flickr)
설악그란폰도 홈페이지에 있는 공식 플리커. 플리커는 동적으로 생성되기 때문에 까다롭다. 스크롤을 내려야 그 때 사진 보이고 링크가 동적으로 생성된다. 각 페이지당 100장씩 사진이 있다. 많네...
결국 해결. 단, 크롬드라이버 있어야 함.
flickr_originals 폴더에 사진 저장. 그런데 재미있는거 발견. 동적으로 생성된 html 원본을 보니 이런 주석이 있다.
나도 채용 신청을???
<!-- _
. - ` : ` '.' `` . - '` ` .
' ,gi$@$q pggq pggq . ' pggq
+ j@@@P*\7 @@@@ @@@@ _ : @@@@ ! ._ , . _ - .
. . @@@K @@@@ ; -` `_,_ ` . @@@@ ;/ ` _,,_ `
; pgg@@@@gggq @@@@ @@@@ .' ,iS@@@@@Si @@@@ .6@@@P' !!!! j!!!!7 ;
@@@@@@@@@@@ @@@@ @@@@ ` j@@@P*"*+Y7 @@@@ .6@@@P !!!!47*"*+;
`_ @@@@ @@@@ @@@@ .@@@7 . ` @@@@.6@@@P ` !!!!; . '
. @@@@ ' @@@@ @@@@ :@@@! !: @@@@7@@@K `; !!!! ' ` '
@@@@ . @@@@ @@@@ `%@@@. . @@@@`7@@@b . !!!! :
! @@@@ @@@@ @@@@ \@@@$+,,+4b @@@@ `7@@@b !!!!
@@@@ : @@@@ @@@@ `7%S@@hX!P' @@@@ `7@@@b !!!! .
: """" """" """" :. `^"^` """" `""""" ''''
` - . . _._ ` _._ _ . -
, ` ,glllllllllg, `-: ' .~ . . . ~. `
,jlllllllllllllllp, .!' .+. . . . . . .+. `.
` jllllllllllllllllllll ` +. . . . . . . . .+ .
. jllllllllllllllllllllll . . . . . . . . . . .
.l@@@@@@@lllllllllllllll. j. . . . . . . :::::::l `
; ;@@@@@@@@@@@@@@@@@@@lllll :. . :::::::::::::::::: ;
:l@@@@@@@@@@@@@@@@@@@@@l; ::::::::::::::::::::::;
` Y@@@@@@@@@@@@@@@@@@@@@P ::::::::::::::::::::: '
- Y@@@@@@@@@@@@@@@@@@@P . ::::::::::::::::::: .
`*@@@@@@@@@@@@@@@*` ` ` `:::::::::::::::`
`. `*%@@@@@@@%*` . ` `+:::::::::+` '
. ``` _ ' - . ``` -
` ' ` ' `
You're reading. We're hiring.
https://flickr.com/jobs/
-->
2. AI님에게 헬멧 찾기 학습
이제 그 많은 사진에서 내 사진을 찾아야 한다. 나는 헬멧을 파란색으로 썼다. 많이 쓰지 않는 색이다. ㅇㅋ. 이걸 찾아야 한다. AI에게 헬멧을 찾도록 한 뒤, 그 헬멧이 파란색인지 확인해야 한다. AI 모델을 찾았는데, 없네. roboflow에서 보니 한국사람 같은데, 헬멧 사진을 무려 5001장이나 올리고 어노테이션 해주셨다. 만세!
검색어: bicycle helmet
Author: Sunjune Kim
1년 전에 해주셔서 덕분에 잘 썼어요!
데이터셋을 다운로드 받아서 학습시켜야 한다. 내가 쓰는 컴퓨터는 GPU도 없다. CPU로 하니 Epoch을 50으로 했을 때, 도저히 답이 안나온다. 이럴 땐??? 구글 Colab에서 GPU로 학습시켜보니 세상에... 엄청 빠르다.
학습시키는 코드
# 설치
!pip install ultralytics roboflow
# roboflow 데이터 다운로드
from roboflow import Roboflow
rf = Roboflow(api_key="-------------") # ✅ 너의 API 키
project = rf.workspace("sunjune-kim").project("bicycle-helmet-2azcz")
dataset = project.version(1).download("yolov8") # YOLOv8 포맷 다운로드
# 다운로드된 경로 확인
print("DATA PATH:", dataset.location)
# YOLOv8 모델 학습
from ultralytics import YOLO
model = YOLO("yolov8n.pt") # 사전학습된 작은 모델 사용
# 정확한 경로 사용
model.train(data=f"{dataset.location}/data.yaml", epochs=50, imgsz=640)
# 학습된 모델 다운로드
from google.colab import files
files.download('runs/detect/train/weights/best.pt')
이제 best.pt라는 파일로 모델을 다운로드 했다. 헷갈리니
bicycle-helmet.pt 라는 이름으로 바꿔줬다. 넌 춘식이여... 아니 넌 자전거 헬멧 찾기 모델이여.
3. 이제 파란 헬멧을 찾아줘!
파일이 너무 많아서 모두 다운 받으면서 찾으려면 쉬운 방법이... 대충 10,000개 쯤 폴더에 넣고 찾은 것만 따로 빼 놓는게 좋겠다. 폴더 구조는 아래와 같다. 현재 폴더에는 파란헬멧 찾을 파이썬 소스와 모델(bicycle-helmet.pt)을 넣는다.
현재폴더 --spct---- Verifying
+--Verified
+--BlueHelmet
파란 헬멧을 찾을 사진들만 Verifying에 넣는다. 모든 사진을 넣어도 되겠지만, 사진 다운로드 받는데 엄청난 시간이 들어서 그럴 수 없다. 우선 다운로드 받은 것만 찾으려면 Verifying에 넣어야만 한다. 그리고, 검사가 끝난 파일은 찾았든 못 찾았든 모두 Verified로 옮겨진다. 파란 헬멧을 찾은 사진만 BlueHelmet에 복사한다.
파란 헬멧을 찾는 파이썬 소스
우와... 파란 헬멧이 무척 많다. 아... 많다. 그래서, 나는 파란색 옷을 입었으니 파란헬멧 사진 중에서 파란 옷을 찾는 것을 추가했다.
결국.... 찾았다.... 내 사진....
이제 썸네일 사진을 찾았으니 원본 파일을 다운로드 받아야 한다.
GUI로 되어 있다. 썸네일 사진을 드래그&드랍하면 원본을 다운로드 받을 수 있다.
소스코드
한 가지 문제가 더 있는데... 나처럼 배번호가 일부 가려지면 사진기록증에 사진이 안들어간다. 또한, 배번호(BibNo)로 사진을 찾을 수 없다. 찾은 사진들에게 배번호를 등록하는 파이썬. GUI이다. 배번호를 입력하고 사진들을 드래그&드랍한 뒤 "배번호 전송" 버튼을 누르면 된다.
소스코드
CUI 버전... 기록 때문에 남김... 코드 수정해 가면서 실행시켜야 함.
import requests
# 요청 보낼 URL
url = "https://time.spct.kr/PhotoBibUpdate.php"
# 입력할 값
bib_number = "0000" # 배번호 입력... 숫자로...
filename = "----.JPG" # 사진파일 이름 입력...
# 폼 데이터 구성
form_data = {
"EVENT_NO": "2025051702",
"TargetYear": "2025",
"photosection": "8",
"currentPage": "1",
"PhotoCurrentPage": "1",
"photofilename": filename,
"NewBIB_NO": bib_number
}
# 기본 헤더 (크롤링 방지 우회 목적)
headers = {
"User-Agent": "Mozilla/5.0",
"Referer": "https://time.spct.kr/photos.php",
}
# POST 요청
response = requests.post(url, data=form_data, headers=headers)
# 결과 확인
if response.status_code == 200:
html = response.text
# 응답에 BIB 번호 또는 성공 관련 키워드가 포함되었는지 확인
if bib_number in html or "성공" in html or "등록" in html:
print(f"✅ 배번 {bib_number} 등록 성공!")
elif "배번을 넣어 주세요" in html or "실패" in html:
print(f"❌ 배번 등록 실패 (입력 오류 또는 서버 거부)")
else:
print("⚠️ 등록 결과가 명확하지 않음 (응답 HTML 일부 미리보기):")
print(html[:500])
else:
print(f"❌ 요청 실패: HTTP 상태 코드 {response.status_code}")
끝.