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_rgb
directly uses the data fromimg
without creating a memory copy. Note that the obtainedimg_rgb
is anRGB
image. 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_bgr
toTrue
. - In
img2 = image.cv2image(img_rgb, bgr=False, copy=False)
, settingcopy
toFalse
meansimg2
directly uses the memory ofimg_rgb
without creating a new memory copy, resulting in faster performance. However, be cautious becauseimg_rgb
must not be destroyed beforeimg2
finishes 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)