라즈베리파이와 파이썬을 이용한 소켓 통신을 만들고 있는데 막히는 부분이 있습니다.

조회수 2068회

라즈베리에서 버튼으로 사진을 찍으면 바로 서버로 전송하는 소켓통신을 만들려고 합니다.

아직 초보라 여기저기 검색하여 얻은 정보로 다음 코드를 작성하였습니다.

사진 촬영과 카메라 종료는 작동하지만 사진 촬영 후 바로 전송에서 막힙니다.

그래서 transfer 함수 호출 위치를 계속 바꿔보고 있지만 해결이 되지 않아 질문드립니다

아래 코드는 클라이언트 코드이며 실행 시 전송에 필요한 사진이 디렉터리에 저장되있지 않다고 나오는데 순서를 어떻게 바꿔야 할지 모르겠습니다.

혹시 코드에 다른 문제점도 지적해주시면 감사하겠습니다.

# TCP client
#-*-coding: utf-8-*-

#-*-coding: euc-kr-*-


import socket
import sys
import os
import time
import picamera
import RPi.GPIO as GPIO
import datetime



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)

def fileName():
    dte = time.localtime()
    Year = dte.tm_year
    Mon = dte.tm_mon
    Day = dte.tm_mday
    WDay = dte.tm_wday
    Hour = dte.tm_hour
    Min = dte.tm_min
    Sec = dte.tm_sec
    imgFileName = str(Year) + '_' + str(Mon) + '_' + str(Day) + '_' + str(Hour) + '_' + str(Min) + '_' + str(
        Sec) + '.jpg';
    return imgFileName

print("Start Camera App")

# Server File Path
src = "C:\\Users\\HJ_2\\Desktop\\programming\\save\\";


def transfer(filename):
    capture_file_name = "/home/pi/Desktop/picture/" + str(saveFileName) + ".jpg"

    # 3 Send File

    # Import img  (path/name)
    file = open(capture_file_name, "rb")
    img_size = os.path.getsize(capture_file_name)
    img = file.read(img_size)  # saved image
    file.close()

    # connect server
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect(("192.168.0.6", 5001))

    # image tramsfer
    client_socket.sendall(img)

    # Terminate connection with server
    client_socket.close()
    print("Finish SendAll")

with picamera.PiCamera() as camera:
    camera.resolution = (640,480)
    camera.rotation = 0
    camera.framerate = 24
    camera.start_preview(fullscreen=False, window=(150,50,640,480))
    frame = 1
    while True:
        GPIO.wait_for_edge(21, GPIO.FALLING)
        saveFileName = fileName()
        camera.capture('/home/pi/Desktop/picture/' + saveFileName + '_%03d.jpg' %frame)
        fileName_list = [saveFileName]
        if saveFileName in fileName_list:
            transfer(saveFileName)
            time.sleep(3)
        frame += 1

while GPIO.input(20):
    camera.annotate_text = ''

print("App Stop")

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

위 코드 실행 시 아래 메시지가 나옵니다.

Traceback (most recent call last):
File "last_2.py", line 76, in <module>
transfer(saveFileName)
File "last_2.py", line 48, in transfer
 file = open(capture_file_name, "rb")
IOError: [Errno 2] No such file or directory: '/home/pi/Desktop/picture/2019_10_29_17_6_44.jpg.jpg
  • (•́ ✖ •̀)
    알 수 없는 사용자

1 답변

  • 에러 메시지를 잘 읽어보세요.

    No such file or directory: '/home/pi/Desktop/picture/2019_10_29_17_6_44.jpg.jpg
    

    위 이름의 파일 또는 디렉토리가 없다고 합니다.

    이 파일이름은

    def transfer(filename):
        capture_file_name = "/home/pi/Desktop/picture/" + str(saveFileName) + ".jpg"
    
        # 3 Send File
    
        # Import img  (path/name)
        file = open(capture_file_name, "rb")
    

    위 코드의 capture_file_name 입니다. 이 파일명이 저장한 파일명과 다릅니다.

    저장할 때의 코드는

    camera.capture('/home/pi/Desktop/picture/' + saveFileName + '_%03d.jpg' %frame)
    
    

    차이가 있어 보입니다.


    다른 문제점 많이 있어 보이는데, 제일 위에 보이는 것만 말씀드리면,

    #-*-coding: utf-8-*-
    
    #-*-coding: euc-kr-*-
    

    이 중 위의 것은 소스파일이 utf-8 문자셋 인코딩으로 인코딩된 파일이라는 뜻입니다. 두번째는 소스파일이 euc-kr 로 인코딩 되었다는 뜻이고요. 두가지가 다 성립할 수 없습니다. 파이썬 3 버전에서는 이마져도 필요 없고, 그냥 맘편하게 utf-8 로 소스를 저장하면 됩니다. 문자전송과정에서 인코딩 문제 때문에 어디선가 잘못된 블로그의 글을 보고 집어넣었을 것 같은데, 아무 상관 없습니다. 전송할 때에는 문자를 원하는 인코딩을 정하고 명시적으로 s.encode('utf-8') 등으로 인코딩하여 바이너리를 얻은 후에 던져야 합니다.

    • 답변 감사합니다! 그런데 제가 아직 많이 부족해서 다시 질문드립니다..ㅠ 답변에서 해주신 말씀이 ```capture_file_name```을 '```camera.capture()```에서 저장 위치와 이름으로 바꾸는 것인지 아님 반대로 capture의 이름을 capture_file_name으로 바꾸는 것인지 이해가 되질 않습니다. 제가 코드 작성할 때 생각한 것은 while 문 아래 saveFileName = fileName() 에서 fileName 함수의 리턴값을 saveFileName에 할당하고 camera.capture()에서 saveFileName + 프레임 인 이름으로 이미지를 얻어 지정한 위치에 저장합니다. 이후 아래의 transfer 함수에서 saveFileName을 인자로 이용하여 capture_file_name에 이를 할당하여 이용하는 것이었습니다. 혹시 제가 잘못 알고 있는것인가요? 알 수 없는 사용자 2019.10.30 13:53
    • 글쎄, 말로 설명할 단계는 아닌 것 같고요. 직접 저장할 때의 파일명 찍어보시고, 읽을 때의 파일명 찍어보시고, 파일 저장되었는지 확인해 보시고, 하면서 디버깅 해 보세요. 개발환경이 괜찮으면, 디버깅모드로 한줄씩 한스텝씩 진행하면서 확인해 보세요. 디버깅모드로 한번만 진행해 보면 틀린 부분 금방 찾을 거에요. nowp 2019.10.30 15:06
    • 감사합니다! 답변 덕분에 에러는 해결되었습니다. 이제 전송까지 작동하지만 20번 버튼 클릭시 카메라 종료가 작동하질 않습니다. 혹시 이 문제에 대해 코드 중 수정해야 할 부분이 있을까요? 코드는 위 코드에서 파일 이름관련 부분을 제외한 나머지는 변경이 없습니다 알 수 없는 사용자 2019.10.31 18:47
    • 다른 문제는 문제 부분을 잘 정리해서 다시 질문을 올리세요. 질문을 정리하는 과정에서 스스로 문제가 풀릴 수도 있어요. nowp 2019.10.31 20:47

답변을 하려면 로그인이 필요합니다.

프로그래머스 커뮤니티는 개발자들을 위한 Q&A 서비스입니다. 로그인해야 답변을 작성하실 수 있습니다.

(ಠ_ಠ)
(ಠ‿ಠ)