Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Small Refactoring and Documentation of the camera_data Module #152

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions camera_data/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Camera Data Module

This module read and writes data from available camera feeds in the `/camera_frames` topic.

### Messages

- `v_angle`: Vertical orientation tilt of the camera enclosed in [-90, 90] degrees (The pitch axis of rotation).
- `h_angle`: Horizontal orientation tilt of the camera enclosed in [-90, 90] degrees (The Yaw axis of rotation).

### Scripts

- `camera_feeds.py`: Collects available camera ports and outputs them all in distinct windows.
- `camera_subscriber.py`: Subscriber to the `/camera_frames` topic that displays the images to screen.
- `camera_publisher.py`: Publishes frames from the selected camera (from the `camera_selection` topic) to the
`/camera_frames` topic at a rate of __30fps__.

### Tests

- `test_get_cameras.py`: Tests the camera feed collection from the `camera_feeds.py` script.
40 changes: 40 additions & 0 deletions camera_data/src/camera_feeds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import cv2


class CameraHandler:
available_cameras = []

def __init__(self):
# Collect all found cameras
# Assumes sequential indices
for i in range (25):
newCap = cv2.VideoCapture(i, cv2.CAP_V4L2)

if newCap is not None and newCap.open(i):
self.available_cameras.append(newCap)

def get_all_feeds(self):
ret_frame = []
for camera in self.available_cameras:
newFeed = camera.read()
ret_frame.append((newFeed[0], newFeed[1]))

return ret_frame

def run_feeds(self):
print("Press 'q' to exit")
while True:
for index, (ret, frame) in enumerate(self.get_all_feeds()):
if ret:
cv2.imshow(f"frame {index}", frame)

if cv2.waitKey(1) & 0xFF == ord('q'):
for vid in self.available_cameras:
vid.release()
cv2.destroyAllWindows()
break

# Runnable to display camera feeds
if __name__ == '__main__':
camera_handler = CameraHandler()
camera_handler.run_feeds()
26 changes: 10 additions & 16 deletions camera_data/src/camera_publisher.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
#!/usr/bin/env python3
import os, sys
from pydoc_data.topics import topics

currentdir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(currentdir)
import rospy
import cv2
import time
from cv_bridge import CvBridge
from sensor_msgs.msg import Image
from std_msgs.msg import Int16
from PyQt5 import QtGui
import sys

stop = False
Expand All @@ -24,23 +21,20 @@ def __init__(self):

rospy.init_node('camera_frame_publisher')
self.camera_select_subscriber = rospy.Subscriber("camera_selection", Int16, self.select_camera)
self.timer = rospy.Timer(rospy.Duration(0.03), self.timer_callback)
_30fps_ns = 30000000
self.timer = rospy.Timer(rospy.Duration(0, _30fps_ns), self.timer_callback)
JosephSaliba01 marked this conversation as resolved.
Show resolved Hide resolved
self.camera_frame_publisher = rospy.Publisher('/camera_frames', Image, queue_size=10)

def timer_callback(self, event):
try:
ret, frame = self.video_capture.read()
# these code cause error
encode_params = [int(cv2.IMWRITE_JPEG_QUALITY), 90]
result, frame = cv2.imencode(".jpg", frame, encode_params)
def timer_callback(self, _):
ret, frame = self.video_capture.read()
if ret:
encode_params = [cv2.IMWRITE_JPEG_QUALITY, 90]
_, frame = cv2.imencode(".jpg", frame, encode_params)
self.frames = self.openCV_to_ros_image(frame)
if ret:
print("Publishing frame")
self.camera_frame_publisher.publish(self.frames)
except:
print("Publishing frame")
self.camera_frame_publisher.publish(self.frames)
else:
print("No camera found")
finally:
pass

def openCV_to_ros_image(self, cv_image):
try:
Expand Down
6 changes: 2 additions & 4 deletions camera_data/src/camera_subscriber.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import os, sys
from pydoc_data.topics import topics
currentdir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(currentdir)

import rospy
currentdir = os.path.dirname(os.path.realpath(__file__))
sys.path.append(currentdir)
import cv2
from sensor_msgs.msg import Image
from cv_bridge import CvBridge
Expand Down Expand Up @@ -34,4 +32,4 @@ def ros_to_openCV_image(self, ros_image):

if __name__ == "__main__":
driver = Node_CameraFrameSub()
rospy.spin()
rospy.spin()
45 changes: 0 additions & 45 deletions camera_data/src/getCameraFeeds.py

This file was deleted.

26 changes: 0 additions & 26 deletions camera_data/test/test_getCam.py

This file was deleted.

13 changes: 13 additions & 0 deletions camera_data/test/test_get_cameras.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import sys
import os

# gets location of getCameraFeeds to be recognized as a module
dir = os.path.dirname(__file__)
filename = os.path.join(dir, '../src')
sys.path.insert(0,filename)

import getCameraFeeds as gcf

# Runnable to display camera feeds
camera_handler = gcf.CameraHandler()
camera_handler.run_feeds()