Package: nanocamera
NanoCameraA simple to use camera interface for the Jetson Nano for working with USB, CSI, IP and also RTSP cameras or streaming video in Python 3.It currently supports the following types of camera or streaming source:Works with CSI Cameras (Tested and Works)Works with various USB cameras (Tested with Logitech USB camera)Works with RTSP streaming camera and video with hardware acceleration (only supports H.264 video codec)Works with IP Cameras(JPEG codec) or any MJPEG streaming source (Currently, supports CPU acceleration. TODO: Hardware acceleration)If you likeNanoCameralibrary - give it a star, or fork it and contribute!. Updates are always welcomed.FeaturesIt is OpenCV ready. The image file can be called directly with OpenCV imshowImage file is a NumPy RGB array.Support different Camera Flip Mode (Counterclockwise, Rotate 180 degrees, Clockwise - 90 degrees, Horizontal Flip, Vertical Flip)Can be used with multiple cameras.Support Frame rate enforcement. *Only available for USB, RTSP, and IP/MJPEG cameras.Frame rate enforcement ensures the cameras work at the given frame rate using GStreamer video rate pluginIt is based onAccelerated GStreamer PluginsShould work with other Jetson boards like Jetson TX1, TX2 and others (Not tested)Support both Hardware and CPU acceleration.Easily read images asnumpyarrays withimage = camera.read()Supports threaded read - available to all camera types. To enable a fast threaded read, you will enable the enforce_fps:enforce_fps = TrueCheck the status of the camera after initialization withisReady()function. ReturnsTrueif ready andFalseif otherwise.Provide debugging support. Added error codes and an optional exception handling. See example inDebugging. Now you can restart the camera if something goes wrong or send an admin notice if your camera goes down.Support multiple CSI cameras using thedevice_idparameter. See examples.RequirementsThis library requires OpenCV to be installed to work.
If you don't have OpenCV, you can install one with pip:pip3installopencv-pythonInstallInstallation is simple. Can be installed in two ways with Pip or Manually.Pip Installationpip3installnanocameraManual Installationgitclonehttps://github.com/thehapyone/NanoCameracdNanoCamera
sudopython3setup.pyinstallUsage & ExampleUsing NanoCamera is super easy. Below we show some usage examples.  You can find more in theexamples.Working with CSI CameraFor CSI Cameras, thecamera_type = 0.Find here for fullCSI camera examplePython Example -
Create a CSI camera using default FPS=30, default image size: 640 by 480 and with no rotation (flip=0)importnanocameraasnano# Create the Camera instance for 640 by 480camera=nano.Camera()Customizing the width and heightimportnanocameraasnano# Create the Camera instance for No rotation (flip=0) with size of 1280 by 800camera=nano.Camera(flip=0,width=1280,height=800,fps=30)if the image is inverted, setflip = 2Multiple CSI Camera support.For Multiple CSI Cameras, set thedevice_idto the ID of the camera.importnanocameraasnano# Create the Camera instance for No rotation (flip=0) with size of 1280 by 800# Connect to CSI camera with ID 0 (Default)camera_1=nano.Camera(device_id=0,flip=0,width=1280,height=800,fps=30)# Connect to another CSI camera on the board with ID 1camera_2=nano.Camera(device_id=1,flip=0,width=1280,height=800,fps=30)Working with USB CameraFor USB Cameras, set thecamera_type = 1, and set thedevice_idas well.
Find here for fullUSB camera examplePython Example -
Create USB camera connected to/dev/video1importnanocameraasnano# Create the Camera instance for No rotation (flip=0) with size of 640 by 480camera=nano.Camera(camera_type=1,device_id=1,width=640,height=480,fps=30)You can see connected USB cameras by running :ls/dev/video*# for USB camera /dev/video2, the device_id will be 2Working with RTSP streaming camera or streaming videoFor RTSP source, set thecamera_type = 2, and set thesourceas well.
Find here for fullRTSP camera examplePython Example -
Create RTSP receiving camera client. RTSP location example:rtsp://192.168.1.26:8554/stream# a location for the rtsp stream. Stream location without "rtsp://"rtsp_location="192.168.1.26:8554/stream"# Create the Camera instancecamera=nano.Camera(camera_type=2,source=rtsp_location,width=640,height=480,fps=30)Working with IP or any MJPEG streaming camera or videoFor IP/MJPEG Cameras, set thecamera_type = 3, and set the streamingsourceas well.
Find here for fullMJPEG camera examplePython Example -
Create an IP camera client connected to a camera streaming tohttp://192.168.1.26:80/stream# a location for the camera stream. Stream location without "http://"camera_stream="192.168.1.26:80/stream"# Create the Camera instancecamera=nano.Camera(camera_type=3,source=camera_stream,width=640,height=480,fps=30)Frame Rate EnforcementEnable frame rate enforcement i.e force the camera to work at the given frame rateimportnanocameraasnano# enforce the capture frame rate with the enforce_fps=Truecamera=nano.Camera(camera_type=1,device_id=1,width=640,height=480,fps=30,enforce_fps=True)Reading CameraCallread()to read the latest image as anumpy.ndarray. The color format isBGR.frame=camera.read()Camera isReady?You can check if the camera is ready for streaming usingisReady()status=camera.isReady()A Simple program to read from the CSI camera and display with OpenCVimportcv2#from nanocamera.NanoCam import Cameraimportnanocameraasnanoif__name__=='__main__':# Create the Camera instancecamera=nano.Camera(flip=0,width=640,height=480,fps=30)print('CSI Camera ready? - ',camera.isReady())whilecamera.isReady():try:# read the camera imageframe=camera.read()# display the framecv2.imshow("Video Frame",frame)ifcv2.waitKey(25)&0xFF==ord('q'):breakexceptKeyboardInterrupt:break# close the camera instancecamera.release()# remove camera objectdelcameraA Simple program to read from the IP/MJPEG camera and display with OpenCVimportcv2# from nanocamera.NanoCam import Cameraimportnanocameraasnanoif__name__=='__main__':# requires the Camera streaming url. Something like this: http://localhost:80/stream# For IP/MJPEG camera, the camera_type=3.# This works with only camera steaming MJPEG format and not H.264 codec for now# a location for the camera streamcamera_stream="192.168.1.26:80"# Create the Camera instancecamera=nano.Camera(camera_type=3,source=camera_stream,width=640,height=480,fps=30)print('MJPEG/IP Camera is now ready')whilecamera.isReady():try:# read the camera imageframe=camera.read()# display the framecv2.imshow("Video Frame",frame)ifcv2.waitKey(25)&0xFF==ord('q'):breakexceptKeyboardInterrupt:break# close the camera instancecamera.release()# remove camera objectdelcameraDebuggingThe library has some debugging builtin for managing expected, unexpected errors, and exceptions that might occur during the camera acquisition or initialization.Using thedebugparameter to enable raising of exceptions when an error occurred. This is disabled in the default mode so you won't get any error if something goes wrong.Using thehasError()to read the current error state of the camera with or without debug enabled.Errors and Exceptions HandlingCallingcamere.hasError()at any point in time returns a list of error codes and a boolean value:# status holds a list.status=camera.hasError()print(status)>>([0,3],True)print("Error codes list : ",status[0])>>Errorcodeslist:[0,3]print("Error State : ",status[1])>>ErrorState:TrueError codes are'''
-1 = Unknown error
0 = No error
1 = Error: Could not initialize camera.
2 = Thread Error: Could not read image from camera
3 = Error: Could not read image from camera
4 = Error: Could not release camera
'''For example:error_status=camera.hasError()iferror_status[1]==False:# means no error detected so far# read the camera imageframe=camera.read()# print the current error codesprint(error_status[0])# display the framecv2.imshow("Video Frame",frame)ifcv2.waitKey(25)&0xFF==ord('q'):breakelse:# an error has occured.print("An error with the camera. Error code : ",error_status[0])Enabling thedebug = Trueparameter allows raising an exception to the main program. This might be useful for parallel computing if you running multiple threads. Without thedebugenabled, your program will continue as normal, and worse if you're enabled the frame rate enforcement which uses the thread read function, you will keep getting image data but those images are old/static images.See an example using thedebugparameter and handling exceptions at different levels. Find here for fulldebugging exampleif__name__=='__main__':# with debug=True. An Exception will be raised if something goes wrong.# Create the Camera instancetry:# Create the Camera instanceprint("camera stream")camera=nano.Camera(camera_type=1,device_id=0,fps=30,debug=True)exceptExceptionase:# handle the exception from opening camera sessionelse:print('USB Camera ready? - ',camera.isReady())whileTrue:try:# read the camera imageframe=camera.read()# do something with frame like: send_to_cloud(frame)exceptKeyboardInterrupt:breakexceptExceptionase:# handle the exception from readingbreakprint("done here")try:# close the camera instancecamera.release()exceptExceptionase:# handle the exception from releasing the cameraIf an error occurred, a Runtime Error will be raised catching the following exceptions:Theexceptcausemightcatchthefollowingexceptions:>>ExceptionType-Error:CouldnotinitializeUSBCamera>>ExceptionType-Anerrorasoccurred.ErrorValue:[0,3]>>ExceptionType-UnknownErrorhasoccurred>>ExceptionType-Error:CouldnotreleasecameraWithoutdebugand even if there is error the program runs as nothing happened. The error can still be detected with thehasError()function.Thanks! & Give it a StarThank you for downloading and enjoying the NanoCamera library.
I hope you find it useful. Heck, I wrote it for you- yeah, that's right- you.Contributing to this software is warmly welcomed. Don't forget to give it a star.LicenseThis project is released under the MIT License.See alsoPlatooning Robot- Resources for building collaborative robots