///|
pub enum ResampleFilter {
Nearest
Bilinear
Area
} derive(Debug, Eq)
///|
pub struct ResampleConfig {
filter : ResampleFilter
fill : Gray
} derive(Debug, Eq)
///|
pub fn ResampleConfig::new(
filter? : ResampleFilter = Bilinear,
fill? : Gray = Gray::black(),
) -> ResampleConfig {
{ filter, fill }
}
///|
fn interpolate_gray(
image : GrayImage,
x1000 : Int,
y1000 : Int,
fill : Gray,
) -> Gray {
if image.width <= 0 || image.height <= 0 {
fill
} else {
let x = clamp(x1000, low=0, high=max_i(0, image.width * 1000 - 1))
let y = clamp(y1000, low=0, high=max_i(0, image.height * 1000 - 1))
let x0 = x / 1000
let y0 = y / 1000
let x1 = min_i(image.width - 1, x0 + 1)
let y1 = min_i(image.height - 1, y0 + 1)
let fx = x % 1000
let fy = y % 1000
let a = image.get(x0, y0).value
let b = image.get(x1, y0).value
let c = image.get(x0, y1).value
let d = image.get(x1, y1).value
let top = a * (1000 - fx) + b * fx
let bottom = c * (1000 - fx) + d * fx
Gray::new((top * (1000 - fy) + bottom * fy) / 1000000)
}
}
///|
pub fn GrayImage::resize(
self : GrayImage,
size : Size,
config? : ResampleConfig = ResampleConfig::new(),
) -> GrayImage {
let out = GrayImage::new(
width=max_i(0, size.width),
height=max_i(0, size.height),
fill=config.fill,
)
if out.width == 0 || out.height == 0 {
out
} else {
for y in 0..
self.get(
clamp((sx + 500) / 1000, low=0, high=max_i(0, self.width - 1)),
clamp((sy + 500) / 1000, low=0, high=max_i(0, self.height - 1)),
)
Bilinear => interpolate_gray(self, sx, sy, config.fill)
Area => {
let x0 = x * self.width / out.width
let y0 = y * self.height / out.height
let x1 = max_i(x0 + 1, (x + 1) * self.width / out.width)
let y1 = max_i(y0 + 1, (y + 1) * self.height / out.height)
let mut total = 0
let mut count = 0
for yy in y0.. GrayImage {
self.resize(size, config=ResampleConfig::new(filter=Nearest))
}
///|
pub fn GrayImage::resize_bilinear(self : GrayImage, size : Size) -> GrayImage {
self.resize(size, config=ResampleConfig::new(filter=Bilinear))
}
///|
pub fn GrayImage::crop_padded(
self : GrayImage,
region : Rect,
fill? : Gray = Gray::black(),
) -> GrayImage {
let out = GrayImage::new(
width=max_i(0, region.width),
height=max_i(0, region.height),
fill~,
)
for y in 0.. GrayImage {
let b = max_i(0, border)
let out = GrayImage::new(
width=self.width + b * 2,
height=self.height + b * 2,
fill~,
)
for y in 0.. GrayImage {
let mut out = self.copy()
for _ in 0.. Array[GrayImage] {
let out : Array[GrayImage] = [self.copy()]
let mut current = self.copy()
for _ in 0.. Int {
let width = min_i(a.width, b.width)
let height = min_i(a.height, b.height)
if width <= 0 || height <= 0 {
0
} else {
let mut total = 0
for y in 0.. Int {
let width = min_i(a.width, b.width)
let height = min_i(a.height, b.height)
if width <= 0 || height <= 0 {
0
} else {
let mut total = 0
for y in 0.. Int {
let mse = image_mse(a, b)
if mse == 0 {
100000
} else {
let ratio = 65025 * 1000 / mse
let mut guess = 0
for value in 0..<=100000 {
if value * value <= ratio * 1000 {
guess = value
}
}
guess
}
}
///|
pub fn GrayImage::match_template(
self : GrayImage,
template : GrayImage,
stride : Int,
) -> Point {
let step = max_i(1, stride)
if template.width <= 0 ||
template.height <= 0 ||
template.width > self.width ||
template.height > self.height {
Point::new(x=-1, y=-1)
} else {
let mut best = 2147483647
let mut result = Point::new(x=0, y=0)
for y in 0..<(self.height - template.height + 1) {
if y % step == 0 {
for x in 0..<(self.width - template.width + 1) {
if x % step == 0 {
let mut error = 0
for yy in 0.. RgbImage {
let out = RgbImage::new(
width=max_i(0, size.width),
height=max_i(0, size.height),
)
if out.width > 0 && out.height > 0 {
for y in 0.. RgbImage {
let out = RgbImage::new(
width=max_i(0, region.width),
height=max_i(0, region.height),
)
for y in 0.. String {
"{\"mae\":\{image_mae(expected, actual)},\"mse\":\{image_mse(expected, actual)},\"psnr_x1000\":\{image_psnr_x1000(expected, actual)}}"
}