1450 lines
39 KiB
Python
1450 lines
39 KiB
Python
# -*- coding: utf-8 -*-
|
|
import numpy as np
|
|
import os
|
|
import math
|
|
from PIL import Image
|
|
from . import io
|
|
from . import utils
|
|
from . import general_funcs as funcs
|
|
from .IE import IE
|
|
from .inproc_520 import inproc_520_flow
|
|
from .inproc_720 import inproc_720_flow
|
|
|
|
DEFAULT = None
|
|
default = {
|
|
'color':{
|
|
'type':'float',
|
|
},
|
|
'crop':{
|
|
'type':'float',
|
|
'align_w_to_4':False,
|
|
},
|
|
'resize':{
|
|
'type':'float',
|
|
},
|
|
'pad':{
|
|
'type':'float',
|
|
},
|
|
'similarity_transform':{
|
|
'type':'float',
|
|
},
|
|
'warpAffine':{
|
|
'type':'float',
|
|
}
|
|
}
|
|
|
|
def set_default_as_520():
|
|
"""
|
|
Set some default parameter as 520 setting
|
|
|
|
Settings
|
|
----------
|
|
color.type = '520'
|
|
|
|
crop.type = '520'
|
|
|
|
crop.align_w_to_4 = True
|
|
|
|
resize.type = '520'
|
|
|
|
pad.type = '520'
|
|
|
|
warpAffine.type = 'fx'
|
|
"""
|
|
global default
|
|
default['color']['type'] = '520'
|
|
default['crop']['type'] = '520'
|
|
default['crop']['align_w_to_4'] = True
|
|
default['resize']['type'] = '520'
|
|
default['pad']['type'] = '520'
|
|
default['similarity_transform']['type'] = 'fx'
|
|
default['warpAffine']['type'] = 'fx'
|
|
return
|
|
|
|
def set_default_as_720():
|
|
"""
|
|
Set some default parameter as 720 setting
|
|
|
|
Settings
|
|
----------
|
|
color.type = '720'
|
|
|
|
crop.type = '720'
|
|
|
|
crop.align_w_to_4 = True
|
|
|
|
resize.type = '720'
|
|
|
|
pad.type = '720'
|
|
|
|
warpAffine.type = 'fx'
|
|
"""
|
|
global default
|
|
default['color']['type'] = '720'
|
|
default['crop']['type'] = '720'
|
|
default['crop']['align_w_to_4'] = True
|
|
default['resize']['type'] = '720'
|
|
default['pad']['type'] = '720'
|
|
default['similarity_transform']['type'] = 'fx'
|
|
default['warpAffine']['type'] = 'fx'
|
|
return
|
|
|
|
def set_default_as_IE():
|
|
"""
|
|
Set some default parameter as IE setting
|
|
|
|
Settings
|
|
----------
|
|
color.type = 'IE'
|
|
|
|
crop.type = 'IE'
|
|
|
|
crop.align_w_to_4 = False
|
|
|
|
resize.type = 'IE'
|
|
|
|
pad.type = 'IE'
|
|
|
|
warpAffine.type = 'IE'
|
|
"""
|
|
global default
|
|
default['color']['type'] = 'IE'
|
|
default['crop']['type'] = 'IE'
|
|
default['crop']['align_w_to_4'] = False
|
|
default['resize']['type'] = 'IE'
|
|
default['pad']['type'] = 'IE'
|
|
default['similarity_transform']['type'] = 'fx'
|
|
default['warpAffine']['type'] = 'IE'
|
|
return
|
|
|
|
def set_default_as_floating():
|
|
"""
|
|
Set some default parameter as floating setting
|
|
|
|
Settings
|
|
----------
|
|
color.type = 'float'
|
|
|
|
crop.type = 'float'
|
|
|
|
crop.align_w_to_4 = False
|
|
|
|
resize.type = 'float'
|
|
|
|
pad.type = 'float'
|
|
|
|
warpAffine.type = 'float'
|
|
"""
|
|
global default
|
|
default['color']['type'] = 'float'
|
|
default['crop']['type'] = 'float'
|
|
default['crop']['align_w_to_4'] = False
|
|
default['resize']['type'] = 'float'
|
|
default['pad']['type'] = 'float'
|
|
default['similarity_transform']['type'] = 'float'
|
|
default['warpAffine']['type'] = 'float'
|
|
return
|
|
|
|
def set_default_as_floating_pillow():
|
|
"""
|
|
Set some default parameter as floating setting
|
|
|
|
Settings
|
|
----------
|
|
color.type = 'float'
|
|
|
|
crop.type = 'float'
|
|
|
|
crop.align_w_to_4 = False
|
|
|
|
resize.type = 'bilinear_pillow'
|
|
|
|
pad.type = 'float'
|
|
|
|
warpAffine.type = 'float'
|
|
"""
|
|
global default
|
|
default['color']['type'] = 'float'
|
|
default['crop']['type'] = 'float'
|
|
default['crop']['align_w_to_4'] = False
|
|
default['resize']['type'] = 'bilinear_pillow'
|
|
default['pad']['type'] = 'float'
|
|
default['similarity_transform']['type'] = 'float'
|
|
default['warpAffine']['type'] = 'float'
|
|
return
|
|
|
|
def print_info_on():
|
|
"""
|
|
turn print infomation on.
|
|
"""
|
|
pass
|
|
|
|
def print_info_off():
|
|
"""
|
|
turn print infomation off.
|
|
"""
|
|
pass
|
|
|
|
def load_image(image):
|
|
"""
|
|
load_image function
|
|
load load_image and output as rgb888 format np.array
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray / str
|
|
Input, can be np.array or image file path
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
Output image in rgb888 format.
|
|
|
|
Examples
|
|
----------
|
|
"""
|
|
if isinstance(image, np.ndarray):
|
|
pass
|
|
elif isinstance(image, str):
|
|
image = Image.open(image)
|
|
if image.mode == "I":
|
|
image = np.array(image)
|
|
else:
|
|
image = image.convert("RGB")
|
|
image = np.array(image).astype('uint8')
|
|
|
|
assert isinstance(image, np.ndarray)
|
|
return image
|
|
|
|
def load_bin(image, fmt=None, size=None, output_fmt='RGB', order=None, **kwargs):
|
|
"""
|
|
load_bin function
|
|
load bin file and output as rgb888 format np.array
|
|
|
|
Parameters
|
|
----------
|
|
image : str,
|
|
Bin file path.
|
|
|
|
fmt : str
|
|
"rgb888" / "yuv444" / "ycbcr444" / "yuv422" / "ycbcr422" / "rgb565"
|
|
|
|
size : tuple
|
|
1x2 array, (image_w, image_h).
|
|
|
|
order : int
|
|
image order.
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
Output image in rgb888 format.
|
|
|
|
Examples:
|
|
----------
|
|
>>> image_data = kp.load_bin(image,'rgb565',(raw_w,raw_h))
|
|
"""
|
|
assert isinstance(size, tuple)
|
|
assert isinstance(fmt, str)
|
|
|
|
image = io.load_bin(input_file=image, src_w=size[0], src_h=size[1], image_fmt=fmt, order=order)
|
|
image = funcs.color_convert(image, input_fmt=fmt, output_fmt=output_fmt)
|
|
return image
|
|
|
|
def load_hex(image, fmt=None, size=None, output_fmt='RGB', **kwargs):
|
|
"""
|
|
load_hex function
|
|
load hex file and output as rgb888 format np.array
|
|
|
|
Parameters
|
|
----------
|
|
image : str
|
|
Hex file path.
|
|
|
|
fmt : str
|
|
"rgb888" / "yuv444" / "ycbcr444" / "yuv422" / "ycbcr422" / "rgb565"
|
|
|
|
size : tuple
|
|
1x2 array, (image_w, image_h).
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
Output image in rgb888 format.
|
|
|
|
Examples:
|
|
----------
|
|
>>> image_data = kp.load_hex(image,'rgb565',(raw_w,raw_h))
|
|
"""
|
|
assert isinstance(size, tuple)
|
|
assert isinstance(fmt, str)
|
|
|
|
image = io.load_hex(input_file=image, src_w=size[0], src_h=size[1], image_fmt=fmt)
|
|
image = funcs.color_convert(image=image, input_fmt=fmt, output_fmt=output_fmt)
|
|
return image
|
|
|
|
def dump_image(image, output, file_fmt='txt', image_fmt='rgb888', order=None, **kwargs):
|
|
"""
|
|
dump_image function
|
|
|
|
dump txt, bin or hex, default is txt
|
|
image format as following format: RGB888, RGBA8888, RGB565, NIR, YUV444, YCbCr444, YUV422, YCbCr422, default is RGB888
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray / str
|
|
Input image, can be np.array or image file path.
|
|
|
|
output : str
|
|
Dump file path
|
|
|
|
file_fmt : str
|
|
"bin" / "txt" / "hex", set dump file format, default is txt
|
|
|
|
image_fmt : str
|
|
RGB888 / RGBA8888 / RGB565 / NIR / YUV444 / YCbCr444 / YUV422 / YCbCr422, default is RGB888
|
|
|
|
Examples:
|
|
----------
|
|
>>> kp.dump_image(image_data,out_path,fmt='bin')
|
|
"""
|
|
if isinstance(image, str):
|
|
image = load_image(image=image)
|
|
assert isinstance(image, np.ndarray)
|
|
|
|
## if input is 1 dimension, dump directly
|
|
if(len(image.shape) == 1):
|
|
io.pack_image(image=image, file=output, pack_fmt=file_fmt)
|
|
return
|
|
|
|
## make sure input dimension more than 2
|
|
assert (len(image.shape) >= 2)
|
|
|
|
## detect input channel, to decide input image format
|
|
## hint, if channel = 3, it assume input as RGB888
|
|
if (len(image.shape) == 2):
|
|
source_format = 'L'
|
|
if (image.shape[2] == 4):
|
|
source_format = 'RGBA8888'
|
|
else:
|
|
source_format = 'RGB888'
|
|
|
|
## color_convert
|
|
image = funcs.color_convert(image=image, input_fmt=source_format, output_fmt=image_fmt)
|
|
|
|
## reorder
|
|
image_pack = io.reorder_image(image=image, image_fmt=image_fmt, order=order)
|
|
|
|
## pack_image
|
|
io.pack_image(image=image_pack, file=output, pack_fmt=file_fmt)
|
|
|
|
return
|
|
|
|
def convert(image, out_fmt='RGB888', source_fmt='RGB888', type=DEFAULT, thread='', **kwargs):
|
|
"""
|
|
color convert
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image.
|
|
|
|
out_fmt : str
|
|
"rgb888" / "rgba8888" / "nir" / "rgb565" / "yuv" / "ycbcr" / "yuv422" / "yuv420" / "ycbcr422"
|
|
|
|
source_fmt : str
|
|
"rgb888" / "rgba8888" / "nir" / "rgb565" / "yuv" / "ycbcr" / "yuv422" / "yuv420" / "ycbcr422"
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> output_image = kp.convert(image=input_image, out_fmt='RGB888', source_fmt='YCbCr422')
|
|
|
|
"""
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['color']['type']
|
|
|
|
if type.lower() in ['ie']:
|
|
ie = IE(thread=thread)
|
|
image = ie.color(image=image, input_fmt=source_fmt, output_fmt=out_fmt)
|
|
else: # float, 520, 720
|
|
image = funcs.color_convert(image=image, input_fmt=source_fmt, output_fmt=out_fmt)
|
|
|
|
return image
|
|
|
|
def get_crop_range(image, box, align_w_to_4=DEFAULT, adjust_crop_box_by_ar=False, cut_boundary=True, rounding_type=0,**kwargs):
|
|
"""
|
|
get exact crop box according different setting
|
|
|
|
Parameters
|
|
----------
|
|
box: tuple
|
|
1x4 array, (x0, y0, x1, y1).
|
|
|
|
align_w_to_4 : bool
|
|
Crop length in w direction align to 4 or not, default False.
|
|
|
|
adjust_crop_box_by_ar: bool
|
|
According box width and ar(crop_h/crop_w) to adjust bbox height, default False.
|
|
|
|
cut_boundary : bool
|
|
cut over boundary bbox or not, default True.
|
|
|
|
rounding_type: int
|
|
0 -> x0,y0 take floor, x1,y1 take ceil;
|
|
1 -> all take rounding.
|
|
|
|
Returns
|
|
----------
|
|
out : tuple
|
|
1x4 array, (x0, y0, x1, y1), new crop box.
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.get_crop_range((272,145,461,341), align_w_to_4=True, pad_square_to_4=True)
|
|
(272, 145, 460, 341)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert image.ndim >= 2
|
|
assert isinstance(box, list) | isinstance(box, tuple)
|
|
assert len(box) == 4
|
|
|
|
## if set DEFAULT
|
|
if align_w_to_4 is DEFAULT:
|
|
align_w_to_4 = default['crop']['align_w_to_4']
|
|
|
|
## rounding
|
|
box = funcs.rounding_crop_box(box=box,rounding_type=rounding_type)
|
|
|
|
## calculate ar before align to 4
|
|
ar_before_align_w_to_4 = 1.0*( box[3]-box[1] ) / ( box[2]-box[0] )
|
|
|
|
## align w to 4
|
|
if align_w_to_4:
|
|
box = funcs.align_crop_box_w_to_4(box=box,w=image.shape[1])
|
|
|
|
## adjust crop box by ar
|
|
if adjust_crop_box_by_ar:
|
|
box = funcs.adjust_crop_box_by_ar(box=box,ar=ar_before_align_w_to_4)
|
|
|
|
if cut_boundary:
|
|
w_ori=image.shape[1]
|
|
h_ori=image.shape[0]
|
|
x0 = np.clip(box[0],0,w_ori)
|
|
x1 = np.clip(box[2],0,w_ori)
|
|
y0 = np.clip(box[1],0,h_ori)
|
|
y1 = np.clip(box[3],0,h_ori)
|
|
box = [x0,y0,x1,y1]
|
|
|
|
return [int(box[0]),int(box[1]),int(box[2]),int(box[3])]
|
|
|
|
def crop(image, box, type=DEFAULT, align_w_to_4=DEFAULT, pad_square_to_4=False, rounding_type=1, thread='',**kwargs):
|
|
"""
|
|
crop function
|
|
|
|
specific crop range by box
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image.
|
|
|
|
box : tuble
|
|
1x4 array, (x0, y0, x1, y1).
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
align_w_to_4 : bool
|
|
Crop length in w direction align to 4 or not, default False.
|
|
|
|
pad_square_to_4: bool
|
|
Pad to square(align 4) or not, default False.
|
|
|
|
rounding_type: int
|
|
0 -> x0,y0 take floor, x1,y1 take ceil;
|
|
1 -> all take rounding.
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.crop(image_data,(272,145,461,341), align_w_to_4=True)
|
|
>>> image_data = kp.crop(image_data,(272,145,461,341), pad_square_to_4=True)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert image.ndim >= 2
|
|
assert isinstance(box, list) | isinstance(box, tuple)
|
|
assert len(box) == 4
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['crop']['type']
|
|
if align_w_to_4 is DEFAULT:
|
|
align_w_to_4 = default['crop']['align_w_to_4']
|
|
|
|
## rounding
|
|
box = funcs.rounding_crop_box(box=box,rounding_type=rounding_type)
|
|
|
|
## align w to 4
|
|
if align_w_to_4:
|
|
box = funcs.align_crop_box_w_to_4(box=box,w=image.shape[1])
|
|
|
|
## pad box to square
|
|
if pad_square_to_4:
|
|
box = funcs.pad_crop_box_to_square(box=box)
|
|
|
|
## crop
|
|
if type.lower() in ['ie']:
|
|
ie = IE(thread=thread)
|
|
image = ie.crop(image=image, box=box)
|
|
else: ## float, 520, 720
|
|
image = funcs.crop(image=image, box=box)
|
|
|
|
return image
|
|
|
|
def crop_center(image, range=None, type=DEFAULT, align_w_to_4=DEFAULT, pad_square_to_4=False, rounding_type=0, thread='',**kwargs):
|
|
"""
|
|
crop function
|
|
|
|
center crop by range
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image
|
|
|
|
range : tuple
|
|
1x2 array, (crop_w, crop_h).
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
align_w_to_4 : bool
|
|
Crop length in w direction align to 4 or not, default False.
|
|
|
|
pad_square_to_4: bool
|
|
Pad to square(align 4) or not, default False.
|
|
|
|
rounding_type: int
|
|
0 -> x0,y0 take floor, x1,y1 take ceil;
|
|
1 -> all take rounding.
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.crop_center(image_data,(102,40), align_w_to_4=True)
|
|
|
|
>>> image_data = kp.crop_center(image_data,(102,40), pad_square_to_4=True)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert image.ndim >= 2
|
|
assert isinstance(range, list) | isinstance(range, tuple)
|
|
assert len(range) == 2
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['crop']['type']
|
|
if align_w_to_4 is DEFAULT:
|
|
align_w_to_4 = default['crop']['align_w_to_4']
|
|
|
|
## calcuate crop box
|
|
box = funcs.calcuate_crop_box_center(image_w=image.shape[1], image_h=image.shape[0], crop_w=range[0], crop_h=range[1])
|
|
|
|
## rounding
|
|
box = funcs.rounding_crop_box(box=box,rounding_type=rounding_type)
|
|
|
|
## align w to 4
|
|
if align_w_to_4:
|
|
box = funcs.align_crop_box_w_to_4(box=box,w=image.shape[1])
|
|
|
|
## pad box to square
|
|
if pad_square_to_4:
|
|
box = funcs.pad_crop_box_to_square(box=box)
|
|
|
|
## crop
|
|
if type.lower() in ['ie']:
|
|
ie = IE(thread=thread)
|
|
image = ie.crop(image=image, box=box)
|
|
else: ## float, 520, 720
|
|
image = funcs.crop(image=image, box=box)
|
|
|
|
return image
|
|
|
|
def crop_corner(image, range=None, type=DEFAULT, align_w_to_4=DEFAULT, pad_square_to_4=False, rounding_type=0, thread='',**kwargs):
|
|
"""
|
|
crop function
|
|
|
|
corner crop by range
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image
|
|
|
|
range : tuple
|
|
1x2 array, (crop_w, crop_h).
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
align_w_to_4 : bool
|
|
Crop length in w direction align to 4 or not, default False.
|
|
|
|
pad_square_to_4: bool
|
|
Pad to square(align 4) or not, default False.
|
|
|
|
rounding_type: int
|
|
0 -> x0,y0 take floor, x1,y1 take ceil;
|
|
1 -> all take rounding.
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.crop_corner(image_data,(102,40), align_w_to_4=True)
|
|
|
|
>>> image_data = kp.crop_corner(image_data,(102,40), pad_square_to_4=True)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert image.ndim >= 2
|
|
assert isinstance(range, list) | isinstance(range, tuple)
|
|
assert len(range) == 2
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['crop']['type']
|
|
if align_w_to_4 is DEFAULT:
|
|
align_w_to_4 = default['crop']['align_w_to_4']
|
|
|
|
## calcuate crop box
|
|
box = funcs.calcuate_crop_box_corner(crop_w=range[0], crop_h=range[1])
|
|
|
|
## rounding
|
|
box = funcs.rounding_crop_box(box=box,rounding_type=rounding_type)
|
|
|
|
## align w to 4
|
|
if align_w_to_4:
|
|
box = funcs.align_crop_box_w_to_4(box=box,w=image.shape[1])
|
|
|
|
## pad box to square
|
|
if pad_square_to_4:
|
|
box = funcs.pad_crop_box_to_square(box=box)
|
|
|
|
## crop
|
|
if type.lower() in ['ie']:
|
|
ie = IE(thread=thread)
|
|
image = ie.crop(image=image, box=box)
|
|
else: ## float, 520, 720
|
|
image = funcs.crop(image=image, box=box)
|
|
|
|
return image
|
|
|
|
def calculate_keep_ratio_size(tar_size, ori_size, type=DEFAULT, pad_mode=None):
|
|
"""
|
|
resize function
|
|
|
|
calculate the resize when keep ratio
|
|
|
|
Parameters
|
|
----------
|
|
tar_size : tuple / list
|
|
1x2 array, (tar_size_w, tar_size_h)
|
|
|
|
ori_size : tuple / list
|
|
1x2 array, (ori_size_w, ori_size_h)
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
pad_mode : str
|
|
'center' / 'corner', if set type = 720, the pad_mode must be given
|
|
|
|
Returns
|
|
----------
|
|
out : list
|
|
[resize_w, resize_h]
|
|
"""
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['resize']['type']
|
|
|
|
return funcs.calculate_keep_ratio_size(tar_size=tar_size, ori_size=ori_size, platform_type=type, pad_mode=pad_mode)
|
|
|
|
def resize(image, size, keep_ratio=True, zoom=True, type=DEFAULT, return_float=False, pad_mode=None, tile_size=None,**kwargs):
|
|
"""
|
|
resize function
|
|
|
|
resize type can be float / bilinear / bilinear_pillow / bilicubic / cv2 as floating type, fixed / 520 / 720 / IE as fixed type.
|
|
|
|
520 / 720 type has add some function to simulate 520 / 720 behavior.
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image
|
|
|
|
size: tuple
|
|
1x2 array, (input_w, input_h)
|
|
|
|
keep_ratio : bool
|
|
Keep_ratio or not, default True
|
|
|
|
zoom : bool
|
|
Enable resize can zoom image or not, default True
|
|
|
|
type : str
|
|
'float'='bilinear' / 'bilinear_pillow' / '520' / '720' / 'IE' / 'bilicubic' / 'cv2' / 'fixed'
|
|
|
|
pad_mode : str
|
|
'center' / 'corner', if set type = 720 & keep_ratio = True, the pad_mode must be given
|
|
|
|
return_float : bool
|
|
return resize image as float type or not, default False
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.resize(image_data,size=(56,56),type='fixed',info_out=info)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['resize']['type']
|
|
|
|
ori_size = (image.shape[1], image.shape[0])
|
|
|
|
## calcuate keep ratio size
|
|
if keep_ratio:
|
|
size = funcs.calculate_keep_ratio_size(tar_size=size, ori_size=ori_size, platform_type=type, pad_mode=pad_mode)
|
|
|
|
## if not allow zoom, return
|
|
if not zoom:
|
|
if (size[0] > ori_size[0]) or (size[1] > ori_size[1]):
|
|
return image
|
|
|
|
## resize
|
|
if type.lower() in ['float', 'bilinear']:
|
|
image = funcs.resize_bilinear_vectorized(image=image, size=size, return_float=return_float)
|
|
elif type.lower() in ['bilinear_pillow']:
|
|
image = funcs.resize_bilinear(image=image, size=size)
|
|
elif type.lower() in ['bicubic']:
|
|
image = funcs.resize_bicubic(image=image, size=size)
|
|
elif type.lower() in ['cv2']:
|
|
image = funcs.resize_cv2(image=image, size=size)
|
|
elif type.lower() in ['fixed']:
|
|
image = funcs.resize_fixed(image=image, size=size, platform_type='general')
|
|
elif type.lower() in ['520', 'fixed_520']:
|
|
image = funcs.resize_fixed(image=image, size=size, platform_type='520')
|
|
elif type.lower() in ['720', 'fixed_720']:
|
|
image = funcs.resize_fixed(image=image, size=size, platform_type='720')
|
|
elif type.lower() in ['ie']:
|
|
ie = IE()
|
|
image = ie.resize(image=image, size=size, tile_size=tile_size)
|
|
elif type.lower() in ['test']:
|
|
image = funcs.resize_test(image=image, size=size)
|
|
elif type.lower() in ['c']:
|
|
image = funcs.resize_bilinear_c(image=image, size=size)
|
|
elif type.lower() in ['ie_sim']:
|
|
image = funcs.resize_IE_sim(image=image, size=size)
|
|
else:
|
|
image = funcs.resize_bilinear_vectorized(image=image, size=size, return_float=return_float)
|
|
|
|
return image
|
|
|
|
def calculate_pad_length_center(tar_size, ori_size, type=DEFAULT, **kwargs):
|
|
"""
|
|
pad function
|
|
|
|
calculate the padding lehth for pad 2 sides(center)
|
|
|
|
Parameters
|
|
----------
|
|
tar_size : tuple / list
|
|
1x2 array, (tar_size_w, tar_size_h)
|
|
|
|
ori_size : tuple / list
|
|
1x2 array, (ori_size_w, ori_size_h)
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
Returns
|
|
----------
|
|
out : list
|
|
[pad_l, pad_r, pad_t, pad_b]
|
|
"""
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['pad']['type']
|
|
return funcs.calculate_pad_length_center(tar_size=tar_size, ori_size=ori_size)
|
|
|
|
def calculate_pad_length_corner(tar_size, ori_size, type=DEFAULT, **kwargs):
|
|
"""
|
|
pad function
|
|
|
|
calculate the padding lehth for pad 2 sides(corner)
|
|
|
|
Parameters
|
|
----------
|
|
tar_size : tuple / list
|
|
1x2 array, (tar_size_w, tar_size_h)
|
|
|
|
ori_size : tuple / list
|
|
1x2 array, (ori_size_w, ori_size_h)
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
Returns
|
|
----------
|
|
out : list
|
|
[pad_l, pad_r, pad_t, pad_b]
|
|
"""
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['pad']['type']
|
|
return funcs.calculate_pad_length_corner(tar_size=tar_size, ori_size=ori_size)
|
|
|
|
def pad(image, pad_l=0, pad_r=0, pad_t=0, pad_b=0, pad_val=0, type=DEFAULT, hw_limit=False, thread='',**kwargs):
|
|
"""
|
|
pad function
|
|
|
|
specific left, right, top and bottom pad size.
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image
|
|
|
|
pad_l : int
|
|
Pad size from left, default 0
|
|
|
|
pad_r : int
|
|
Pad size form right, default 0
|
|
|
|
pad_t : int
|
|
Pad size from top, default 0
|
|
|
|
pad_b : int
|
|
Pad size form bottom, default 0
|
|
|
|
pad_val : float
|
|
The value of pad, , default 0
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
hw_limit : bool
|
|
turn on the hw limit or not, if true, the max pad length for each side will take 127 for 520 type, 255 for 720 type,
|
|
default is False
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.pad(image_data,20,40,20,40,-0.5)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert isinstance(pad_l, int)
|
|
assert isinstance(pad_r, int)
|
|
assert isinstance(pad_t, int)
|
|
assert isinstance(pad_b, int)
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['pad']['type']
|
|
|
|
if type.lower() in ['520']:
|
|
if pad_l > 127:
|
|
if hw_limit:
|
|
pad_l = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_r > 127:
|
|
if hw_limit:
|
|
pad_r = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_t > 127:
|
|
if hw_limit:
|
|
pad_t = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_b > 127:
|
|
if hw_limit:
|
|
pad_b = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
elif type.lower() in ['720']:
|
|
if pad_l > 255:
|
|
if hw_limit:
|
|
pad_l = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_r > 255:
|
|
if hw_limit:
|
|
pad_r = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_t > 255:
|
|
if hw_limit:
|
|
pad_t = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_b > 255:
|
|
if hw_limit:
|
|
pad_b = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
else: ## float, ie
|
|
pass
|
|
|
|
##
|
|
image = funcs.pad(image=image, pad_l=pad_l, pad_r=pad_r, pad_t=pad_t, pad_b=pad_b, pad_val=pad_val)
|
|
return image
|
|
|
|
def pad_center(image, size, pad_val=0, type=DEFAULT, hw_limit=False, thread='',**kwargs):
|
|
"""
|
|
pad function
|
|
|
|
center pad with pad size.
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image
|
|
|
|
size : tuple,
|
|
1x2 array, (padded_size_w, padded_size_h)
|
|
|
|
pad_val : float
|
|
The value of pad, default is 0
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
hw_limit : bool
|
|
turn on the hw limit or not, if true, the max pad length for each side will take 127 for 520 type, 255 for 720 type,
|
|
default is False
|
|
|
|
Returns:
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples:
|
|
----------
|
|
>>> image_data = kp.pad_center(image_data,size=(56,56),pad_val=-0.5)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert isinstance(size, list) | isinstance(size, tuple)
|
|
assert len(size) >= 2
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['pad']['type']
|
|
|
|
## calcuate pad length
|
|
pad_l,pad_r,pad_t,pad_b = funcs.calculate_pad_length_center(tar_size=size, ori_size=(image.shape[1],image.shape[0]))
|
|
|
|
if type.lower() in ['520']:
|
|
if pad_l > 127:
|
|
if hw_limit:
|
|
pad_l = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_r > 127:
|
|
if hw_limit:
|
|
pad_r = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_t > 127:
|
|
if hw_limit:
|
|
pad_t = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_b > 127:
|
|
if hw_limit:
|
|
pad_b = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
elif type.lower() in ['720']:
|
|
if pad_l > 255:
|
|
if hw_limit:
|
|
pad_l = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_r > 255:
|
|
if hw_limit:
|
|
pad_r = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_t > 255:
|
|
if hw_limit:
|
|
pad_t = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_b > 255:
|
|
if hw_limit:
|
|
pad_b = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
else: ## float, ie
|
|
pass
|
|
|
|
##
|
|
image = funcs.pad(image=image, pad_l=pad_l, pad_r=pad_r, pad_t=pad_t, pad_b=pad_b, pad_val=pad_val)
|
|
return image
|
|
|
|
def pad_corner(image, size, pad_val=0, type=DEFAULT, hw_limit=False ,thread='',**kwargs):
|
|
"""
|
|
pad function
|
|
|
|
corner pad with pad size.
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image
|
|
|
|
size : tuple
|
|
1x2 array, (padded_size_w, padded_size_h)
|
|
|
|
pad_val : float
|
|
The value of pad, default is 0
|
|
|
|
type : str
|
|
'float' / '520' / '720' / 'IE'
|
|
|
|
hw_limit : bool
|
|
turn on the hw limit or not, if true, the max pad length for each side will take 127 for 520 type, 255 for 720 type,
|
|
default is False
|
|
|
|
Returns:
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples:
|
|
----------
|
|
>>> image_data = kp.pad_corner(image_data,size=(56,56),pad_val=-0.5)
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert isinstance(size, list) | isinstance(size, tuple)
|
|
assert len(size) >= 2
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['pad']['type']
|
|
|
|
## calcuate pad length
|
|
pad_l,pad_r,pad_t,pad_b = funcs.calculate_pad_length_corner(tar_size=size, ori_size=(image.shape[1],image.shape[0]))
|
|
|
|
if type.lower() in ['520']:
|
|
if pad_l > 127:
|
|
if hw_limit:
|
|
pad_l = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_r > 127:
|
|
if hw_limit:
|
|
pad_r = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_t > 127:
|
|
if hw_limit:
|
|
pad_t = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
if pad_b > 127:
|
|
if hw_limit:
|
|
pad_b = 127
|
|
print("Error: Pad value larger than 127 is not supported in inproc_520\n")
|
|
elif type.lower() in ['720']:
|
|
if pad_l > 255:
|
|
if hw_limit:
|
|
pad_l = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_r > 255:
|
|
if hw_limit:
|
|
pad_r = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_t > 255:
|
|
if hw_limit:
|
|
pad_t = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
if pad_b > 255:
|
|
if hw_limit:
|
|
pad_b = 255
|
|
print("Error: Pad value larger than 255 is not supported in inproc_720\n")
|
|
else: ## float, ie
|
|
pass
|
|
|
|
##
|
|
image = funcs.pad(image=image, pad_l=pad_l, pad_r=pad_r, pad_t=pad_t, pad_b=pad_b, pad_val=pad_val)
|
|
|
|
return image
|
|
|
|
def norm(image,scale=256.,bias=-0.5, thread='',**kwargs):
|
|
"""
|
|
norm function
|
|
|
|
x = (x/scale - bias)
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
Input image
|
|
|
|
scale : float / 1x3 array
|
|
Default = 256
|
|
|
|
bias : float / 1x3 array
|
|
Default = -0.5
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.norm(image_data)
|
|
>>> image_data = kp.norm(image_data,bias=[0.485, 0.456, 0.406], scale=[0.229, 0.224, 0.225])
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
|
|
image = funcs.norm(image=image, scale=scale, bias=bias)
|
|
return image
|
|
|
|
def inproc_520(image,return_float=False,raw_fmt=None,raw_size=None,npu_size=None,crop_box=None,pad_mode=None,resize_size=None,pad_length=None,norm='kneron', gray=False, rotate=0, radix=8, bit_width=8, round_w_to_16=True, NUM_BANK_LINE=32,BANK_ENTRY_CNT=512,MAX_IMG_PREPROC_ROW_NUM=511,MAX_IMG_PREPROC_COL_NUM=256,pad_limit_on=True,**kwargs):
|
|
"""
|
|
inproc_520 python simulator
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray / string
|
|
Image input, can be image file, bin or hex file
|
|
|
|
return_float : bool
|
|
If False, return RGBA fix format
|
|
If True, return RGB float format
|
|
default = False
|
|
|
|
raw_fmt : string
|
|
If image is raw file, set the raw fmt
|
|
|
|
raw_size : tuple
|
|
(src_w, src_h)
|
|
|
|
npu_size : tuple
|
|
(target_w, target_h)
|
|
|
|
crop_box : tuple
|
|
(x1, y1, x2, y2), will skip crop if set None
|
|
|
|
pad_mode : int
|
|
0: pad 2 sides, 1: pad 1 side, 2: no pad. default = 0
|
|
|
|
pad_val : int
|
|
|
|
norm : str
|
|
Norm mode, default = 'kneron'
|
|
|
|
rotate: int
|
|
0 / 1(90 degree) / 2(180 degree), default = 0
|
|
|
|
radix : int
|
|
Default = 8
|
|
|
|
bit_width : int
|
|
Default = 8
|
|
|
|
round_w_to_16 : bool
|
|
Default = True
|
|
|
|
gray : bool
|
|
Default = False
|
|
|
|
pad_limit_on : bool
|
|
turn on the hw pad limit(up to 255 pre side) or not, default = True(on)
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image_data = kp.inproc_520(image_data,npu_size=(56,56),crop_box=(272,145,460,341),pad_mode=1)
|
|
"""
|
|
return inproc_520_flow(
|
|
image=image,
|
|
return_float=return_float,
|
|
raw_fmt=raw_fmt,
|
|
raw_size=raw_size,
|
|
npu_size=npu_size,
|
|
crop_box=crop_box,
|
|
pad_mode=pad_mode,
|
|
resize_size=resize_size,
|
|
pad_length=pad_length,
|
|
norm=norm,
|
|
gray=gray,
|
|
rotate=rotate,
|
|
radix=radix,
|
|
bit_width=bit_width,
|
|
round_w_to_16=round_w_to_16,
|
|
NUM_BANK_LINE=NUM_BANK_LINE,
|
|
BANK_ENTRY_CNT=BANK_ENTRY_CNT,
|
|
MAX_IMG_PREPROC_ROW_NUM=MAX_IMG_PREPROC_ROW_NUM,
|
|
MAX_IMG_PREPROC_COL_NUM=MAX_IMG_PREPROC_COL_NUM)
|
|
|
|
def inproc_720(image,return_float=False,raw_fmt=None,raw_size=None ,npu_size=None, crop_box=None, pad_mode=None, resize_size=None, pad_length=None, matrix=None, bias=None, shift_1_bit=False, sub_128=False, radix=8, pad_limit_on=True,**kwargs):
|
|
"""
|
|
inproc_720 python simulator
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray / string
|
|
Image input, can be image file, bin or hex file
|
|
|
|
return_float : bool
|
|
If False, return RGBA fix format
|
|
If True, return RGB float format
|
|
default = False
|
|
|
|
raw_fmt : string
|
|
If image is raw file, set the raw fmt
|
|
|
|
raw_size : tuple
|
|
(src_w, src_h)
|
|
|
|
npu_size : tuple
|
|
(target_w, target_h)
|
|
|
|
crop_box : tuple
|
|
(x1, y1, x2, y2), will skip crop if set None
|
|
|
|
pad_mode : int
|
|
0: pad 2 sides, 1: pad 1 side, 2: no pad. default = 0
|
|
|
|
matrix : list / tuple
|
|
Matirx for the matrix operator, must be a list/tuple for 9 elements, default = [256,0,0,0,256,0,0,0,256]
|
|
|
|
bias : list / tuple
|
|
Bias for the matrix operator, must be a list/tuple for 3 elements, default = [0,0,0]
|
|
|
|
shift_1_bit : bool
|
|
Shift 1 bit for the matrix operator, default = False
|
|
|
|
sub_128 : bool
|
|
Sub 128 for the matrix operator, default = False
|
|
|
|
radix : int
|
|
default = 8
|
|
|
|
pad_limit_on : bool
|
|
turn on the hw pad limit(up to 255 pre side) or not, default = True(on)
|
|
|
|
Returns
|
|
----------
|
|
out : np.ndarray
|
|
|
|
Examples
|
|
----------
|
|
>>> image = './w512xh375_rgb565.raw'
|
|
>>> image_data = kp.inproc_720(image,raw_fmt='rgb565',raw_size=(512,375),npu_size=(416,416),pad_mode=1)
|
|
"""
|
|
return inproc_720_flow(
|
|
image=image,
|
|
return_float=return_float,
|
|
raw_fmt=raw_fmt,
|
|
raw_size=raw_size,
|
|
npu_size=npu_size,
|
|
crop_box=crop_box,
|
|
pad_mode=pad_mode,
|
|
resize_size=resize_size,
|
|
pad_length=pad_length,
|
|
matrix=matrix,
|
|
bias=bias,
|
|
shift_1_bit=shift_1_bit,
|
|
sub_128=sub_128,
|
|
radix=radix,
|
|
pad_limit_on=pad_limit_on)
|
|
|
|
def bit_match(data1, data2, dump_file = None,**kwargs):
|
|
"""
|
|
bit_match function
|
|
|
|
check data1 is equal to data2 or not.
|
|
|
|
Parameters
|
|
----------
|
|
data1: np.ndarray / str
|
|
Can be array or txt/bin file.
|
|
|
|
data2: np.array / str
|
|
Can be array or txt/bin file.
|
|
|
|
Returns
|
|
----------
|
|
out1: bool
|
|
Is match or not
|
|
|
|
out2: np.array
|
|
If not match, save the position for mismatched data
|
|
|
|
Examples
|
|
----------
|
|
>>> result, mismatched = kp.bit_match(data1,data2)
|
|
"""
|
|
if isinstance(data1, str):
|
|
if os.path.splitext(data1)[1] == '.bin':
|
|
data1 = np.fromfile(data1, dtype='uint8')
|
|
elif os.path.splitext(data1)[1] == '.txt':
|
|
data1 = np.loadtxt(data1)
|
|
|
|
assert isinstance(data1, np.ndarray)
|
|
|
|
if isinstance(data2, str):
|
|
if os.path.splitext(data2)[1] == '.bin':
|
|
data2 = np.fromfile(data2, dtype='uint8')
|
|
elif os.path.splitext(data2)[1] == '.txt':
|
|
data2 = np.loadtxt(data2)
|
|
|
|
assert isinstance(data2, np.ndarray)
|
|
|
|
|
|
data1 = data1.reshape((-1,1))
|
|
data2 = data2.reshape((-1,1))
|
|
|
|
if dump_file != None:
|
|
text_file = open(dump_file, "w")
|
|
|
|
if not(len(data1) == len(data2)):
|
|
print('error len')
|
|
if dump_file != None:
|
|
text_file.write('error len\n')
|
|
text_file.close()
|
|
return False, np.zeros((1))
|
|
else:
|
|
ans = abs(data2 - data1)
|
|
if len(np.where(ans>0)[0]) > 0:
|
|
print('error')
|
|
if dump_file != None:
|
|
text_file.write('error\n')
|
|
for i in range(len(np.where(ans>0)[0])):
|
|
j = np.where(ans>0)[0][i]
|
|
info = 'index: {}, {}, {}\n'.format(j, data1[j],data2[j])
|
|
text_file.write(info)
|
|
text_file.close()
|
|
return False, np.where(ans>0)[0]
|
|
else:
|
|
print('pass')
|
|
if dump_file != None:
|
|
text_file.write('pass')
|
|
text_file.close()
|
|
return True, np.zeros((1))
|
|
|
|
def similarity_transform(dst_vec, src_vec, type=DEFAULT):
|
|
"""
|
|
Estimate N-D similarity transformation with or without scaling.
|
|
Set type as float to use python umeyama function.
|
|
Set type as fx to use C code function.
|
|
|
|
Parameters
|
|
----------
|
|
src_vec(landmark in fr) : list / tuple / nd.array
|
|
MxN array for Source coordinates. MxN must = 10
|
|
|
|
dst_vec(src in fr) : list / tuple / nd.array
|
|
MxN array for Destination coordinates. MxN must = 10
|
|
|
|
type : str
|
|
'float' / 'fx'
|
|
|
|
Returns
|
|
-------
|
|
out: (2, 3) np.array
|
|
|
|
Examples:
|
|
-------
|
|
>>> landmarks = (294, 185, 365, 169, 324, 199, 310, 252, 362, 243)
|
|
>>> src_vec = np.array((30.2946, 51.6963, 65.5318, 51.5014, 48.0252, 71.7366, 33.5493, 92.3655, 62.7299, 92.2041))
|
|
>>> matrix = kp.similarity_transform(src_vec, landmarks, type='fx')
|
|
"""
|
|
assert isinstance(src_vec, list) | isinstance(src_vec, tuple) | isinstance(src_vec, np.ndarray)
|
|
assert isinstance(dst_vec, list) | isinstance(dst_vec, tuple) | isinstance(dst_vec, np.ndarray)
|
|
src_size = np.array(src_vec).size
|
|
dst_size = np.array(dst_vec).size
|
|
assert src_size == dst_size
|
|
assert src_size%2 == 0
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['warpAffine']['type']
|
|
|
|
## fx
|
|
if type.lower() in ['fx']:
|
|
src_vec = np.array(src_vec).reshape((src_size)).tolist()
|
|
dst_vec = np.array(dst_vec).reshape((dst_size)).tolist()
|
|
ret, out = utils.similarity_transform(src_vec, dst_vec)
|
|
## float
|
|
else:
|
|
src_vec = np.array(src_vec).reshape((src_size//2,2))
|
|
dst_vec = np.array(dst_vec).reshape((dst_size//2,2))
|
|
out = utils.umeyama(src_vec, dst_vec, True)[0:2,:]
|
|
|
|
return np.array(out).reshape((2,3))
|
|
|
|
|
|
def warpAffine(image, Matrix, warp_size, type=DEFAULT, thread='',**kwargs):
|
|
"""
|
|
warpAffine function that using fixed, IE or OpenCV behavior
|
|
Set type as float to use cv2.warpAffine function.
|
|
Set type as fx to use C code function.
|
|
Set type as IE to use IE C model.
|
|
|
|
Parameters
|
|
----------
|
|
image : np.ndarray
|
|
|
|
Matrix : tuple / list / np.ndarray
|
|
2x3 array for [R|T] matrix.
|
|
|
|
warp_size : tuple / list
|
|
|
|
type : str
|
|
'float' / 'fx' / '520' / '720' / 'IE'
|
|
|
|
Returns
|
|
-------
|
|
out: np.array
|
|
|
|
Examples:
|
|
-------
|
|
>>> m = kp.similarity_transform(src_vec, landmarks)
|
|
>>> warp_size = (112,112)
|
|
>>> image_data = kp.warpAffine(image_data,Matrix=m,warp_size=image_size,type='fx')
|
|
"""
|
|
assert isinstance(image, np.ndarray)
|
|
assert isinstance(warp_size, list) | isinstance(warp_size, tuple)
|
|
assert len(warp_size) == 2
|
|
assert isinstance(Matrix, list) | isinstance(Matrix, tuple) | isinstance(Matrix, np.ndarray)
|
|
assert np.array(Matrix).size == 6
|
|
Matrix = np.array(Matrix).reshape((2,3))
|
|
|
|
## if set DEFAULT
|
|
if type is DEFAULT:
|
|
type = default['warpAffine']['type']
|
|
|
|
##
|
|
if type.lower() in ['fx','520', '720']:
|
|
ret, image = utils.warpAffine_so(image=image, Matrix=Matrix, warp_size=warp_size)
|
|
elif type.lower() in ['ie']:
|
|
ie = IE(thread=thread)
|
|
image = ie.dewarping(image=image, matrix=Matrix, dst_size=warp_size)
|
|
else: ## float
|
|
import cv2
|
|
image = cv2.warpAffine(image, Matrix, (warp_size[0], warp_size[1]), flags=cv2.INTER_LINEAR, borderValue=0.0)
|
|
|
|
return image
|