mirror of
https://github.com/visioncortex/vtracer.git
synced 2026-09-28 15:01:20 -07:00
Release 1.0.0-alpha.4
Bump every package version to 1.0.0-alpha.4 (PyPI 1.0.0a4) and promote the CHANGELOG [Unreleased] section to 1.0.0-alpha.4. Refresh the tracked lockfile. App download links are intentionally left at 1.0.0-alpha.3 (desktop app release lands separately).
This commit is contained in:
@@ -64,8 +64,13 @@ pub struct FidelityReport {
|
||||
fn dssim_score(a_rgb: &[u8], b_rgb: &[u8], w: usize, h: usize) -> f64 {
|
||||
let d = dssim_core::Dssim::new();
|
||||
let to = |buf: &[u8]| {
|
||||
let px: Vec<rgb::RGB<u8>> =
|
||||
(0..w * h).map(|i| rgb::RGB { r: buf[i * 3], g: buf[i * 3 + 1], b: buf[i * 3 + 2] }).collect();
|
||||
let px: Vec<rgb::RGB<u8>> = (0..w * h)
|
||||
.map(|i| rgb::RGB {
|
||||
r: buf[i * 3],
|
||||
g: buf[i * 3 + 1],
|
||||
b: buf[i * 3 + 2],
|
||||
})
|
||||
.collect();
|
||||
d.create_image_rgb(&px, w, h).expect("dssim image")
|
||||
};
|
||||
let (val, _) = d.compare(&to(a_rgb), &to(b_rgb));
|
||||
@@ -75,7 +80,13 @@ fn dssim_score(a_rgb: &[u8], b_rgb: &[u8], w: usize, h: usize) -> f64 {
|
||||
/// Compare an original against a candidate reconstruction, both RGB8, w×h.
|
||||
/// `thresh` is the RGB Euclidean bad-pixel gate (use [`DEFAULT_THRESH`]).
|
||||
/// Returns the report plus the bad-pixel mask (255/0, one byte per pixel).
|
||||
pub fn fidelity(orig_rgb: &[u8], cand_rgb: &[u8], w: usize, h: usize, thresh: f64) -> (FidelityReport, Vec<u8>) {
|
||||
pub fn fidelity(
|
||||
orig_rgb: &[u8],
|
||||
cand_rgb: &[u8],
|
||||
w: usize,
|
||||
h: usize,
|
||||
thresh: f64,
|
||||
) -> (FidelityReport, Vec<u8>) {
|
||||
assert_eq!(orig_rgb.len(), w * h * 3);
|
||||
assert_eq!(cand_rgb.len(), w * h * 3);
|
||||
|
||||
@@ -108,7 +119,11 @@ pub fn fidelity(orig_rgb: &[u8], cand_rgb: &[u8], w: usize, h: usize, thresh: f6
|
||||
// the signature of a slightly blurred/compressed source) vanish; genuine
|
||||
// missing patches survive. The reported mask keeps the raw bad pixels.
|
||||
let at = |m: &[u8], x: i64, y: i64| {
|
||||
x >= 0 && y >= 0 && (x as usize) < w && (y as usize) < h && m[y as usize * w + x as usize] != 0
|
||||
x >= 0
|
||||
&& y >= 0
|
||||
&& (x as usize) < w
|
||||
&& (y as usize) < h
|
||||
&& m[y as usize * w + x as usize] != 0
|
||||
};
|
||||
let mut eroded = vec![0u8; w * h];
|
||||
for y in 0..h as i64 {
|
||||
@@ -142,7 +157,11 @@ pub fn fidelity(orig_rgb: &[u8], cand_rgb: &[u8], w: usize, h: usize, thresh: f6
|
||||
let patch_mass = if sizes.is_empty() {
|
||||
0.0
|
||||
} else {
|
||||
sizes.iter().map(|&a| (a as f64) * (a as f64)).sum::<f64>().sqrt()
|
||||
sizes
|
||||
.iter()
|
||||
.map(|&a| (a as f64) * (a as f64))
|
||||
.sum::<f64>()
|
||||
.sqrt()
|
||||
};
|
||||
let p_frac = patch_mass / (w * h) as f64;
|
||||
|
||||
@@ -212,7 +231,12 @@ mod tests {
|
||||
assert!((rd.s_patch - 1.0).abs() < 1e-9);
|
||||
// identical PSNR/RMSE by construction; the patch axis must separate them
|
||||
assert!((rb.rmse - rd.rmse).abs() < 1e-9);
|
||||
assert!(rb.s_patch < rd.s_patch * 0.25, "blob {} dust {}", rb.s_patch, rd.s_patch);
|
||||
assert!(
|
||||
rb.s_patch < rd.s_patch * 0.25,
|
||||
"blob {} dust {}",
|
||||
rb.s_patch,
|
||||
rd.s_patch
|
||||
);
|
||||
assert!(rb.fidelity < rd.fidelity);
|
||||
}
|
||||
|
||||
@@ -231,7 +255,10 @@ mod tests {
|
||||
let (rf, _) = fidelity(&clean, &fil, 64, 64, DEFAULT_THRESH);
|
||||
assert_eq!(rf.bad_px, 128);
|
||||
assert_eq!(rf.clusters, 0);
|
||||
assert!((rf.s_patch - 1.0).abs() < 1e-9, "filament must not count as a patch");
|
||||
assert!(
|
||||
(rf.s_patch - 1.0).abs() < 1e-9,
|
||||
"filament must not count as a patch"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//! metrics, their [0,1] subscores, the composite fidelity, and a
|
||||
//! machine-readable csv line.
|
||||
|
||||
use vtracer_bench::{fidelity, DEFAULT_THRESH};
|
||||
use vtracer_bench::{DEFAULT_THRESH, fidelity};
|
||||
|
||||
fn main() {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
@@ -49,11 +49,20 @@ fn main() {
|
||||
let (r, mask) = fidelity(orig.as_raw(), &cand, w, h, thresh);
|
||||
|
||||
if let Some(out) = mask_out {
|
||||
image::GrayImage::from_raw(w as u32, h as u32, mask).unwrap().save(&out).expect("save mask");
|
||||
image::GrayImage::from_raw(w as u32, h as u32, mask)
|
||||
.unwrap()
|
||||
.save(&out)
|
||||
.expect("save mask");
|
||||
}
|
||||
|
||||
println!("psnr {:>8.2} dB (rmse {:.2}) -> {:.4}", r.psnr, r.rmse, r.s_psnr);
|
||||
println!("ssim {:>8.5} (dssim {:.5}) -> {:.4}", r.s_ssim, r.dssim, r.s_ssim);
|
||||
println!(
|
||||
"psnr {:>8.2} dB (rmse {:.2}) -> {:.4}",
|
||||
r.psnr, r.rmse, r.s_psnr
|
||||
);
|
||||
println!(
|
||||
"ssim {:>8.5} (dssim {:.5}) -> {:.4}",
|
||||
r.s_ssim, r.dssim, r.s_ssim
|
||||
);
|
||||
println!(
|
||||
"patch {:>8.1} px rms ({} bad px, {} clusters, largest {}) -> {:.4}",
|
||||
r.patch_mass, r.bad_px, r.clusters, r.largest, r.s_patch
|
||||
|
||||
@@ -15,7 +15,7 @@ name = "vtracer"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
vtracer = { version = "1.0.0-alpha.3", path = "../vtracer" }
|
||||
vtracer = { version = "1.0.0-alpha.4", path = "../vtracer" }
|
||||
visioncortex.workspace = true
|
||||
# Decode-only: trimmed to real input formats (drops the AV1 encoder + OpenEXR).
|
||||
image = { version = "0.25", default-features = false, features = [
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
[package]
|
||||
name = "vtracer-py"
|
||||
description = "Python bindings for the vtracer vectorization framework."
|
||||
version = "1.0.0-alpha.3"
|
||||
version = "1.0.0-alpha.4"
|
||||
authors = ["Chris Tsang <tyt2y7@gmail.com>"]
|
||||
edition = "2024"
|
||||
license = "MIT OR Apache-2.0"
|
||||
@@ -19,7 +19,7 @@ name = "vtracer"
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[dependencies]
|
||||
vtracer = { version = "1.0.0-alpha.3", path = "../vtracer" }
|
||||
vtracer = { version = "1.0.0-alpha.4", path = "../vtracer" }
|
||||
# Decode-only: trimmed to real input formats (drops the AV1 encoder + OpenEXR).
|
||||
image = { version = "0.25", default-features = false, features = [
|
||||
"png", "jpeg", "gif", "bmp", "webp", "tiff", "ico", "pnm", "tga", "qoi",
|
||||
|
||||
@@ -36,7 +36,7 @@ Technical descriptions of the [tracing algorithm](https://www.visioncortex.org/v
|
||||
## Install
|
||||
|
||||
```sh
|
||||
pip install vtracer==1.0.0a3
|
||||
pip install vtracer==1.0.0a4
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Reference in New Issue
Block a user