Skip to content

Commit

Permalink
Add instrumented versions
Browse files Browse the repository at this point in the history
  • Loading branch information
jetsonhacks committed Mar 26, 2020
1 parent bacee3d commit 6dd01cd
Show file tree
Hide file tree
Showing 9 changed files with 596 additions and 167 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
simple_camera
__pycache__
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,16 @@ The camera should be installed in the MIPI-CSI Camera Connector on the carrier b
The new Jetson Nano B01 developer kit has two CSI camera slots. You can use the sensor_mode attribute with nvarguscamerasrc to specify the camera. Valid values are 0 or 1 (the default is 0 if not specified), i.e.

```
nvarguscamerasrc sensor_mode=0
nvarguscamerasrc sensor_id=0
```

To test the camera:

```
# Simple Test
# Ctrl^C to exit
$ gst-launch-1.0 nvarguscamerasrc ! nvoverlaysink
# sensor_id selects the camera: 0 or 1 on Jetson Nano B01
$ gst-launch-1.0 nvarguscamerasrc sensor_id=0 ! nvoverlaysink
# More specific - width, height and framerate are from supported video modes
# Example also shows sensor_mode paramter to nvarguscamerasrc
Expand Down Expand Up @@ -50,6 +51,7 @@ The final example is dual_camera.py. This example is for the newer rev B01 of th
$ python3 dual_camera.py
```

The directory 'instrumented' contains instrumented code which can help adjust performance and frame rates.

<h2>Notes</h2>

Expand All @@ -58,7 +60,7 @@ You can use v4l2-ctl to determine the camera capabilities. v4l2-ctl is in the v4

$ sudo apt-get install v4l-utils

For the Raspberry Pi V2 camera the output is (assuming the camera is /dev/video0):
For the Raspberry Pi V2 camera, typically the output is (assuming the camera is /dev/video0):

```
$ v4l2-ctl --list-formats-ext
Expand Down
145 changes: 145 additions & 0 deletions instrumented/csi_camera.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
# MIT License
# Copyright (c) 2019,2020 JetsonHacks
# See license in root folder
# CSI_Camera is a class which encapsulates an OpenCV VideoCapture element
# The VideoCapture element is initialized via a GStreamer pipeline
# The camera is read in a separate thread
# The class also tracks how many frames are read from the camera;
# The calling application tracks the frames_displayed

# Let's use a repeating Timer for counting FPS
import cv2
import threading

class RepeatTimer(threading.Timer):
def run(self):
while not self.finished.wait(self.interval):
self.function(*self.args, **self.kwargs)

class CSI_Camera:

def __init__ (self) :
# Initialize instance variables
# OpenCV video capture element
self.video_capture = None
# The last captured image from the camera
self.frame = None
self.grabbed = False
# The thread where the video capture runs
self.read_thread = None
self.read_lock = threading.Lock()
self.running = False
self.fps_timer=None
self.frames_read=0
self.frames_displayed=0
self.last_frames_read=0
self.last_frames_displayed=0


def open(self, gstreamer_pipeline_string):
try:
self.video_capture = cv2.VideoCapture(
gstreamer_pipeline_string, cv2.CAP_GSTREAMER
)

except RuntimeError:
self.video_capture = None
print("Unable to open camera")
print("Pipeline: " + gstreamer_pipeline_string)
return
# Grab the first frame to start the video capturing
self.grabbed, self.frame = self.video_capture.read()

def start(self):
if self.running:
print('Video capturing is already running')
return None
# create a thread to read the camera image
if self.video_capture != None:
self.running=True
self.read_thread = threading.Thread(target=self.updateCamera)
self.read_thread.start()
return self

def stop(self):
self.running=False
self.read_thread.join()

def updateCamera(self):
# This is the thread to read images from the camera
while self.running:
try:
grabbed, frame = self.video_capture.read()
with self.read_lock:
self.grabbed=grabbed
self.frame=frame
self.frames_read += 1
except RuntimeError:
print("Could not read image from camera")
# FIX ME - stop and cleanup thread
# Something bad happened


def read(self):
with self.read_lock:
frame = self.frame.copy()
grabbed=self.grabbed
return grabbed, frame

def release(self):
if self.video_capture != None:
self.video_capture.release()
self.video_capture = None
# Kill the timer
self.fps_timer.cancel()
self.fps_timer.join()
# Now kill the thread
if self.read_thread != None:
self.read_thread.join()

def update_fps_stats(self):
self.last_frames_read=self.frames_read
self.last_frames_displayed=self.frames_displayed
# Start the next measurement cycle
self.frames_read=0
self.frames_displayed=0

def start_counting_fps(self):
self.fps_timer=RepeatTimer(1.0,self.update_fps_stats)
self.fps_timer.start()

@property
def gstreamer_pipeline(self):
return self._gstreamer_pipeline

# Currently there are setting frame rate on CSI Camera on Nano through gstreamer
# Here we directly select sensor_mode 3 (1280x720, 59.9999 fps)
def create_gstreamer_pipeline(
self,
sensor_id=0,
sensor_mode=3,
display_width=1280,
display_height=720,
framerate=60,
flip_method=0,
):
self._gstreamer_pipeline = (
"nvarguscamerasrc sensor-id=%d sensor-mode=%d ! "
"video/x-raw(memory:NVMM), "
"format=(string)NV12, framerate=(fraction)%d/1 ! "
"nvvidconv flip-method=%d ! "
"video/x-raw, width=(int)%d, height=(int)%d, format=(string)BGRx ! "
"videoconvert ! "
"video/x-raw, format=(string)BGR ! appsink"
% (
sensor_id,
sensor_mode,
framerate,
flip_method,
display_width,
display_height,
)
)



Loading

0 comments on commit 6dd01cd

Please sign in to comment.