TypeError: must be str, not bytes , Python 3, Raspberry pi - sockets

I am trying to send video from raspberry pi to my laptop via laptop
and save them as pictures so i found the below code online
but I get the following errors when I run them
so i run this client code on the pi using Thonny ide that comes preloaded
, I apologize for the way code is formatted below and would be very grateful if anybody can help me sort this out
Server on the laptop is run using python 3.6 idle
import sys
import numpy as np
import cv2
import socket
class VideoStreamingTest(object):
def __init__(self):
self.server_socket = socket.socket()
self.server_socket.bind(('0.0.0.0', 9006))
self.server_socket.listen(0)
self.connection, self.client_address = self.server_socket.accept()
self.connection = self.connection.makefile('rb')
self.streaming()
def streaming(self):
try:
print("Connection from: ", self.client_address)
print("Streaming...")
print("Press 'q' to exit")
stream_bytes = ' '
while True:
stream_bytes += self.connection.read(1024)
first = stream_bytes.find('\xff\xd8')
last = stream_bytes.find('\xff\xd9')
if first != -1 and last != -1:
jpg = stream_bytes[first:last + 2]
stream_bytes = stream_bytes[last + 2:]
#image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.CV_LOAD_IMAGE_GRAYSCALE)
image = cv2.imdecode(np.fromstring(jpg, dtype=np.uint8), cv2.CV_LOAD_IMAGE_UNCHANGED)
cv2.imshow('image', image)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
finally:
self.connection.close()
self.server_socket.close()
if __name__ == '__main__':
VideoStreamingTest()
I get the following error
Connection from: ('192.168.43.3', 47518)
Streaming...
Press 'q' to exit
Traceback (most recent call last):
File "C:\Users\John Doe\d-ff\Desktop\AutoRCCar-master
3\test\stream_server_test.py", line 46, in <module>
VideoStreamingTest()
File "C:\Users\John Doe\d-ff\Desktop\AutoRCCar-master
3\test\stream_server_test.py", line 16, in __init__
self.streaming()
File "C:\Users\John Doe\d-ff\Desktop\AutoRCCar-master
3\test\stream_server_test.py", line 28, in streaming
stream_bytes += self.connection.read(1024)
TypeError: must be str, not bytes
Client side on the pi
import io
import socket
import struct
import time
import picamera
# create socket and bind host
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect(('ToM', 9006))
connection = client_socket.makefile('wb')
try:
with picamera.PiCamera() as camera:
camera.resolution = (320, 240) # pi camera resolution
camera.framerate = 5 # 10 frames/sec
time.sleep(2) # give 2 secs for camera to initilize
start = time.time()
stream = io.BytesIO()
# send jpeg format video stream
for foo in camera.capture_continuous(stream, 'jpeg', use_video_port = True):
connection.write(struct.pack('<L', stream.tell()))
connection.flush()
stream.seek(0)
connection.write(stream.read())
if time.time() - start > 600:
break
stream.seek(0)
stream.truncate()
connection.write(struct.pack('<L', 0))
finally:
connection.close()
client_socket.close()
I get the following error
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "/home/pi/Desktop/stream_client.py", line 40, in <module>
connection.close()
File "/usr/lib/python3.5/socket.py", line 594, in write
return self._sock.send(b)
BrokenPipeError: [Errno 32] Broken pipe
I first thought it might be because of the limited bandwidth since i was running vnc viewer (remote desktop) via wifi on the pi but I don't think it is

I also had same problem. After some searching I found solution.
In python 3 we have to specify whether string is regular string or binary.Thats why we use b'string' instead of just 'string'
Change
stream_bytes = ' '
to
stream_bytes = b' '
Also change
first = stream_bytes.find('\xff\xd8')
last = stream_bytes.find('\xff\xd9')
to
first = stream_bytes.find(b'\xff\xd8')
last = stream_bytes.find(b'\xff\xd9')
Note that you are using cv2.CV_LOAD_IMAGE_UNCHANGED which is not available in opencv3.0
Use cv2.IMREAD_COLOR to show image in color.
Edit these changes and your stream should run smoothly.

connection.write(struct.pack('<L', 0))
Check out by inserting the above within try

Related

Error code in a SPI camera connected to raspberry pi - micropython code

I've got the following code:
import machine
import time as utime
from OV5642_reg import *
OV5642=1
BMP =0
JPEG=1
RAW =2
OV5642_CHIPID_HIGH=0x300a
OV5642_CHIPID_LOW=0x300b
class ArducamClass(object):
def __init__(self,Type):
self.CameraMode=JPEG
self.CameraType=Type
self.SPI_CS = machine.Pin(5, mode=machine.Pin.OUT, value=1)
self.I2cAddress=0x3c
self.spi = machine.SPI(0, baudrate=4000000,polarity=0,phase=0,bits=8, sck=machine.Pin(2), mosi=machine.Pin(3), miso=machine.Pin(4))
self.i2c = machine.I2C(0, scl=machine.Pin(9), sda=machine.Pin(8), freq=1000000)
print(self.i2c.scan())
self.Spi_write(0x07,0x80)
utime.sleep(0.1)
self.Spi_write(0x07,0x00)
utime.sleep(0.1)
def Camera_Detection(self):
while True:
if self.CameraType==OV5642:
self.I2cAddress=0x3c
self.wrSensorReg16_8(0xff,0x01)
id_h=self.rdSensorReg16_8(OV5642_CHIPID_HIGH)
id_l=self.rdSensorReg16_8(OV5642_CHIPID_LOW)
if((id_h==0x56)and(id_l==0x42)):
print('CameraType is OV5642')
break
else:
print('Can\'t find OV5642 module')
utime.sleep(1)
def Set_Camera_mode(self,mode):
self.CameraMode=mode
def wrSensorReg16_8(self,addr,val):
buffer=bytearray(3)
buffer[0]=(addr>>8)&0xff
buffer[1]=addr&0xff
buffer[2]=val
self.iic_write(buffer)
def rdSensorReg16_8(self,addr):
buffer=bytearray(2)
rt=bytearray(1)
buffer[0]=(addr>>8)&0xff
buffer[1]=addr&0xff
self.iic_write(buffer)
self.iic_readinto(rt)
return rt[0]
def iic_write(self, buf, *, start=0, end=None):
if end is None:
end = len(buf)
self.i2c.writeto(self.I2cAddress, buf[start:end])
def iic_readinto(self, buf, *, start=0, end=None):
if end is None:
end = len(buf)
print(buf[start:end])
print(self.I2cAddress)
self.i2c.readfrom_into(self.I2cAddress, buf[start:end])
def Spi_write(self,address,value):
maskbits = 0x80
buffer=bytearray(2)
buffer[0]=address | maskbits
buffer[1]=value
self.SPI_CS.value(0)
self.spi_write(buffer)
self.SPI_CS.value(1)
def spi_write(self, buf, *, start=0, end=None):
if end is None:
end = len(buf)
self.spi.write(buf[start:end])
mycam = ArducamClass(OV5642)
mycam.Camera_Detection()
Which gives me the following error:
Traceback (most recent call last):
File "<stdin>", line 89, in <module>
File "<stdin>", line 33, in Camera_Detection
File "<stdin>", line 58, in rdSensorReg16_8
File "<stdin>", line 71, in iic_readinto
OSError: [Errno 5] EIO
I'm sure that the camera is connected correctly (I've tested it using the standard CircuitPython code provided with it and it works) so I think that I'm misinterpreting how the readfrom_into call works... any hint?
I tried to understand what get's written in the readfrom_into part but can't get anything.. The starting code (based on circuitpython) is here: https://github.com/ArduCAM/PICO_SPI_CAM/blob/master/Python/Arducam.py

Setting up a PICT with Raspberry Pi W zero: Error in picamera *.py : ], quality=qual):

For field, research where I want to study a plant-insect interaction, I am trying to set up a PICT (Plant Insect Interactions Camera Trap). There is a very detailed description available on https://zenodo.org/record/6301001, still I am stuck.
I can excess the camera through the browser but the script won’t start.
I am an absolute beginner and I have no idea what I am doing wrong. Can anybody help get this running?
This is the script from the paper which I saved as camera.py in home/pi:
import picamera
import socket
import uuid
from datetime import datetime as dt
qual=22 # level of image quality between 1 (highest quality, largest size) and 40 (lowest quality, smallest size), with typical values 20 to 25, default is 0.
video_duration = 3600 # video duration in seconds
video_number = 1000 # number of video sequences to shoot
UID = uuid.uuid4().hex[:4].upper()+'_'+dt.now().strftime('%Y-%m-%d_%H-%M') # generate random unique ID that will be used in video filename
HostName=socket.gethostname()
with picamera.PiCamera() as camera:
camera.resolution = (1296, 972) # max fps is 42 at 1296x972
camera.framerate = 15 # recomended are 12, 15, 24, 30
camera.annotate_frame_num = True
camera.annotate_text_size = int(round(camera.resolution[0]/64))
camera.annotate_background = picamera.Color('black') # text background colour
camera.annotate_foreground = picamera.Color('white') # text colour
for filename in camera.record_sequence([
'/home/pi/record/'+HostName+'_'+UID+'_%03d.h264' % (h + 1)
for h in range(video_number)
], quality=qual):
start = dt.now() # get the current date and time
while (dt.now() - start).seconds < video_duration: # run until video_duration is reached
camera.annotate_text = HostName+', '+str(camera.framerate)+' fps, Q='+str(qual)+', '+dt.now().strftime('%Y-%m-%d %H:%M:%S') # tag the video with a custom text
camera.wait_recording(0.2) # pause the script for a short interval to save power
I am gettin the following output:
~ $ python camera.py
Traceback (most recent call last):
File "camera.py", line 23, in <module>
], quality=qual):
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 1270, in record_sequence
camera_port, output_port = self._get_ports(True, splitter_port)
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 559, in _get_ports
self._check_camera_open()
File "/usr/lib/python2.7/dist-packages/picamera/camera.py", line 540, in _check_camera_open
raise PiCameraClosed("Camera is closed")
picamera.exc.PiCameraClosed: Camera is closed

Getting 'OSError: -2' while converting a tif image into jpg image using python

I'm trying to convert tiff images into jpg format and use it later in opencv. It is working fine in my local system but when I am executing it over linux server which is not connected to internet it is getting failed while saving the Image object as jpg format.
I'm using python3.8 and had installed all the libraries and its dependencies using wheel files over server using pip.
Here is the piece of code:
import PIL
import cv2
def face_detect(sourceImagepath1, processedFileName, imagename, pdfname):
temp_path = TEMP_PATH
processed_path = PROCESSED_PATH
misc_path = MISC_PATH
# cascade file path1
cascpath1 = misc_path + 'frontalface_cascade.xml'
# Create harr cascade
faceCascade = cv2.CascadeClassifier(cascpath1)
# Read image with PIL
image_pil = Image.open(sourceImagepath1)
# Save image in jpg format
image_pil.save(temp_path + processedFileName + '.jpg')
# Read image with opencv
image_cv = cv2.imread(temp_path + processedFileName + '.jpg')
# Convert image into grayscale
image_gray = cv2.cvtColor(image_cv, cv2.COLOR_BGR2GRAY)
# Detect faces in the image
face = faceCascade.detectMultiScale(
image_gray,
scaleFactor=1.3,
minNeighbors=5,
minSize=(30, 30)
# flags = cv2.CASCADE_SCALE_IMAGE
)
if len(face) > 0:
# Coordinates based on auto-face detection
x, y, w, h = face[0][0], face[0][1], face[0][2], face[0][3]
crop_image = image_pil.crop([x - 20, y - 30, x + w + 40, y + h + 60])
crop_image.save(processed_path + imagename)
# Save tif file as pdf
image_pil.save(processed_path + pdfname, save_all=True)
# Close image object
image_pil.close()
return len(face)
Here TEMP_PATH,PROCESSED_PATH,MISC_PATH are global variables of syntax like '/Users/user/Documents/Temp/'. I'm getting error on line:
image_pil.save(temp_path + processedFileName + '.jpg')
Below is the error i'm getting when executing the file
Traceback (most recent call last):
File "*path_from_root_directory*/PYTHON_SCRIPTS/Script/staging.py", line 363, in <module>
auto_face_count = face_detect(sourceImagepath1, processedFileName, imagename, pdfname)
File "*path_from_root_directory*/PYTHON_SCRIPTS/Script/staging.py", line 71, in greyScaleCheck
image_pil.save(temp_path + processedFileName + '.jpg')
File "*path_from_root_directory*/python3.8/site-packages/PIL/Image.py", line 2201, in save
self._ensure_mutable()
File "*path_from_root_directory*/python3.8/site-packages/PIL/Image.py", line 624, in _ensure_mutable
self._copy()
File "*path_from_root_directory*/python3.8/site-packages/PIL/Image.py", line 617, in _copy
self.load()
File "*path_from_root_directory*/python3.8/site-packages/PIL/TiffImagePlugin.py", line 1122, in load
return self._load_libtiff()
File "*path_from_root_directory*/python3.8/site-packages/PIL/TiffImagePlugin.py", line 1226, in _load_libtiff
raise OSError(err)
OSError: -2
I have provided full privileges to python directory and its sub-directories/files. Anyone have any idea why I'm getting this error ?

pymssql.connect error - unexpected keyword argument 'server'

I'm trying to run a program I've made but am having issues. It's stating there is an error on line 8? It was working the other day and I'm not sure if it has been changed. Is this an connection error to the database perhaps??
import RPi.GPIO as GPIO
import datetime
import time
import pymssql
conn = pymssql.connect (server='192.168.0.223', user='iad', password='iad',database='inputData')
cursor = conn.cursor()
#cursor.execute('select * from yesno')
#row = cursor.fetchone()
#while row:
# print str(row[0])
# row = cursor.fetchone()
print("Welcome! Button live data:")
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
while True:
input_state = GPIO.input(18)
input_state2 = GPIO.input(23)
if input_state == False:
print('Happy')
print(time.strftime("%Y-%m-%d"))
cursor.execute("INSERT INTO buttonsPressed (inputResult, date) VALUES ('yes', '" + time.strftime("%Y-%m-%d") + "')")
conn.commit()
time.sleep(1)
if input_state2 == False:
print('Not Happy')
print(time.strftime("%Y-%m-%d"))
cursor.execute("INSERT INTO buttonsPressed (inputResult, date) VALUES ('no', '" + time.strftime("%Y-%m-%d") + "')")
conn.commit()
time.sleep(1)
I'm getting this error?:
File "buttonin.py", line 8, in <module>
conn = pymssql.connect (server='192.168.0.223', user='iad', password='iad',database='inputData')
TypeError: connect() got an unexpected keyword argument 'server'
You may use host="" instead of server=""
I also had the same error.
Try upgrading the python pymssql library.
In Ubuntu you can upgrade it by following commands:
1. sudo apt-get install freetds-dev
2. pip install pymssql --upgrade
Hope this helps you.

Need help in Python3

I have the below code that i am trying the run using python3.2 interpreter.
import socket #for sockets
import sys #for exit
#from UserString import MutableString
#create an INET, STREAMing socket
try:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
except socket.error:
print ('Failed to create socket')
sys.exit()
print ('Socket Created')
host = 'www.google.com';
port = 80;
try:
remote_ip = socket.gethostbyname( host )
except socket.gaierror:
#could not resolve
print ('Hostname could not be resolved. Exiting')
sys.exit()
#Connect to remote server
s.connect((remote_ip , port))
print ('Socket Connected to ' + host + ' on ip ' + remote_ip)
#Send some data to remote server
message = "GET / HTTP/1.0\r\n\r\n"
try :
#Set the whole string
s.sendall(message.encode())
except socket.error:
#Send failed
print ('Send failed')
sys.exit()
print ('Message send successfully')
#Now receive data
messageParts = []
remaining = 4096
chunk = s.recv(remaining)
messageParts.append(chunk)
while (len(chunk) > 0):
chunk = s.recv(remaining)
messageParts.append(chunk.decode())
finalMessage = b"".join(messageParts)
print('Printing the html contents ...')
print(finalMessage)
Upon running the above code, with python version 3.2, i get the below error:
Socket Created
Socket Connected to www.google.com on ip 74.125.201.147
Message send successfully
Traceback (most recent call last):
File "TestMainServerV2.py", line 73, in <module>
finalMessage = b"".join(messageParts)
TypeError: sequence item 1: expected bytes, str found
Could anybody let me know what is the issue?
Thanks!
messageParts.append(chunk.decode())
is appending strs to messageParts.
chunk = s.recv(remaining)
messageParts.append(chunk)
is appending bytes to messageParts. (Everything that comes through a socket is bytes so chunk is a bytes object.)
Especially in Python3, one should never mix strs and bytes.
b"".join(messageParts)
raises a TypeError since b"".join expects only bytes.
You can avoid the problem by not decoding chunk. Use
messageParts.append(chunk)
instead of
messageParts.append(chunk.decode())