Search code examples
python-2.7video-streamingpygamewebcam

Stream video in python use pygame lib


I use library pygame in python to stream video from webcam of RasberryPi to my computer. But I have a problem when receive image. It's not convert true image. I've replaced my cam's ip adress with a placeholder <my_ip>. This is my code:

Server:

import socket,os
from PIL import *
import pygame,sys
import pygame.camera
from pygame.locals import *

#Create server:
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((<my_ip>,5000))
server.listen(5)

#Start Pygame
pygame.init()
pygame.camera.init()

screen = pygame.display.set_mode((320,240))

cam = pygame.camera.Camera("/dev/video0",(320,240),"RGB")
cam.start()

#Send data
while True:
    s,add = server.accept()
    print "Connected from",add
    image = cam.get_image()
    screen.blit(image,(0,0))
    data = cam.get_raw()
    s.sendall(data)
    pygame.display.update()

#Interupt
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()

Client:

import socket,sys
import pygame
from PIL import Image

#Create a var for storing an IP address:
ip = <my_ip>

#Start PyGame:
pygame.init()
screen = pygame.display.set_mode((320,240))
pygame.display.set_caption('Remote Webcam Viewer')
font = pygame.font.SysFont("Arial",14)
clock = pygame.time.Clock()
timer = 0
previousImage = ""
image = ""

#Main program loop:
while True:
  for event in pygame.event.get():
    if event.type == pygame.QUIT:
      sys.exit()

#Receive data
  if timer < 1:
    client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    client_socket.connect((str(ip),5000))
    data = client_socket.recv(1024000)
    timer = 30

  else:
    timer -= 1
  previousImage = image

#Convert image
  try:
    image = Image.fromstring("RGB",(120,90),data)
    image = image.resize((320,240))
    image = pygame.image.frombuffer(image.tostring(),(320,240),"RGB")

#Interupt
  except:
    image = previousImage 
  output = image
  screen.blit(output,(0,0))
  clock.tick(60)
  pygame.display.flip()

But this is result after tranfer:

Image


Solution

  • You are reassembling an image from the raw data received, but because you are sending a bigger resolution that you are re-creating, the pixels are 'overflowing' creating this effect.

    the offending line is:

    image = Image.fromstring("RGB",(120,90),data)
    

    which should be:

    image = Image.fromstring("RGB",(320,240),data)
    

    *Not tested but should work.