Introduction
The autofocus camera is an advanced IMX219 camera module for Jetson Nano/Xavier NX board. It helps to focus the object in close range from 5cm~30cm, within this range the standard fixed focus camera can not get sharp focus and the image looks burry. All the focus procedure is controlled by the software without manually adjust the lens barrel.
To learn more about autofocus with Raspberry Pi camera modules, we recommend you read Raspberry Pi Camera Autofocus: The Complete Guide.
Models in this Series
There are four cameras in this series. The main differences between them are IR sensitivity and whether the camera board is included. They are the same in terms of software operation.
SKU | Model | Field of View | IR Sensitivity |
B0190 | IMX219-drop-in-replacement | 77.6°D x 65°H x 51°V | NoIR(IR sensitive) |
B0182 | IMX219-drop-in-replacement | 77.6°D x 65°H x 51°V | Visible Light |
B0181 | IMX219 Autofocus Module | 77.6°D x 65°H x 51°V | Visible Light |
B0189 | IMX219 Autofocus Module | 77.6°D x 65°H x 51°V | NoIR(IR sensitive) |
Too short camera cable?
You may need Arducam 30cm Sensor Extension Cable which extends the small camera module with a much longer distance and fit into the space-constrained environment.

Common Specs
General Specifications
Sensor Model | IMX219 |
Shutter Type | Rolling Shutter |
Active Pixels | 3280 (H) × 2464 (V) |
Resolution | 8MP |
Image Sensor Format | Type 1/4″ |
Pixel Size | 1.12μm×1.12μm |
CSI-2 Data Output | 2-lane mode |
Data Format | Raw Bayer 10bit |

Quick Start Guide
Hardware Setup
- Locate the camera connector (CSI). It’s on the side of the carrier board, opposite to the GPIO pins.
- Pull up on the plastic edges of the camera port. Do it gently to avoid pulling it off.

- Push in the camera ribbon. Make sure the contacts are facing the heatsinks. Do not bend the flex cable, and make sure it’s firmly inserted into the bottom of the connector.



- Push the plastic connector down. Do it while holding the flex cable until the connector is back in place.
Software Setup
Preparation
- Start up your Raspberry Pi.
- Go to the main menu and open the Raspberry Pi Configuration tool.
- Select the Interfaces tab and ensure that the camera is enabled:
- Reboot your Raspberry Pi.
First Use
1.Download Arducam’s Jetson Nano repository
git clone https://github.com/ArduCAM/Nvidia_Jetson.git
2.Enter the folder with the autofocus demo
cd Nvidia_Jetson/IMX219_AutoFocus
3.Run the demo
This example python code is modified from JetsonHacks sample code in order to work with Arducam Autofocus IMX219 camera module.
sudo python Autofocus.py
# MIT License # Copyright (c) 2019 JetsonHacks # See license # Using a CSI camera (such as the Raspberry Pi Version 2) connected to a # NVIDIA Jetson Nano Developer Kit using OpenCV # Drivers for the camera and OpenCV are included in the base image import cv2 import numpy as py import os def focusing(val): value = (val << 4) & 0x3ff0 data1 = (value >> 8) & 0x3f data2 = value & 0xf0 os.system("i2cset -y 6 0x0c %d %d" % (data1,data2)) def sobel(img): img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) img_sobel = cv2.Sobel(img_gray,cv2.CV_16U,1,1) return cv2.mean(img_sobel)[0] def laplacian(img): img_gray = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) img_sobel = cv2.Laplacian(img_gray,cv2.CV_16U) return cv2.mean(img_sobel)[0] # gstreamer_pipeline returns a GStreamer pipeline for capturing from the CSI camera # Defaults to 1280x720 @ 60fps # Flip the image by setting the flip_method (most common values: 0 and 2) # display_width and display_height determine the size of the window on the screen def gstreamer_pipeline (capture_width=1280, capture_height=720, display_width=1280, display_height=720, framerate=60, flip_method=0) : return ('nvarguscamerasrc ! ' 'video/x-raw(memory:NVMM), ' 'width=(int)%d, height=(int)%d, ' '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' % (capture_width,capture_height,framerate,flip_method,display_width,display_height)) def show_camera(): max_index = 10 max_value = 0.0 last_value = 0.0 dec_count = 0 focal_distance = 10 focus_finished = False # To flip the image, modify the flip_method parameter (0 and 2 are the most common) print gstreamer_pipeline(flip_method=0) cap = cv2.VideoCapture(gstreamer_pipeline(flip_method=0), cv2.CAP_GSTREAMER) if cap.isOpened(): window_handle = cv2.namedWindow('CSI Camera', cv2.WINDOW_AUTOSIZE) # Window while cv2.getWindowProperty('CSI Camera',0) >= 0: ret_val, img = cap.read() cv2.imshow('CSI Camera',img) if dec_count < 6 and focal_distance < 1000: #Adjust focus focusing(focal_distance) #Take image and calculate image clarity val = laplacian(img) #Find the maximum image clarity if val > max_value: max_index = focal_distance max_value = val #If the image clarity starts to decrease if val < last_value: dec_count += 1 else: dec_count = 0 #Image clarity is reduced by six consecutive frames if dec_count < 6: last_value = val #Increase the focal distance focal_distance += 10 elif not focus_finished: #Adjust focus to the best focusing(max_index) focus_finished = True # This also acts as keyCode = cv2.waitKey(16) & 0xff # Stop the program on the ESC key if keyCode == 27: break elif keyCode == 10: max_index = 10 max_value = 0.0 last_value = 0.0 dec_count = 0 focal_distance = 10 focus_finished = False cap.release() cv2.destroyAllWindows() else: print 'Unable to open camera' if __name__ == '__main__': show_camera()