1. 오렌지랑 사과 이미지 다운로드 받기
https://www.kaggle.com/datasets?search=apple+image+dataset
Find Open Datasets and Machine Learning Projects | Kaggle
Download Open Datasets on 1000s of Projects + Share Projects on One Platform. Explore Popular Topics Like Government, Sports, Medicine, Fintech, Food, More. Flexible Data Ingestion.
www.kaggle.com
2. 다운로드 받은 이미지로 로보플로우 인식
https://app.roboflow.com/kimyeonju/projects
Sign in to Roboflow
Even if you're not a machine learning expert, you can use Roboflow train a custom, state-of-the-art computer vision model on your own data.
app.roboflow.com
3. 딥러닝 학습시키기
(이전 블로그 참고)
4. 딥러닝 한 best 파일로 파이썬 코드 작성
import cv2
import torch
from ultralytics import YOLO
from collections import deque
from PIL import ImageFont, ImageDraw, Image
import numpy as np
import os # 경로 확인을 위해 추가
# =========================
# 설정
# =========================
# [수정] dy15_fruits -> day15_fruits (경로 오타 수정)
MODEL_PATH = r"C:\sundo\AIpython\AI\day15_fruits\datasets\runs\detect\orange_yolo8\weights\best.pt"
# 사과/오렌지 best.pt
CAM_INDEX = 0
CONF_THRESHOLD = 0.5 # conf는 낮게 (참고용)
HISTORY_SIZE = 10 # 최근 프레임 수
CONFIRM_COUNT = 3 # 3프레임 이상이면 확정
# =========================
# CUDA 확인
# =========================
# [수정] is_available() 줄바꿈 오타 수정
DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
print("[INFO] CUDA available:", torch.cuda.is_available())
if DEVICE == "cuda":
print("[INFO] GPU:", torch.cuda.get_device_name(0))
# =========================
# YOLO 모델 로드
# =========================
# [주석] 아래 경로에 파일이 없으면 FileNotFoundError가 발생합니다.
# 반드시 탐색기에서 해당 위치에 best.pt가 있는지 확인하세요.
if not os.path.exists(MODEL_PATH):
print(f"[ERROR] 모델 파일을 찾을 수 없습니다: {MODEL_PATH}")
exit()
model = YOLO(MODEL_PATH).to(DEVICE)
print("[INFO] YOLO model loaded on", DEVICE)
print("[INFO] model.names =", model.names) # {0:'apple', 1:'orange'}
# =========================
# 카메라 열기 (Windows)
# =========================
cap = cv2.VideoCapture(CAM_INDEX, cv2.CAP_DSHOW)
if not cap.isOpened():
print("[ERROR] 카메라를 열 수 없습니다.")
exit()
print("[OK] 카메라 연결 성공")
# =========================
# 한글 출력 준비 (PIL)
# =========================
FONT_PATH = "C:/Windows/Fonts/malgun.ttf"
# [주석] 폰트 파일이 없을 경우를 대비해 예외 처리가 필요할 수 있습니다.
try:
font = ImageFont.truetype(FONT_PATH, 40)
except:
font = ImageFont.load_default()
print("[WARN] 한글 폰트를 로드할 수 없어 기본 폰트를 사용합니다.")
def put_korean_text(img, text, pos, color=(255, 0, 0)):
"""OpenCV 이미지에 한글 출력"""
img_pil = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
draw = ImageDraw.Draw(img_pil)
draw.text(pos, text, font=font, fill=color)
return cv2.cvtColor(np.array(img_pil), cv2.COLOR_RGB2BGR)
# =========================
# 프레임 누적 버퍼
# =========================
history = deque(maxlen=HISTORY_SIZE)
# =========================
# 실시간 인식 루프
# =========================
while True:
ret, frame = cap.read()
if not ret:
print("[ERROR] 프레임 읽기 실패")
break
# YOLO 추론
results = model.predict(
frame,
conf=CONF_THRESHOLD,
device=DEVICE,
verbose=False
)
r0 = results[0]
# 이번 프레임 결과 초기화
best_conf = 0.0
current_label = None
if r0.boxes is not None:
for box in r0.boxes:
conf = float(box.conf[0])
cls_id = int(box.cls[0])
label = model.names.get(cls_id, "unknown")
# 가장 높은 conf 하나 선택
if conf > best_conf:
best_conf = conf
current_label = label
# 바운딩 박스 표시
x1, y1, x2, y2 = map(int, box.xyxy[0])
cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(
frame,
f"{label} {conf:.2f}",
(x1, y1 - 10),
cv2.FONT_HERSHEY_SIMPLEX,
0.7,
(0, 255, 0),
2
)
# 프레임 누적 기록
if current_label in ["apple", "orange"]:
history.append(current_label)
# =========================
# 최종 판단 (프레임 누적)
# =========================
final_result = "몰라"
if history.count("apple") >= CONFIRM_COUNT:
final_result = "사과"
elif history.count("orange") >= CONFIRM_COUNT:
final_result = "오렌지"
# =========================
# 결과 한글 출력
# =========================
frame = put_korean_text(
frame,
f"결과: {final_result} (conf={best_conf:.2f})",
(20, 20),
color=(255, 0, 0)
)
cv2.imshow("Fruit AI (CUDA)", frame)
# ESC 종료
if cv2.waitKey(1) & 0xFF == 27:
break
# =========================
# 종료 처리
# =========================
cap.release()
cv2.destroyAllWindows()
2. 결과

'AI딥러닝' 카테고리의 다른 글
| 딥러닝 모델을 재사용하되 스프링부트에서 스트리밍할것 (0) | 2026.02.12 |
|---|---|
| AI딥러닝로보플로우로 함께하는 Trash_tree 욜로 2탄(설명추가)!! (0) | 2026.02.09 |
| 로보플로우로 함께하는 Car_DeepLearning 욜로~ (0) | 2026.02.09 |
| Mnist 숫자 인식하기 (0) | 2026.02.09 |
| 아리리스(붓꽃) 자바스프링부트와 연동가능한 파이썬 코드 (0) | 2026.02.03 |