[FRDM-IMX95] Installing the i.MX 95 Camera Application (Japanese Blog) Introduction
Here are two examples of how to implement camera-based applications using the FRDM-IMX95 board.
Display preview images using Gstreamer
Capture camera images using Python, process them with OpenCV, and then display the results.
Strictly speaking, both methods use GStreamer, but the latter also serves as a foundation for use cases where each acquired image frame is input into an AI model.
(Estimated time: 10 minutes) *Assuming the Linux image has been successfully written to the FRDM-IMX95.
Required hardware
FRDM-IMX95 (The photo shows a prototype, so the appearance may differ slightly from the commercially available product.)
OS08A20 Camera Module
HDMI input display
For instructions on how to use the FRDM-IMX95, please refer to the FRDM-IMX95 Board User Manual .
FRDM-IMX95-resized.jpg
Required software
Linux demo image (running on L6.18.2_1.0.0)
You are welcome to use an image file you built yourself. In that case, please use imx-image-full. Please also refer to "[Beginner's Guide] How to Build Yocto Linux BSP - i.MX FRDM Board Edition" (Japanese Blog) .
The procedure for writing the image is described in section 4.2.2 of the method for writing the image generated by building a Linux BSP to the target board . Please refer to "Writing with uuu - Writing the entire wic image".
table of contents
1. Modify the device tree and boot Linux.
2. Check the hardware and device tree.
3. Preview display in Gstreamer
4. Perform camera capture and image processing.
4.1 Camera Capture + Image Processing in Python
4.2 Code Explanation
In conclusion
1. Modify the device tree and boot Linux.
In the u-boot console, execute the following: This is the device tree configuration to allow Linux to recognize the OS08A20 camera module.
u-boot=> setenv fdtfile imx95-15x15-frdm-os08a20-isp.dtb
u-boot=> saveenv
2. Check the hardware and device tree.
The i.MX 95 uses a framework called libcamera. The `cam -l` command can be used to verify that the hardware is correctly connected and that the configured device tree is correct. The following is the expected result:
root@imx95-15x15-lpddr4x-frdm:~# cam -l
[0:27:23.440218928] [901] INFO Camera camera_manager.cpp:340 libcamera v0.0.0+6489-lf-6.18.2-1.0.0
[0:27:23.544276996] [902] INFO MediaPipeline media_pipeline.cpp:240 Found pipeline: [os08a20 3-0036|0] -> [0|csidev-4ad30000.csi|1] -> [0|4ac10000.syscon:formatter@20|1] -> [2|crossbar]
[0:27:23.545335314] [902] INFO Camera camera_manager.cpp:223 Adding camera '/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36' for pipeline handler imx8-isi
Available cameras:
1: External camera 'os08a20' (/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36)
The last line displayed (/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36) will be used later as the camera name.
3. Preview display in Gstreamer
Execute the following two lines to set the appropriate environment variables.
root@imx95-15x15-lpddr4x-frdm:~# export LIBCAMERA_IPA_MODULE_PATH="/usr/lib/libcamera/ipa"
root@imx95-15x15-lpddr4x-frdm:~# export LIBCAMERA_PIPELINES_MATCH_LIST="nxp/neo,imx8-isi,uvc"
Next, the following two commands should display a preview of the camera on the HDMI-connected display.
root@imx95-15x15-lpddr4x-frdm:~# CAMERA0=/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36
root@imx95-15x15-lpddr4x-frdm:~# gst-launch-1.0 libcamerasrc camera-name="${CAMERA0}" ! \
video/x-raw, width=3840,height=2160,framerate=30/1,format=YUY2 ! \
queue ! \
waylandsink
The first line defines a variable called "CAMERA0" and specifies the camera name (path) found using the `cam -l` command after Linux has started. This is then passed as `camera-name` to the `libcamerasrc` plugin of Gstreamer (gst-launch-1.0), specifying which camera to use. If you have multiple cameras, you can specify them in this way. You can also pass the `camera-name` directly without setting the variable CAMERA0.
4. Camera capture + image processing execution
4.1 Camera Capture + Image Processing in Python
Next, create the following text file and save it as run-opencv.py.
import os
import cv2
os.environ["LIBCAMERA_IPA_MODULE_PATH"] = "/usr/lib/libcamera/ipa-nxp-neo-uguzzi/"
os.environ["LIBCAMERA_PIPELINES_MATCH_LIST"] = "nxp/neo,imx8-isi,uvc"
CAMERANAME = r"/base/soc/bus@42000000/i2c@42540000/os08a20_mipi@36"
pipeline = (
f'libcamerasrc camera-name="{CAMERANAME}" ! '
'video/x-raw,width=3840,height=2160,framerate=30/1,format=YUY2 ! '
'imxvideoconvert_g2d ! '
'video/x-raw,width=1280,height=720,framerate=30/1,format=BGRA ! '
'appsink drop=true max-buffers=1'
)
cap = cv2.VideoCapture(pipeline, cv2.CAP_GSTREAMER)
if not cap.isOpened():
print("cannot open camera")
exit()
while True:
ret, frame = cap.read()
if not ret:
break
# BGRA -> BGR に変.してから処理
frame_bgr = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
# エッジ強調処理
gray = cv2.cvtColor(frame_bgr, cv2.COLOR_BGR2GRAY)
laplacian = cv2.Laplacian(gray, cv2.CV_64F, ksize=5)
edge = cv2.convertScaleAbs(laplacian)
edge_bgr = cv2.cvtColor(edge, cv2.COLOR_GRAY2BGR)
result = cv2.addWeighted(frame_bgr, 1.0, edge_bgr, 0.5, 0)
cv2.imshow('Edge Enhanced', result)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cap.release()
cv2.destroyAllWindows()
To do this, do the following:
python3 run-opencv.py
4.2 Code Explanation
This sample uses Python and the OpenCV API. OpenCV has a mechanism for receiving data from Gsteamer pipelines, and this is utilized in the example.
shigenobukatagi_0-1776220175808.png
As shown, we are configuring the Gstmeamer pipeline using pipeline. The purpose of resizing is to improve the frame rate by reducing the CPU processing load in subsequent stages. The purpose of the format conversion is to convert to BGR, a format that OpenCV can use. These processes are performed on 2D GPUs to reduce CPU load. A simplified diagram of the pipeline is shown below.
shigenobukatagi_0-1776647464589.png
shigenobukatagi_1-1776220418672.png
This is frame-by-frame processing. It receives one frame at a time from the pipeline configured in Gstmeamer and passes it on to the subsequent edge enhancement processing.
In this way, the process is divided into two parts: the initial stage, which heavily relies on the SoC hardware (libcamerasrc (MIPI-CSI + ISP) → imxvideoconvert_g2d (GPU 2D)), is performed by Gstreamer, and the subsequent stage involves edge enhancement using the CPU/OpenCV. Since images can be extracted frame by frame with cap.read(), subsequent processing becomes easier.
In conclusion
We've shown you two examples of how to implement camera-based applications using the FRDM-IMX95 board.
Use cases where acquired image frames are input into an AI model will be introduced in a separate article.
*This article includes content that has been reviewed by the author based on AI-generated code.
=========================
We are currently unable to respond to comments left in the " Comment " section of this post . We apologize for the inconvenience, but please refer to " Technical Questions to NXP - How to Contact Us( Japanese Blog) " when making inquiries.(If you are already an NXP distributor or have a relationship with NXP, you may ask your representative directly.) Let's try moving the camera using the FRDM-IMX95 board. Gstreamer Python/OpenCV We will implement these two methods. I am using Linux BSP 6.18.2_1.0.0.
(Estimated time: 10 minutes) *Assuming the Linux image has been successfully written to the FRDM-IMX95. i.MX Processors Japanese Blog
View full article