본문으로 바로가기

라즈베리파이 같은 아이들은 가지고 놀면 놀수록 참 재미있습니다. 틈틈이 쉬는 시간에 이것저것 테스트하고 후다닥 코드 고민하고 또 글쓰고~~~ 요런게 스트레스 해소용으로 참 좋죠~^^ 그래서 최근 라즈베리파이에서 단순히 카메라를 연결해서 촬영(Capture)하는 흉내[바해로가기]도 한 번 해 보았습니다. 그리고 나서 영상 위에 글자를 올려보는 것도 해보았구요[바로가기]. 또 카메라랑 관계는 없지만, GPIO의 인터럽트 방식으로 사용도 해보았습니다.[바로가기] 이제 오늘은 정~~~말 허접하지만 카메라 흉내를 한 번 내볼까 합니다.^^ 일단, 회로 구성부터 보시죠~~

위와 같이 구성했습니다. 파란줄은 GPIO21번에 연결된 촬영버튼이구요... 그 다음 버튼은 20번에 연결된 화면에 날짜와 시간을 표시할지 말지 결정하는 버튼입니다. 그리고 마지막은 16번에 연결됭서 종료를 하는 버튼으로 사용할 겁니다.^^

실제로는 위 그림처럼 구성되구요~~

FRITZING에서 그린것과 색상은 좀 다르지만 위와 같이 구현합니다.

그리고... 필름 케이블의 구성때문에 카메라는 저렇게 뒤집혔구요(ㅠㅠ) 이 상태에서 이제 Python으로 짠 코드를 보죠~~~

 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. 
import picamera
import RPi.GPIO as GPIO
import datetime

camera = picamera.PiCamera()
isOverlayOn = True

GPIO.setmode(GPIO.BCM)
GPIO.setup(21, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(20, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(16, GPIO.IN, pull_up_down=GPIO.PUD_UP)

def cameraShot(channel):
    saveFileName = datetime.datetime.now().strftime('%y%m%d-%H%M%S%f')+'.jpg'
    camera.capture(saveFileName)
    print('Camera Shoot. File : ' + saveFileName)

def overlayToggle(channel):
    global isOverlayOn
    isOverlayOn = not isOverlayOn
    if isOverlayOn:
        print("Camera overlay mode is ON.")
    else:
        print("Camera overlay mode is OFF.")
     
GPIO.add_event_detect(21, GPIO.FALLING, callback=cameraShot, bouncetime=300)
GPIO.add_event_detect(20, GPIO.FALLING, callback=overlayToggle, bouncetime=300)

print("Start Camera App")

camera.resolution = (640,480)
camera.rotation = 180
camera.framerate = 24
camera.start_preview(fullscreen=False, window=(150,50,640,480))

while GPIO.input(16):
    dateString = datetime.datetime.now().strftime('%b %d %H:%M:%S')
    if isOverlayOn:
        camera.annotate_text = dateString
    else:
        camera.annotate_text = " "           

print("App Stop")

camera.stop_preview()
camera.close()
GPIO.cleanup()

일단 필요한 모듈은 당연히 picamera와 GPIO입니다. 그리고 날짜와 시간을 화면에 표시도 하고 저장하는 파일명으로 잡을려고 datetime도 필요하구요. 이전에 했던 인터럽트 글에서 없던 것이 26, 27행의 bouncetime인데요. 이건 푸쉬버튼을 누르면 파형이 노이즈처럼 튀는 경우가 많은데 인터럽트로 할떄 이걸 다 인식하게 되어서 여러번 이벤트를 실행할 수 있습니다. 하드웨어적으로 100nF정도의 캐패시터면 좋은데 없는 경우, 혹은 병행해서 bouncetime이라는 설정을 사용하면 어느 정도 해소가 됩니다. 그건 300ms정도이 시간의 간격을 두어서 그 안에 발생한 파형은 인지하지 않는거죠. 그리고 이벤트 호출 함수인 callback의 특성한 19번에서 global로 사용할 수 밖에 없었는데... 이부분은 혹시 지나가는 고수님들이 보시면 올바른 방향으로 코딩을 인도해 주시길 바랍니다.ㅠㅠ. 그리고 나면 이전에 이야기했던 내용을 적절히 버무려서 위 코드를 만든거죠^^

이제 처음 실행한 화면입니다. 날짜와 시간도 나오네요~~~ 그리고 두번째 버튼을 눌러서 저 글자가 나오는 걸 해제할 수 있습니다.

저렇게 말이죠~~~^^

저렇게 화면에 보면 저장하고 하는 모드가 실행됨을 알 수 있죠. 실제 촬영한 결과를 보면..

저렇게 잘 저장되어 있습니다.^^

날짜가 있을때 사진과

없을때 사진이죠^^ 에구... 카메라 가지고 놀기 기초... 완전 기초편 하나를 또 이렇게 올리네요~~~ ^^.


댓글을 달아 주세요

  1. 어릴때부터 프로그래밍 가르치면 뇌 발달에 좋을것 같아여.ㅎ
    제가 컴공이라서 그럴수두요.ㅋㅋㅋㅋ

  2. BlogIcon 핑구야 날자 2016.05.07 07:47 신고

    개발에 필요한 모듈이 있으니 도움이 되겠군요

  3. sms3300 2018.05.01 15:53

    카메라로 영상을 찍을때 위 글처럼 화면 일부분에서 영상이 보이는게아니라 영상이 화면 전체를 덮어버립니다.. 이럴때 어떠카나요?

    • BlogIcon PinkWink 2018.05.01 21:32 신고

      화면의 사이즈를 변경해보시지요...
      코드에보면 저는 680,480으로 되어 있거든요...
      그게 아니면 잘 모르겠습니다.ㅠㅠ

  4. 라즈베리 뉴비 2019.10.28 20:39

    안녕하세요! 이제 막 라즈베리를 시작하여 블로그에 올려주신 코드를 보면서 공부 중인 학생입니다.
    제가 올려주신 코드를 이용해서 20번 21번 버튼만을 사용해 오버레이 없이 사진 촬영 및 종료 기능만 만들어보려구 하였지만 막히는 부분이 있어 질문드립니다.
    저는 21번 버튼으로 사진 촬영을하고 20번 버튼으로 카메라 종료를 시키기 위해 오버레이 부분 코드를 지우고 36행 채널을 20번으로 바꿨습니다.
    이 떄 6행과 36행 if문을 유지하면 촬영 및 종료가 버튼으로 제어가 되는데
    6행과 if문을 지우면 촬영 기능이 작동하지 않고
    6행과 36~41행 while문 모두 지우면 사진이 한번만 촬영되고 여려장 촬영이 불가능해집니다.
    오버레이 관련 코드들이 없이 구현해보고 싶었는데 제가 아직 많이 부족해 이것저것 해봐도 해결방법을 못찾겠더군요..ㅠ
    혹시 방법을 알고 계신다면 도움 부탁드립니다.ㅠ

  5. 라즈베리공부중 2019.10.31 18:18

    혹시 왜 16번 버튼을 클릭하면 카메라가 종료되는지 코드를 설명해 주실수 있으신가요?
    36행 while문은 오버레이에 관한 코드 아닌가요?

    • BlogIcon PinkWink 2019.11.06 21:34 신고

      버튼이 눌러지기 전까지는 조건에 걸려서 대기하다가... 눌러지면 빠져나가기 때문입니다. 제가 그냥 한 번만 찍도록 만들었네요^^