Corrupt JPEG data: premature end of data segment
Hi everybody,
I am using ROS 20 noetic on ubuntu 20.04. I try using my camera (Arducam IMX477 with usb adapter). I first started using it with a simple python script and it has worked well, then using ros was ok. But when I tried to created a camera handler in a thread to be able acquiring frame continuously in a background and being able to change the resolution when I want.
import rospy
import os
from pathlib import Path
import cv2
import time
from threading import Thread
from cv_bridge import CvBridge
from sensor_msgs.msg import Image
bridge = CvBridge()
# Initialize architecture
import inspect
FILE = Path(inspect.getfile(lambda: None)).resolve() # Get the full path of the file
node_name = os.path.splitext(FILE.name)[0]
import rospkg
rospack = rospkg.RosPack()
package = rospkg.get_package_name(FILE) # Get the package name
ROOT = Path(package).resolve() # Get the full path of the package
# Topics to subscribe/publish
camera_topic = "/cam_2/color/image_raw"
# Define a camera handler
class Camera_handler:
def __init__(self):
# Create the camera handler object
try:
entries = os.listdir("/dev")
num = min([int(entry[5:]) for entry in entries if "video" in entry])
src = "/dev/video"+str(num)
self.cap = cv2.VideoCapture(src, cv2.CAP_V4L2)
except cv2.error as error:
print("[Error]: {}".format(error))
if not self.cap.isOpened():
print("Cannot open camera handler")
exit()
(self.ret, self.img) = self.cap.read()
self.idx = 1 # The number of frame grabbed
self.width = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)
self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
self.fps = self.cap.get(cv2.CAP_PROP_FPS)
self.cam_pub = rospy.Publisher(camera_topic, Image, queue_size=1) # Publisher
self.cam_thread = None
self.stop_thread = False
self.start()
print("Camera handler capturing %s at (%d,%d) %dFPS" %(src, int(self.width),int(self.height),int(self.fps)))
def setResolution(self, width, height):
self.stop()
self.cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
self.cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
# update attributes
self.width = self.cap.get(cv2.CAP_PROP_FRAME_WIDTH)
self.height = self.cap.get(cv2.CAP_PROP_FRAME_HEIGHT)
self.fps = self.cap.get(cv2.CAP_PROP_FPS)
print("Parameters updated to (%d,%d) %dFPS" %(int(self.width),int(self.height),int(self.fps)))
self.start()
def read():
return self.img
def start(self):
self.stop_thread = False
self.cam_thread = Thread(target=self.update, args=())
self.cam_thread.start()
def update(self):
while self.cap.isOpened():
if self.stop_thread:
break
(self.ret, self.img) = self.cap.read()
if self.ret:
self.img = cv2.rotate(self.img, cv2.ROTATE_90_CLOCKWISE)
im = bridge.cv2_to_imgmsg(self.img, encoding="bgr8")
# Select one frame according to the index and publish it
im.header.stamp = rospy.get_rostime() # Set a timestamp
im.header.frame_id = "frame_" + str(self.idx)
im.header.seq = self.idx
self.cam_pub.publish(im) # Publish the frame
self.idx+=1
def stop(self):
self.stop_thread = True # stop immediatly the camera
self.cam_thread.join()
def release(self):
self.stop_thread = True # stop immediatly the camera
self.cam_thread.join()
print(" ")
print("Camera thread killed")
self.cap.release()
print("VideoCapture released")
def testIMX477_usb():
# Create the camera controller
imx = Camera_handler()
imx.start()
rospy.spin()
imx ...
Just an observation:
that's not what
header.frame_id
is supposed to be used for.frame_id
should contain the TF frame name associated with the captured image.The frame here does not refer to a frame in a video sequence, but a coordinate system.
The way you're using it here appears to be like a frame counter, which will make everything downstream very confused about where the sensor capturing those images is located, and will likely make using TF impossible.
Thank you for your comment, I don't use tf yet but you avoid me to meet a future little error. I have changed this, thank you.
My problem remains, does anyone have an idea to inspect ? Maybe like pecularities in ros thread which don't able me to use another thread with rospy or something else ?