프로젝트 소개
프로젝트 배경 및 목적
왜 쓰레기 분류가 중요한지 설명
(1) 자원 절약
(2) 환경 오염 감소
(3) 온실가스 배출 감소

이 시스템을 통해 해결하자고 하는 문제
(1) 사람들이 분리수거를 할 때, 재활용 방법을 잘 몰라서 안하는 경우가 존재


(2) 또한 본인에게 직접적으로 돌아오는게 없어서 안함
(3) 이러한 문제를 자동 분리수거를 이용하여 해결
시스템 설계
알고리즘 및 코드
시스템 주요 알고리즘
초음파 센서를 이용한 물체 감지
(알고리즘 단순하게 정리)
cv를 통한 물체 분류
서보 모터를 이용한 쓰레기 분류 동작
코드 흐름 설명
주요 함수 및 모듈에 대한 간단한 설명
(1) 초음파 센서 함수
def get_distance(pin):
try:
distance = grovepi.ultrasonicRead(pin)
return distance
except TypeError:
print("초음파 센서가 작동되지 않음")
return None
(2) DC 모터 함수
# DC 모터 제어 함수
def operate_dc_motor(speed, state):
if state == 1:
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
pwm1.ChangeDutyCycle(speed)
GPIO.output(IN3, GPIO.HIGH)
GPIO.output(IN4, GPIO.LOW)
pwm2.ChangeDutyCycle(speed)
else:
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
pwm1.ChangeDutyCycle(0)
GPIO.output(IN3, GPIO.LOW)
GPIO.output(IN4, GPIO.LOW)
pwm2.ChangeDutyCycle(0)
(3) 서보 모터 함수
def move_servo(result):
if result == 'Paper':
grovepi.servoWrite(SERVO_PIN1, 30)
grovepi.servoWrite(SERVO_PIN2, 120)
elif result == 'Plastic':
grovepi.servoWrite(SERVO_PIN1, 60)
grovepi.servoWrite(SERVO_PIN2, 90)
elif result == 'PET':
grovepi.servoWrite(SERVO_PIN1, 90)
grovepi.servoWrite(SERVO_PIN2, 60)
elif result == 'Glass':
grovepi.servoWrite(SERVO_PIN1, 120)
grovepi.servoWrite(SERVO_PIN2, 30)
time.sleep(1)
(4) 쓰레기 분류
# 쓰레기 분류 함수
def classify_waste(input_image):
input_hist = cv2.calcHist([input_image], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
cv2.normalize(input_hist, input_hist, 0, 1, cv2.NORM_MINMAX)
best_match = None
highest_score = -1
for label, ref_image in reference_images.items():
ref_hist = cv2.calcHist([ref_image], [0, 1, 2], None, [8, 8, 8], [0, 256, 0, 256, 0, 256])
cv2.normalize(ref_hist, ref_hist, 0, 1, cv2.NORM_MINMAX)
score = cv2.compareHist(input_hist, ref_hist, cv2.HISTCMP_CORREL)
if score > highest_score:
highest_score = score
best_match = label
return best_match
(5) lcd 함수
# I2C LCD 관련 설정
I2C_ADDR = 0x27
LCD_WIDTH = 16
LCD_CHR = 1
LCD_CMD = 0
LCD_LINE_1 = 0x80
LCD_LINE_2 = 0xC0
E_DELAY = 0.0005
# LCD 제어 함수
def lcd_byte(bits, mode):
bus.write_byte_data(I2C_ADDR, mode, bits)
time.sleep(E_DELAY)
def lcd_string(message, line):
message = message.ljust(LCD_WIDTH, " ")
for i in range(LCD_WIDTH):
lcd_byte(ord(message[i]), LCD_CHR)
def lcd_init():
lcd_byte(0x33, LCD_CMD)
lcd_byte(0x32, LCD_CMD)
lcd_byte(0x06, LCD_CMD)
lcd_byte(0x0C, LCD_CMD)
lcd_byte(0x28, LCD_CMD)
lcd_byte(0x01, LCD_CMD)
time.sleep(E_DELAY)
데이터 흐름
(1) try 안에 while 반복문 정의
try:
bus = smbus.SMBus(1)
lcd_init()
while True:
# 초음파 센서 1에서 물체 감지
if get_distance(ULTRASONIC_PIN_1) < 10:
operate_dc_motor(speed=50, state=1) # 모터 작동
time.sleep(3) # 이동 시간
# 초음파 센서 2에서 물체 감지
if get_distance(ULTRASONIC_PIN_2) < 10:
operate_dc_motor(speed=0, state=0) # 모터 정지
# 카메라로 이미지 캡처
camera = cv2.VideoCapture(0)
ret, frame = camera.read()
camera.release()
if ret:
# 쓰레기 분류
result = classify_waste(frame)
print(f"분류 결과: {result}")
lcd_string("Classified as:", LCD_LINE_1)
lcd_string(result, LCD_LINE_2)
# 서보 모터 동작
move_servo(result)
time.sleep(2)
except KeyboardInterrupt:
pwm1.stop()
pwm2.stop()
GPIO.cleanup()
print("프로그램 종료")
시스템 구현 과정
하드웨어 설치 및 조립
(1) 설계도
분류 모델 설명
(1) 모델 기본 설명
테스트 및 결과
실제 하드웨어 동작 과정 영상
딥러닝 분류 모델 동작 과정 영상
문제점 및 개선점
문제점
기존에 목표였던 라즈베리파이에, 모델 넣기 실패 이유
(1) 라즈베리파이2의 하드웨어 한계로 인해 tensorflow 설치 이슈
분류 한계
(1) 하드웨어적인 한계로 인해 너무 무겁거나 큰 물체는 분류하지 못함
(2) 사용자가 하나하나 쓰레기를 넣어야함
대안 및 개선점
cv 사용
셔틀과 배큠을 이용한 분류
(1) 영상
결론
(1) 목표 달성 여부
(2) 주요 성과
(1) 환경 보호
(2) 효율적인 쓰레기 관리
(3) 교육적 도구로 활용 가능
(4) 상업적 활용 가능성
(1) 제한된 분류 대상
Q&A