반응형

파이썬의 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




  

 

반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts