본문 바로가기
기술팁/라즈베리파이(raspberry)

라즈베리파이 카메라 성능, motion 사용, 파이썬 소스

by nyg -i 2019. 11. 20.

혹시 Picamera 를 설치 하지 않았다면, 설치

  • sudo apt-get update
  • sudo apt-get upgrade
  • sudo apt-get install python-picamera

 참고로 파이 카메라의 framerate를 30으로 설정한다하더라도, 라즈베리파이의 VNC환경이나 다른 부하가 많은 상태라면 320*240 해상도 에서도 30fs가 나오지 않는다.  1920*1080에서 2fs 정도 되는듯 하다. 스틸사진 찍는수준 ㅠㅠ

 스트리밍이라면 모를까 , 라즈베리파이에 아무런 연결없고 부하없이 부팅후 바로 motion녹화만 해보았다. 

720해상도까지에서는 녹화된 영상이 볼만하다. 하지만 1920*1080에서의 녹화영상은 움직임의 흐림효과?와 함께 타임랩스 사진 처럼 녹화되어있다. 따라서 opencv등 영상처리를위해서는 320해상도로 한다해도 제대로 처리하기는 버거울 것 같다.

GPIO 버튼 누르면 스틸사진 촬영 저장, 동영상 촬영저장

 

import time

import picamera

import RPi.GPIO as GPIO # new

GPIO.setmode(GPIO.BCM) # new

GPIO.setup(17, GPIO.IN, GPIO.PUD_UP) # new

with picamera.PiCamera() as camera:

   camera.resolution = (1920, 1080)   #해상도

   camera.framerate = 30  #30Fs

   camera.start_preview()

   camera.annotate_text = "HELLO APPLE"  #텍스트 추가,  .annotate_text_size =50:텍스트사이즈

   GPIO.wait_for_edge(17, GPIO.FALLING) # new 버튼 입력전 대기

   time.sleep(5) # new 버튼 누른뒤 5초후

   camera.capture('/home/pi/Desktop/image.jpg')  #사진찍고 저장

   camera.stop_preview()

    time.sleep(5) #  5초후

    camera.start_preview()   

    GPIO.wait_for_edge(17, GPIO.FALLING)   #버튼입력 대기

    camera.start_recording('/home/pi/Desktop/video.h264')   # 동영상 촬영 저장 시작

    time.sleep(1)

    GPIO.wait_for_edge(17, GPIO.FALLING)   #버튼 입력 대기

    camera.stop_recording() camera.stop_preview()  #저장 종료

    camera.stop_preview()

 만약 실행시 에러가 뜬다면, 카메라를 다른 곳(motion 등)에서 쓰고 있는지 확인 후 motion이 사용중이라면 off 해야함. 

마지막 N 초의 영상만 저장

Circular buffer 를 이용해서 마지막 n 초 간의 영상만 저장하도록 하는 예제입니다.

picamera.PiCameraCircularIO() 함수를 이용해서 버퍼에 영상을 계속 써둡니다. 촬영 종료를 알리는 버튼이 감지되면 버퍼에 있는 스트림을 파일로 저장하는 방식입니다.

import io

import time

import picamera

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

with picamera.PiCamera() as camera:

      stream = picamera.PiCameraCircularIO(camera, seconds=20)

      camera.start_preview()

      camera.start_recording(stream, format='h264')

      GPIO.wait_for_edge(17, GPIO.FALLING)

      camera.stop_recording()

      camera.stop_preview()

      for frame in stream.frames:

            if frame.header:

                  stream.seek(frame.position)

                  break

      with io.open('/home/pi/Desktop/video.h264', 'wb') as output:

            while True:

                  data = stream.read1()

                 if not data:

                         break

                  output.write(data)

기존에 생성된 비디오 파일을 삭제하고 스크립트를 실행해서 확인해보세요.

 

일정간격(TIME-LAPSE) 촬영

촬영을 하고 일정 시간만큼 sleep() 을 한 뒤 다시 촬영하는 패턴입니다. 이걸 몇 일 동안 반복하도록 놔두면 Time-Lapse 영상이 가능합니다.

import time

import picamera

VIDEO_DAYS = 5

FRAMES_PER_HOUR = 1

FRAMES = FRAMES_PER_HOUR * 24 * VIDEO_DAYS

def capture_frame(frame):

     with picamera.PiCamera() as cam:

          time.sleep(2)

          cam.capture('/home/pi/Desktop/frame%03d.jpg' % frame)

# Capture the images

for frame in range(FRAMES):

     # Note the time before the capture

     start = time.time()

     capture_frame(frame)

     # Wait for the next capture. Note that we take into

     # account the length of time it took to capture the

     # image when calculating the delay

     time.sleep(     int(60 * 60 / FRAMES_PER_HOUR) - (time.time() - start)    )

 

이미지로부터 Video 파일을 생성하기 위해서는 FFMPEG 패키지가 필요합니다.

  • sudo apt-get install ffmpeg

설치가 끝나면 아래 경로와 파일 설정이 자신에게 맞는지 확인하고 실행합니다.

  • ffmpeg -y -f image2 -i /home/pi/Desktop/frame%03d.jpg -r 24 -vcodec libx264 -profile high -preset slow /home/pi/Desktop/timelapse.mp4

스톱 모션 촬영

여기까지 보셨다면 이건 쉽겠죠. 버튼 입력을 대기하고 있다가 버튼 눌러지면 촬영하는 패턴을 무한반복 시키면 됩니다.

import picamera

import RPi.GPIO as GPIO

GPIO.setmode(GPIO.BCM)

GPIO.setup(17, GPIO.IN, GPIO.PUD_UP)

with picamera.PiCamera() as camera:

          camera.start_preview()

          frame = 1

          while True:

                    GPIO.wait_for_edge(17, GPIO.FALLING)

                    camera.capture('/home/pi/Desktop/frame%03d.jpg' % frame)

                    frame += 1

          camera.stop_preview()

마찬가지로 영상으로 만들 때는

  • ffmpeg -y -f image2 -i /home/pi/Desktop/frame%03d.jpg -r 24 -vcodec libx264 -profile high -preset slow /home/pi/Desktop/stop_motion.mp4

보안 촬영

가장 복잡한 예제. 영상에 움직임이 발견되면 마지막 10초 영상을 기록하는 예제입니다.

마지막 n 초의 영상을 기록하는 예제에 모션을 감지하는 루틴이 추가되면 됩니다. 친절하게도 소스코드 저자가 모션 감지하는 부분은 직접 해보라고 비워뒀네요.

 

import io

import random

import picamera

from PIL import Image

prior_image = None

     def detect_motion(camera):

    global prior_image

    stream = io.BytesIO()

    camera.capture(stream, format='jpeg', use_video_port=True)

    stream.seek(0)

    if prior_image is None:

        prior_image = Image.open(stream)

        return False

    else:

        current_image = Image.open(stream)

        # Compare current_image to prior_image to detect motion. This is

        # left as an exercise for the reader!

        result = random.randint(0, 10) == 0

       # Once motion detection is done, make the prior image the current

       prior_image = current_image

       return result

def write_video(stream):

    # Write the entire content of the circular buffer to disk. No need to

    # lock the stream here as we're definitely not writing to it

    # simultaneously

    with io.open('before.h264', 'wb') as output:

        for frame in stream.frames:

           if frame.header:

                stream.seek(frame.position)

               break

       while True:

           buf = stream.read1()

           if not buf:

               break

           output.write(buf)

    # Wipe the circular stream once we're done

    stream.seek(0)

    stream.truncate()

with picamera.PiCamera() as camera:

    camera.resolution = (1280, 720)

    stream = picamera.PiCameraCircularIO(camera, seconds=10)

    camera.start_recording(stream, format='h264')

    try:

        while True:

                camera.wait_recording(1)

                if detect_motion(camera):

                        print('Motion detected!')

                        # As soon as we detect motion, split the recording to

                        # record the frames "after" motion

                       camera.split_recording('after.h264')

                        # Write the 10 seconds "before" motion to disk as well

                       write_video(stream)

                       # Wait until motion is no longer detected, then split

                        # recording back to the in-memory circular buffer

                        while detect_motion(camera):

                       camera.wait_recording(1)

                        print('Motion stopped!')

                        camera.split_recording(stream)

  finally:

        camera.stop_recording()

 

모션을 감지하는 부분 - detect_motion() 은 직접 채워넣어야 제대로 동작합니다.

 

모션 설치 사용하기>https://itworldexplorer.blogspot.com/2018/06/blog-post_11.html

출처>http://www.hardcopyworld.com/gnuboard5/bbs/board.php?bo_table=lecture_rpi&wr_id=11

 

파이카메라(PiCamera) 파이썬으로 제어하기 > Raspberry Pi | HardCopyWorld

파이카메라(PiCamera) 파이썬으로 제어하기 > Raspberry Pi | HardCopyWorld

www.hardcopyworld.com

https://learn.adafruit.com/diy-wifi-raspberry-pi-touch-cam/overview

참고자료 :