import os
file_size = os.path.getsize("test.txt")
file_size_mb = file_size / 1024 # KB 단위
file_size_kb = file_size_mb / 1024 # MB 단위
'Language > Python' 카테고리의 다른 글
[Python] OpenCV, UDP를 이용해 Webcam 영상 데이터를 서버로 보내기 (3) | 2019.07.29 |
---|
import os
file_size = os.path.getsize("test.txt")
file_size_mb = file_size / 1024 # KB 단위
file_size_kb = file_size_mb / 1024 # MB 단위
[Python] OpenCV, UDP를 이용해 Webcam 영상 데이터를 서버로 보내기 (3) | 2019.07.29 |
---|
진행하고 있는 프로젝트 중에 Webcam 영상 데이터를 서버로 보낼 필요가 있어 자료를 조사하기 시작했다.
그리고 자료를 조사하던 중 아래 사이트에서 Webcam 영상 데이터를 OpenCV를 이용해 보낼 수 있는 코드를 발견했다.
https://stackoverflow.com/questions/46912475/python-webcam-stream-over-udp-socket?rq=1
해당 코드는 Python2를 기준으로 작성되어있어서 Python3에서 사용할 수 있게 조금 코드를 변경했다. 아래는 변경한 코드이다.
import socket |
import socket |
※ 참고로 위의 코드에서 46080이 자주 나오는데 이것이 의미하는 바는 다음과 같다.
Client의 Webcam에서 생성하는 각 프레임은 640x480 RGB 픽셀을 가지는데 이것의 실제 데이터 크기는 640 x 480 x 3 = 921,600 Byte이다. 이 때 3은 RGB 즉, 빨강, 초록, 파랑을 나타내기 위해 사용하는 것이다.
그런데 UDP는 한번에 데이터를 65,535 Byte 까지 보낼 수 있어 위의 921,600 Byte를 한 번에 보낼 수 없다. 그래서 데이터를 나눠서 보내야하는데 해당 코드에서는 921,600 Byte를 20으로 나눈 46,080 Byte를 보내주고 있다.
그래서 46080이 코드에서 계속 나오는 것이다.
그래서 만약 OpenCV에서 생성하는 프레임이 다르다면 그에 맞게 고쳐주면 된다. |
실행해보면 실행은 되나 영상이 조금씩 내려가는 현상을 볼 수 있는데 원인은 UDP 프로토콜의 특성 때문이다. 서버로 가는 데이터 중 일부를 못 받아도 그냥 무시하고 데이터의 순서가 잘못되어있더라도 데이터를 받는 순서대로 이미지를 생성하기 떄문이다.
그래서 이를 해결하기 위해 코드를 다음과 같이 수정했다.
import socket
if cv2.waitKey(1) & 0xFF == ord('q'): |
import socket import numpy import cv2 UDP_IP = "127.0.0.1" UDP_PORT = 9505 sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.bind((UDP_IP, UDP_PORT)) s = [b'\xff' * 46080 for x in range(20)] fourcc = cv2.VideoWriter_fourcc(*'DIVX') out = cv2.VideoWriter('output.avi', fourcc, 25.0, (640, 480)) while True: picture = b'' data, addr = sock.recvfrom(46081) s[data[0]] = data[1:46081] if data[0] == 19: for i in range(20): picture += s[i] frame = numpy.fromstring(picture, dtype=numpy.uint8) frame = frame.reshape(480, 640, 3) cv2.imshow("frame", frame) out.write(frame) if cv2.waitKey(1) & 0xFF == ord('q'): cv2.destroyAllWindows() break |
코드를 보면 Client에서 데이터를 보낼 때 앞의 1 Byte에 0 ~ 19까지의 숫자를 포함시켜 보냈는데 이는 Server에게 해당 데이터가 프레임의 어디 부분의 데이터인지 알려주기 위해서이다.
그리고 Server에서는 크기가 20인 프레임에 대한 리스트를 만들어 Client에게서 데이터를 받으면 앞의 1 Byte를 읽어 s[data[0]] = data[1:46081]와 같이 리스트의 해당 위치에 앞의 1 Byte를 제외한 나머지 데이터를 할당한다.
그리고 앞의 1 Byte가 19 즉, 프레임의 마지막 데이터이면 리스트의 데이터들을 전부 합쳐 이미지로 보여주게 했다.
그리고 이번에는 서버에서 보여지는 영상이 서버에 저장될 수 있도록 VideoWriter 함수를 사용해서 Server에 대한 코드가 있는 곳에 output.avi라는 파일로 저장하게 하였다.
실제 실행시켜보면 이전의 코드에서 발생한 영상이 조금씩 내려가는 현상이 사라진 것을 볼 수 있다.
[Python] 파일 크기 구하기 (0) | 2019.09.25 |
---|