Skip to content
This repository has been archived by the owner on Jan 20, 2024. It is now read-only.

Commit

Permalink
[_maix_vivo] fix 320x240 for maix smart.
Browse files Browse the repository at this point in the history
  • Loading branch information
junhuanchen committed May 20, 2022
1 parent c4f408d commit d681dde
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 238 deletions.
89 changes: 47 additions & 42 deletions ext_modules/_maix_vivo/_maix_vivo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -160,17 +160,17 @@ class _v83x_vivo
public:
void set(py::bytes &bytes)
{
frame_t *frame = this->ui;
frame_t *ui = this->ui;
std::string value = static_cast<std::string>(bytes);
void *tmp = this->vo->get_frame(this->vo, VO_UI);
if (tmp != NULL)
{
const int frame_size = frame->size.w * frame->size.h;
const int frame_size = ui->size.w * ui->size.h;
if (frame_size * 4 == value.length())
{
// puts("rgba");
// rgba > abgr > argb
uint32_t *argb = (uint32_t *)frame->buf, *abgr = (uint32_t *)value.c_str();
uint32_t *argb = (uint32_t *)ui->buf, *abgr = (uint32_t *)value.c_str();
for (int i = 0, sum = frame_size; i != sum; i++)
{
argb[i] = (abgr[i] & 0xFF000000) | // ______AA
Expand All @@ -183,7 +183,7 @@ class _v83x_vivo
{
// puts("rgb");
// rgb > argb
uint32_t *argb = (uint32_t *)frame->buf;
uint32_t *argb = (uint32_t *)ui->buf;
uint8_t *rgb = (uint8_t *)value.c_str();
for (int i = 0, sum = frame_size; i != sum; i++)
{
Expand All @@ -197,30 +197,31 @@ class _v83x_vivo
{
return;
}
// memcpy(frame->buf, value.c_str(), frame_size); // bgra
// printf("[set] ui->ion %d this->vo_dir %d \r\n", ui->ion, this->vo_dir);
// memcpy(ui->buf, value.c_str(), frame_size); // bgra
uint32_t *phy = NULL, *vir = NULL;
this->vo->frame_addr(this->vo, tmp, &vir, &phy);
if (this->vo_dir)
{
if (frame->ion)
if (ui->ion)
{
_g2d_argb_rotate((void *)frame_phy(frame->buf), (void *)phy[0], frame->size.w, frame->size.h, this->vo_dir);
// printf("[set] ui->size.w %d ui->size.h %d \r\n", ui->size.w, ui->size.h);
_g2d_argb_rotate((void *)frame_phy(ui->buf), (void *)phy[0], ui->size.w, ui->size.h, this->vo_dir);
}
else
{
g2d_argb_rotate((uint32_t *)frame->buf, (void *)phy[0], frame->size.w, frame->size.h, this->vo_dir);
g2d_argb_rotate((uint32_t *)ui->buf, (void *)phy[0], ui->size.w, ui->size.h, this->vo_dir);
}
}
else
{
memcpy((uint8_t *)vir[0], frame->buf, frame->size.w * frame->size.h * 4);
memcpy((uint8_t *)vir[0], ui->buf, ui->size.w * ui->size.h * 4);
}
this->vo->set_frame(this->vo, tmp, VO_UI);

}
}

py::list get(bool show=true)
py::list get(bool show=false, bool more=false)
{
py::list result; // l.attr("pop")();
if (LIBMAIX_ERR_NONE == this->vi[0]->capture(this->vi[0], (uint8_t *)this->fm[0]->buf))
Expand All @@ -235,6 +236,7 @@ class _v83x_vivo
this->vo->frame_addr(this->vo, tmp, &vir, &phy);
if (this->vo_dir)
{
// printf("[get] frame->ion %d this->vo_dir %d \r\n", frame->ion, this->vo_dir);
if (frame->ion)
{
const int _w_h_ = frame->size.w * frame->size.h; //ALIGN(w, 16) * ALIGN(h, 16);
Expand Down Expand Up @@ -266,24 +268,26 @@ class _v83x_vivo
result.append(py::bytes((char *)this->y2r[0]->data, this->yuv2rgb->height * this->yuv2rgb->width * 3));
if (LIBMAIX_ERR_NONE == this->vi[1]->capture(this->vi[1], (uint8_t *)this->fm[1]->buf))
{
frame_t *frame = this->fm[1];
if (this->ai_dir)
{
g2d_nv21_rotate((uint8_t *)frame->buf, frame->size.w, frame->size.h, this->ai_dir);
this->yuv2rgb->width = this->fm[1]->size.h;
this->yuv2rgb->height = this->fm[1]->size.w;
}
else
{
this->yuv2rgb->width = this->fm[1]->size.w;
this->yuv2rgb->height = this->fm[1]->size.h;
}
this->yuv2rgb->data = this->fm[1]->buf;
libmaix_err_t err = this->yuv2rgb->convert(this->yuv2rgb, LIBMAIX_IMAGE_MODE_RGB888, &this->y2r[1]);
if (err == LIBMAIX_ERR_NONE)
{
result.append(py::bytes((char *)this->y2r[1]->data, this->yuv2rgb->height * this->yuv2rgb->width * 3));
// CALC_FPS("get");
if (more) {
frame_t *frame = this->fm[1];
if (this->ai_dir)
{
g2d_nv21_rotate((uint8_t *)frame->buf, frame->size.w, frame->size.h, this->ai_dir);
this->yuv2rgb->width = this->fm[1]->size.h;
this->yuv2rgb->height = this->fm[1]->size.w;
}
else
{
this->yuv2rgb->width = this->fm[1]->size.w;
this->yuv2rgb->height = this->fm[1]->size.h;
}
this->yuv2rgb->data = this->fm[1]->buf;
libmaix_err_t err = this->yuv2rgb->convert(this->yuv2rgb, LIBMAIX_IMAGE_MODE_RGB888, &this->y2r[1]);
if (err == LIBMAIX_ERR_NONE)
{
result.append(py::bytes((char *)this->y2r[1]->data, this->yuv2rgb->height * this->yuv2rgb->width * 3));
// CALC_FPS("get");
}
}
}
}
Expand All @@ -297,6 +301,7 @@ class _v83x_vivo
// // save buffer used default 3 3
// extern uint8_t libmaix_cam_vovi_bufmax, libmaix_cam_voui_bufmax;
// libmaix_cam_vovi_bufmax = 3, libmaix_cam_voui_bufmax = 3;
// printf("[_v83x_vivo] %d %d %d %d %d %d \r\n", vi_w, vi_h, ai_w, ai_h, vo_dir, ai_dir);
init(vi_w, vi_h, ai_w, ai_h, vo_dir, ai_dir);
}

Expand Down Expand Up @@ -354,11 +359,11 @@ class _v83x_vivo
if (NULL == this->vi[1])
return exit();

// if (this->ai_dir % 2 == 1)
// {
// int tmp = ai_w;
// ai_w = ai_h, ai_h = tmp;
// }
if (this->ai_dir % 2 == 1)
{
int tmp = ai_w;
ai_w = ai_h, ai_h = tmp;
}

this->fm[1] = frame_new(VI_YUV420, {0, 0, ai_w, ai_h}, 0);
if (NULL == this->fm[1])
Expand All @@ -368,20 +373,20 @@ class _v83x_vivo
return exit();
this->vi[1]->start_capture(this->vi[1]);

int _w = vi_w, _h = vi_h;
int ui_w = vi_w, ui_h = vi_h;

if (this->vo_dir % 2 == 1)
{
int tmp = vi_w;
vi_w = vi_h, vi_h = tmp;
ui_w = vi_h, ui_h = vi_w;
}

// vi 320*240 > 90 > 240*320 => vo 240*320
// printf("[init] ui_w %d ui_h %d \r\n", ui_w, ui_h);
this->ui = frame_new(VI_ARGB8888, (rect_size_t){0, 0, vi_w, vi_h}, this->vo_dir);
if (NULL == this->ui)
return exit();

this->vo = libmaix_vo_create(vi_w, vi_h, 0, 0, _w, _h);
this->vo = libmaix_vo_create(ui_w, ui_h, 0, 0, ui_w, ui_h);
if (NULL == this->vo)
return exit();

Expand Down Expand Up @@ -409,8 +414,8 @@ class _v83x_vivo
libmaix_image_destroy(&this->yuv2rgb);
if (NULL != this->vo)
libmaix_vo_destroy(&this->vo);
libmaix_camera_module_deinit();
usleep(200000); // wait 1s to deinit
// libmaix_camera_module_deinit();
// usleep(200000); // wait 1s to deinit
libmaix_image_module_deinit();
libmaix_camera_module_deinit();
this->inited = false;
Expand All @@ -428,8 +433,8 @@ PYBIND11_MODULE(_maix_vivo, m)
{
pybind11::class_<_v83x_vivo>(m, "_v83x_vivo")
.def(pybind11::init<int, int, int, int, int, int>(),
py::arg("vi_w") = 240, py::arg("vi_h") = 240, py::arg("ai_w") = 192, py::arg("ai_h") = 128, py::arg("vo_dir") = 0, py::arg("ai_dir") = 0)
.def("get", &_v83x_vivo::get, py::arg("show") = 1)
py::arg("vi_w") = 240, py::arg("vi_h") = 240, py::arg("ai_w") = 224, py::arg("ai_h") = 224, py::arg("vo_dir") = 0, py::arg("ai_dir") = 0)
.def("get", &_v83x_vivo::get, py::arg("show") = false, py::arg("more") = false)
.def("resize", &_v83x_vivo::resize, py::arg("w") = 240, py::arg("h") = 240, py::arg("i") = 1)
.def("set", &_v83x_vivo::set);
}
137 changes: 78 additions & 59 deletions maix/camera.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,44 @@
from typing import Tuple
from .video import MaixVideo

class MaixVideo():

def __init__(self):
self.cam, self._width, self._height = None, 0, 0

def width(self):
return self._width

def height(self):
return self._height

def write(self):
pass # for file

def read(self):
return b'\xFF\x00\x00' * (self._width * self._height)

def config(self, size):
# print("MaixVideo", size)
self._width, self._height = size[0], size[1]

def capture(self, pillow=False):
tmp = self.read()
if tmp:
try:
if pillow == False:
from maix import image
return image.Image().load(tmp, (self._width, self._height), "RGB")
except Exception as e:
pass
try:
from PIL import Image
return Image.frombytes("RGB", (self._width, self._height), tmp)
except Exception as e:
pass
return None

def close(self):
self.__del__()


camera = MaixVideo()

Expand All @@ -9,48 +48,42 @@
from maix import display, image
from _maix_vivo import _v83x_vivo
class V831VivoMaixVideo(MaixVideo):
def __init__(self, source="/v831"):
def __init__(self, source="allwinner mpp"):
self.source = source
self.cam = None
self._width, self._height = (0, 0)

def config(self, size=(display.__width__, display.__height__), _vo_dir=1, _ai_dir=1):
self._vo_dir = self._ai_dir = 0
super(V831VivoMaixVideo, self).__init__()
if display.width() < display.height(): # 240 x 320 to 320 x 240
# maix-smart or other display.config 240 x 320 => 320 x 240
display.config(size=(display.height(), display.width()))
self._vo_dir = self._ai_dir = 3 # -90 rotate show
self.config() # for maix smart

def config(self, size=None, _ai_size=(224, 224)):
if size == None:
size = (display.width(), display.height())
super(V831VivoMaixVideo, self).config(size)
if self.cam == None:
super(V831VivoMaixVideo, self).__init__(size)
try:
# from PIL import Image
self.cam = _v83x_vivo(display.__width__, display.__height__, self.width(), self.height(), vo_dir = _vo_dir, ai_dir = _ai_dir)
display.__display__ = image.Image().new(mode="RGBA", size=(display.__width__, display.__height__), color=(0, 0, 0, 0))
display.__fastview__ = self.cam
def __new_draw__(img):
if isinstance(img, bytes):
# print('V831VivoMaixVideo', display.__width__, display.__height__, self.width(), self.height())
display.__fastview__.set(img)
display.__draw__ = __new_draw__
except ModuleNotFoundError as e:
pass
except Exception as e:
pass

print('[camera] config input size(%d, %d)' %
(self.width(), self.height()))
self.cam = _v83x_vivo(display.width(), display.height(), _ai_size[0], _ai_size[1], vo_dir = self._vo_dir, ai_dir = self._ai_dir)
display.__display__ = image.new(mode="RGBA", size=size, color=(0, 0, 0, 0))
display.__fastview__ = self.cam
def __new_draw__(img):
if isinstance(img, bytes):
display.__fastview__.set(img)
display.__draw__ = __new_draw__
else:
self._width, self._height = size
self.cam.resize(size[0], size[1])
print('[camera] config input size(%d, %d)' %
(self.width(), self.height()))

def read(self, video_num=1, show=False, skip_frame=8):
def read(self, video_num=0, show=False, skip_frame=8):
if self.cam == None:
print('[camera] run config(size=(w, h)) before capture.')
self.config()
for i in range(skip_frame):
frame = self.cam.get(False)
if self.cam:
if self.cam: # allow bytes 240*240*3, bytes 224*224*3
frame = self.cam.get(show)
if len(frame) == 2:
return frame[video_num] # bytes 240*240*3, bytes 224*224*3
# try again if fail
frame = self.cam.get(show)
if len(frame) == 2:
if len(frame) > 0:
return frame[video_num]
return None

Expand All @@ -67,20 +100,21 @@ def __del__(self):

class SpMaixVideo(MaixVideo):

def __init__(self, source="/dev/video"):
def __init__(self, source="/dev/videoX"):
self.source = source
self.cam = None
self._width, self._height = (0, 0)
super(SpMaixVideo, self).__init__()

def config(self, size=None, video=0, horizontal=1, vertical=1):
if size == None:
from maix import display
size = (display.width(), display.height())
super(SpMaixVideo, self).config(size)
if self.cam == None:
if size == None:
from maix import display
size = (display.__width__, display.__height__)
super(SpMaixVideo, self).__init__(size)
self.cam = Camera(self.width(), self.height(), video, horizontal, vertical)
print('[camera] config input size(%d, %d, %d)' %
(self.width(), self.height(), video))
else:
pass
print('[camera] config input size(%d, %d, %d)' %
(self.width(), self.height(), video))

def read(self):
if self.cam == None:
Expand All @@ -106,15 +140,14 @@ class CvMaixVideo(MaixVideo):

def __init__(self, source=0):
self.source = source
self.cam = None
self._width, self._height = (0, 0)
super(CvMaixVideo, self).__init__()

def config(self, size=(640, 480), source=None):
if self.cam == None:
super(CvMaixVideo, self).__init__(size)
if source:
self.source = source
self.cam = VideoCapture(self.source)
super(CvMaixVideo, self).config(size)
print('[camera] config input size(%s, %d, %d)' %
(self.source, self.width(), self.height()))

Expand Down Expand Up @@ -144,17 +177,3 @@ def __del__(self):
height = camera.height
width = camera.width
close = camera.close

if __name__ == '__main__':
camera.config((224, 224))
from maix import display
display.clear((255, 0, 0))
display.show(camera.capture())
# tmp = camera.read()
# import _maix
# frame = _maix.rgb2jpg(camera.rgbbuf, camera.width, camera.height)
# print(len(frame) // 1024, camera.width, camera.height)
# from PIL import Image
# from io import BytesIO
# img = Image.open(BytesIO(frame))
# img.show()
Loading

0 comments on commit d681dde

Please sign in to comment.