파이썬의 TCP 소켓을 사용하여 웹캠에서 캡쳐한 이미지를 전송하는 서버와 클라이언트를 간단히 만들었습니다.
웹캠으로부터 이미지 캡쳐는 OpenCV를 사용하였습니다.
서버에는 두 종류의 쓰레드를 생성합니다.
웹캠으로부터 캡처한 이미지를 큐에 삽입하는 쓰레드와 클라이언트가 접속하면 큐에서 이미지를 꺼내어 클라이언트에 전송하는 쓰레드입니다.
서버에서 이미지를 전송하기 전에 넘파이 배열을 압축한 후, 최종적으로 String으로 변환해야 하고
클라이언트에서는 수신된 String 데이터를 넘파이 배열로 변환하여 화면에 보여줍니다.
서버 프로그램을 실행 후, 웹캠 영상이 화면에 보여지면
클라이언트 프로그램을 실행하세요.
여러 개 실행가능한데 몇 개 까지 가능한지 확인 안해봤습니다.
파이썬에서 소켓 사용하는 방법에 대해서는 다음 포스트를 참고하세요.
파이썬 클라이언트 / 서버 소켓 예제
https://webnautes.tistory.com/2082
2019. 9. 30 최초작성
2023. 7. 26 제목 변경
image-server.py
파이썬의 recv 함수는 수신될 데이터의 크기를 미리 알아야 하기 때문에 서버에서 전송할 이미지의 크기를 보내서 클라이언트에서 수신받을 준비를 하게 해놓고 이미지를 전송합니다.
import socket import cv2 import numpy from queue import Queue from _thread import * enclosure_queue = Queue() # 쓰레드 함수 def threaded(client_socket, addr, queue): print('Connected by :', addr[0], ':', addr[1]) while True: try: data = client_socket.recv(1024) if not data: print('Disconnected by ' + addr[0],':',addr[1]) break stringData = queue.get() client_socket.send(str(len(stringData)).ljust(16).encode()) client_socket.send(stringData) except ConnectionResetError as e: print('Disconnected by ' + addr[0],':',addr[1]) break client_socket.close() def webcam(queue): capture = cv2.VideoCapture(0) while True: ret, frame = capture.read() if ret == False: continue encode_param=[int(cv2.IMWRITE_JPEG_QUALITY),90] result, imgencode = cv2.imencode('.jpg', frame, encode_param) data = numpy.array(imgencode) stringData = data.tostring() queue.put(stringData) cv2.imshow('image', frame) key = cv2.waitKey(1) if key == 27: break HOST = '127.0.0.1' PORT = 9999 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) server_socket.bind((HOST, PORT)) server_socket.listen() print('server start') start_new_thread(webcam, (enclosure_queue,)) while True: print('wait') client_socket, addr = server_socket.accept() start_new_thread(threaded, (client_socket, addr, enclosure_queue,)) server_socket.close() |
image-client.py
import socket import numpy as np import cv2 def recvall(sock, count): buf = b'' while count: newbuf = sock.recv(count) if not newbuf: return None buf += newbuf count -= len(newbuf) return buf HOST = '127.0.0.1' PORT = 9999 client_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM) client_socket.connect((HOST, PORT)) while True: message = '1' client_socket.send(message.encode()) length = recvall(client_socket,16) stringData = recvall(client_socket, int(length)) data = np.frombuffer(stringData, dtype='uint8') decimg=cv2.imdecode(data,1) cv2.imshow('Image',decimg) key = cv2.waitKey(1) if key == 27: break client_socket.close() |
참고
https://stackoverflow.com/questions/20820602/image-send-via-tcp
https://pymotw.com/3/queue/index.html
'Python > Python 예제 코드' 카테고리의 다른 글
두개의 리스트를 같은 순서로 정렬시키는 파이썬 예제 (0) | 2023.10.21 |
---|---|
MQTT 개념 및 예제 (0) | 2023.10.21 |
AttributeError: ‘str’ object has no attribute ‘stem’ 해결방법 (0) | 2023.10.15 |
특정 문자만 사용한 문자열인지 검사하는 파이썬 예제 (0) | 2023.10.14 |
파이썬 딕셔너리를 문자열로 바꾸기 (0) | 2023.10.14 |
시간날때마다 틈틈이 이것저것 해보며 블로그에 글을 남깁니다.
블로그의 문서는 종종 최신 버전으로 업데이트됩니다.
여유 시간이 날때 진행하는 거라 언제 진행될지는 알 수 없습니다.
영화,책, 생각등을 올리는 블로그도 운영하고 있습니다.
https://freewriting2024.tistory.com
제가 쓴 책도 한번 검토해보세요 ^^
그렇게 천천히 걸으면서도 그렇게 빨리 앞으로 나갈 수 있다는 건.
포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!