118 lines
4.6 KiB
Python
118 lines
4.6 KiB
Python
"""
|
|
Camera
|
|
|
|
MicroPython library for the Camera(Inherit C module)
|
|
=======================================================
|
|
@dahanzimin From the Mixly Team
|
|
"""
|
|
import time, gc
|
|
import urequests
|
|
from _camera import *
|
|
from base64 import b64encode
|
|
from machine import SoftI2C, Pin
|
|
from jpeg import Encoder, Decoder
|
|
|
|
class IMG:
|
|
def __init__(self, image, width, height):
|
|
self.image = image
|
|
self.width = width
|
|
self.height = height
|
|
self.format = "RGB565"
|
|
|
|
class Camera(Camera):
|
|
def __init__(self, frame_size=FrameSize.R240X240, pixel_format=PixelFormat.RGB565, skip_frame=3, hmirror=False, vflip=False, **kwargs):
|
|
from mixgo_sant import onboard_bot
|
|
onboard_bot.cam_reset(1, 0)
|
|
onboard_bot.cam_en(1, 150)
|
|
super().__init__(frame_size=frame_size, pixel_format=pixel_format, **kwargs)
|
|
self.set_hmirror(not hmirror)
|
|
time.sleep_ms(150)
|
|
self.set_vflip(not vflip)
|
|
SoftI2C(scl=Pin(47), sda=Pin(48), freq=400000) # 恢复I2C
|
|
for _ in range(skip_frame):
|
|
super().capture()
|
|
|
|
def deinit(self):
|
|
super().deinit()
|
|
gc.collect()
|
|
onboard_bot.cam_reset(0, 0)
|
|
onboard_bot.cam_en(0, 100)
|
|
|
|
def snapshot(self, path=None, quality=90, rotation=0):
|
|
if path is None:
|
|
return self.capture()
|
|
else:
|
|
Image.save(self.capture(), path, quality=quality, rotation=rotation)
|
|
|
|
def capture(self):
|
|
return IMG(super().capture(), self.get_pixel_width(), self.get_pixel_height())
|
|
|
|
class Image:
|
|
def save(self, img, path="mixly.jpg", **kwargs):
|
|
'''quality(1-100), rotation (0, 90, 180, 270)'''
|
|
_encoder = Encoder(pixel_format="RGB565_BE", width=img.width, height=img.height, **kwargs)
|
|
_jpeg = _encoder.encode(img.image)
|
|
del _encoder
|
|
gc.collect()
|
|
if isinstance(path, str):
|
|
with open(path, 'wb') as f:
|
|
f.write(_jpeg)
|
|
else:
|
|
return _jpeg
|
|
|
|
def open(self, path="mixly.jpg", scale_width=None, scale_height=None, tft_width=240, tft_height=240, **kwargs):
|
|
'''rotation (0, 90, 180, 270), clipper_width, clipper_height'''
|
|
with open(path, "rb") as f:
|
|
_jpeg = f.read()
|
|
return self._jpg_decoder(_jpeg, scale_width, scale_height, tft_width, tft_height, **kwargs)
|
|
|
|
def convert(self, img, formats=0, **kwargs):
|
|
if formats == 0:
|
|
return self.save(img, None, **kwargs)
|
|
elif formats == 1:
|
|
return b'data:image/jpg;base64,' + b64encode(self.save(img, None, **kwargs))
|
|
|
|
def download(self, url, path=None, scale_width=None, scale_height=None, tft_width=240, tft_height=240, block=1024, **kwargs):
|
|
'''rotation (0, 90, 180, 270), clipper_width, clipper_height'''
|
|
response = urequests.get(url, stream=True)
|
|
if path is None:
|
|
_image = self._jpg_decoder(response.raw.read(), scale_width, scale_height, tft_width, tft_height, **kwargs)
|
|
response.close()
|
|
return _image
|
|
else:
|
|
with open(path, 'wb') as f:
|
|
while True:
|
|
_data = response.raw.read(block)
|
|
if not _data:
|
|
break
|
|
else:
|
|
f.write(_data)
|
|
response.close()
|
|
|
|
def _jpg_decoder(self, jpg, scale_width, scale_height, tft_width, tft_height, **kwargs):
|
|
'''Automatically zoom based on the screen'''
|
|
if scale_width is None or scale_height is None:
|
|
_width = tft_width
|
|
_height = tft_height
|
|
for i in range(min(len(jpg), 1024)):
|
|
if jpg[i] == 0xFF and (jpg[i + 1] & 0xF0) == 0xC0:
|
|
if jpg[i + 1] not in [0xC4, 0xC8, 0xCC]:
|
|
_width = jpg[i + 7] << 8 | jpg[i + 8]
|
|
_height = jpg[i + 5] << 8| jpg[i + 6]
|
|
break
|
|
if _width > tft_width or _height > tft_height:
|
|
_scale = max(_width / tft_width, _height / tft_height) * 8
|
|
_decoder = Decoder(pixel_format="RGB565_BE", scale_width=round(_width / _scale) * 8, scale_height=round(_height / _scale) * 8, **kwargs)
|
|
else:
|
|
_decoder = Decoder(pixel_format="RGB565_BE", **kwargs)
|
|
else:
|
|
_decoder = Decoder(pixel_format="RGB565_BE", scale_width=scale_width // 8 * 8, scale_height=scale_height // 8 * 8, **kwargs)
|
|
_info = _decoder.get_img_info(jpg)
|
|
_image = IMG(_decoder.decode(jpg), _info[0], _info[1])
|
|
del _decoder, jpg
|
|
gc.collect()
|
|
return _image
|
|
|
|
#图像处理
|
|
Image = Image()
|