MaixCAM MaixPy Use OpenCV
Introduction
For MaixCAM, since it uses Linux and the performance can support using the Python version of OpenCV, you can use the cv2 module directly in addition to the maix module.
The examples in this article and more can be found in MaixPy/examples/vision/opencv.
Note that OpenCV functions are basically CPU-calculated. If you can use maix modules, try not to use OpenCV, because many maix functions are hardware-accelerated.
Converting between Numpy/OpenCV and maix.image.Image Formats
You can convert maix.image.Image object to a numpy array, which can then be used by libraries such as numpy and opencv:
from maix import image, time, display, app
disp = display.Display()
while not app.need_exit():
img = image.Image(320, 240, image.Format.FMT_RGB888)
img.draw_rect(0, 0, 100, 100, image.COLOR_RED, thickness=-1)
t = time.ticks_ms()
img_bgr = image.image2cv(img, ensure_bgr=True, copy=True)
img2 = image.cv2image(img_bgr, bgr=True, copy=True)
print("time:", time.ticks_ms() - t)
print(type(img_bgr), img_bgr.shape)
print(type(img2), img2)
print("")
disp.show(img2)
The previous program is slower because each conversion involves a memory copy. Below is an optimized version for better performance. However, it is not recommended to use this unless you are aiming for extreme speed, as it is prone to errors:
from maix import image, time, display, app
disp = display.Display()
while not app.need_exit():
img = image.Image(320, 240, image.Format.FMT_RGB888)
img.draw_rect(0, 0, 100, 100, image.COLOR_RED, thickness=-1)
t = time.ticks_ms()
img_rgb = image.image2cv(img, ensure_bgr=False, copy=False)
img2 = image.cv2image(img_rgb, bgr=False, copy=False)
print("time:", time.ticks_ms() - t)
print(type(img_rgb), img_rgb.shape)
print(type(img2), img2)
disp.show(img2)
- In
img_rgb = image.image2cv(img, ensure_bgr=False, copy=False),img_rgbdirectly uses the data fromimgwithout creating a memory copy. Note that the obtainedimg_rgbis anRGBimage. Since OpenCV APIs assume the image isBGR, you need to be careful when using OpenCV APIs to process the image. If you are not sure, setensure_bgrtoTrue. - In
img2 = image.cv2image(img_rgb, bgr=False, copy=False), settingcopytoFalsemeansimg2directly uses the memory ofimg_rgbwithout creating a new memory copy, resulting in faster performance. However, be cautious becauseimg_rgbmust not be destroyed beforeimg2finishes using it; otherwise, the program will crash. - Note that since memory is borrowed, modifying the converted image will also affect the original image.
Load an Image
import cv2
file_path = "/maixapp/share/icon/detector.png"
img = cv2.imread(file_path)
print(img)
Since the cv2 module is quite large, import cv2 may take some time.
Display Image on Screen
To display an image on the screen, convert it to a maix.image.Image object and then use display to show it:
from maix import display, image, time
import cv2
disp = display.Display()
file_path = "/maixapp/share/icon/detector.png"
img = cv2.imread(file_path)
img_show = image.cv2image(img)
disp.show(img_show)
while not app.need_exit():
time.sleep(1)
Use OpenCV Functions
For example, edge detection:
Based on the code above, use the cv2.Canny function:
from maix import image, display, app, time
import cv2
file_path = "/maixapp/share/icon/detector.png"
img0 = cv2.imread(file_path)
disp = display.Display()
while not app.need_exit():
img = img0.copy()
# canny method
t = time.ticks_ms()
edged = cv2.Canny(img, 180, 60)
t2 = time.ticks_ms() - t
# show by maix.display
t = time.ticks_ms()
img_show = image.cv2image(edged)
print(f"edge time: {t2}ms, convert time: {time.ticks_ms() - t}ms")
disp.show(img_show)
Use Camera
On a PC, we use OpenCV's VideoCapture class to read from the camera. For MaixCAM, OpenCV does not support this directly, so we use the maix.camera module to read from the camera and then use it with OpenCV.
Convert a maix.image.Image object to a numpy.ndarray object using the image.image2cv function:
from maix import image, display, app, time, camera
import cv2
disp = display.Display()
cam = camera.Camera(320, 240, image.Format.FMT_BGR888)
while not app.need_exit():
img = cam.read()
# convert maix.image.Image object to numpy.ndarray object
t = time.ticks_ms()
img = image.image2cv(img, ensure_bgr=False, copy=False)
print("time: ", time.ticks_ms() - t)
# canny method
edged = cv2.Canny(img, 180, 60)
# show by maix.display
img_show = image.cv2image(edged, bgr=True, copy=False)
disp.show(img_show)
Read USB camera
First, in the development board settings, select USB Mode under USB Settings and set it to HOST mode. If there is no screen available, you can use the examples/tools/maixcam_switch_usb_mode.py script to set it.
from maix import image, display, app
import cv2
import sys
cap = cv2.VideoCapture(0)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
# cap.set(cv2.CAP_PROP_CONVERT_RGB, 0)
disp = display.Display()
if not cap.isOpened():
print("无法打开摄像头")
sys.exit(1)
print("开始读取")
while not app.need_exit():
ret, frame = cap.read()
if not ret:
print("无法读取帧")
break
img = image.cv2image(frame, bgr=True, copy=False)
disp.show(img)