Vision โ Prism¶
New in v0.1.5
The olaverse.vision module wraps the Prism family โ small, self-contained image-to-image models for upscaling, denoising, and steganography. None of these require African-language data; they're general-purpose image utilities that ship under the same SDK.
Each Prism model ships its own small model.py architecture file alongside the checkpoint on its Hugging Face repo (no standard transformers auto-class covers FSRCNN/LIIF/U-Net image codecs). Loading a Prism model downloads and executes that model.py from the corresponding olaverse/prism-* repo โ the same approach documented on each model card. All Prism repos are published by Olaverse under Apache-2.0.
PrismUpscaler โ Super-Resolution¶
Model Cards: olaverse/prism-upscaler-2x ยท olaverse/prism-upscaler-4x ยท olaverse/prism-upscaler-max
size= |
Model | Architecture | Scale |
|---|---|---|---|
"2x" (default) |
prism-upscaler-2x | FSRCNN (~25K params) | Fixed 2x |
"4x" |
prism-upscaler-4x | FSRCNN (~25K params) | Fixed 4x |
"max" |
prism-upscaler-max | LIIF (RRDB encoder + implicit MLP decoder) | Any continuous resolution |
The 2x/4x models are fixed-scale convolutional upscalers โ fast, single forward pass. max targets an exact output resolution (e.g. fitting a specific size) at a higher inference cost per pixel.
from olaverse import PrismUpscaler
# Fixed scale
upscaler = PrismUpscaler(size="2x")
upscaler.upscale("input.jpg").save("output.jpg")
# Arbitrary target resolution
upscaler_max = PrismUpscaler(size="max")
upscaler_max.upscale("input.jpg", target_size=(1024, 1024)).save("output.jpg")
All three were trained with realistic degradation (blur, sensor noise, JPEG re-compression) rather than plain bicubic downsampling โ built for real-world low-quality input, not just clean synthetic test images.
Known limitations
4xover-smooths fine/curly hair and other high-frequency texture โ a consistent, known tradeoff at this scale, not an occasional artifact.- None of the three have been evaluated against standard academic benchmarks (Set5/Set14/BSD100/Urban100) โ comparisons on each model card are informal, single-image checks against a bicubic baseline.
olaverse.vision.PrismUpscaler ¶
Image upscaling with the Prism family.
Models (size=): "2x" โ prism-upscaler-2x (fixed 2x, FSRCNN, ~25K params) "4x" โ prism-upscaler-4x (fixed 4x, FSRCNN, ~25K params) "max" โ prism-upscaler-max (any continuous target resolution, LIIF)
Requires: pip install olaverse[vision]
Quick start โ fixed scale: >>> upscaler = PrismUpscaler(size="2x") >>> upscaler.upscale("input.jpg").save("output.jpg")
Quick start โ arbitrary target resolution: >>> upscaler = PrismUpscaler(size="max") >>> upscaler.upscale("input.jpg", target_size=(1024, 1024)).save("output.jpg")
Methods:¶
upscale ¶
upscale(image: 'str | os.PathLike | Image.Image', target_size: tuple | None = None) -> 'Image.Image'
Upscale an image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
'str | os.PathLike | Image.Image'
|
Path to an image file, or a PIL.Image. |
required |
target_size
|
tuple | None
|
(width, height) โ required for size="max", ignored otherwise. |
None
|
Returns:
| Type | Description |
|---|---|
'Image.Image'
|
PIL.Image: the upscaled image. |
PrismDenoiser โ Noise/Blur/Compression Removal¶
Model Card: olaverse/prism-denoiser
Removes Gaussian noise, blur, and JPEG-like compression artifacts using a compact U-Net. Useful as a standalone restoration tool or as pre-processing before other image tasks.
Output is always 128x128
Input is resized to 128x128 internally and the output is returned at that resolution โ a 640x480 photo comes back 128x128, not restored in place. This is a restoration model for small tiles, not a full-resolution filter. To restore a larger image, tile it yourself, or follow PrismDenoiser with PrismUpscaler(size="max") to get back to the target resolution.
from olaverse import PrismDenoiser
denoiser = PrismDenoiser()
denoiser.denoise("noisy.jpg").save("denoised.jpg")
Reduces, doesn't eliminate, noise
On complex, high-detail scenes (foliage, sky), denoising is genuinely effective (+3-4 dB PSNR in the model card's benchmarks) but typically incomplete โ some residual grain remains. On near-grayscale/texture-only images, the model can render a faint color tint that isn't in the original, since it was trained predominantly on full-color photos.
olaverse.vision.PrismDenoiser ¶
Image restoration โ removes Gaussian noise, blur, and JPEG-like compression artifacts.
Wraps olaverse/prism-denoiser โ a compact U-Net trained with on-the-fly random degradation. Input is resized to 128x128 and the output is returned at that resolution, whatever the input size โ this restores small tiles, it is not a full-resolution filter. Reduces but does not fully eliminate noise on complex, high-detail scenes.
Requires: pip install olaverse[vision]
Quick start
denoiser = PrismDenoiser() denoiser.denoise("noisy.jpg").save("denoised.jpg")
Methods:¶
denoise ¶
Remove noise/blur/compression artifacts from an image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
'str | os.PathLike | Image.Image'
|
Path to an image file, or a PIL.Image. Resized to 128x128. |
required |
Returns:
| Type | Description |
|---|---|
'Image.Image'
|
PIL.Image: the denoised image, always 128x128 regardless of input size. |
PrismSteganography โ Hide/Recover Messages¶
Model Card: olaverse/prism-steganography
Hides a recoverable message (up to 8 ASCII characters / 64 bits) inside a cover image imperceptibly, using a jointly-trained U-Net encoder / CNN decoder pair. A differentiable noise layer sits between them at train time (blur, sensor noise, JPEG-like compression, pixel dropout).
Save as PNG โ JPEG destroys the message
The hidden bits do not survive a real JPEG round-trip at any quality setting, including quality=100, and do not survive rescaling. Always write the stego image to a lossless format, and decode it at 128x128 without an intermediate resize.
from olaverse import PrismSteganography
steg = PrismSteganography()
stego_image = steg.hide("cover.jpg", "hi there")
stego_image.save("stego.png") # PNG โ a .jpg save loses the message
steg.reveal(stego_image)
# โ 'hi there'
Images are resized to 128x128 internally; longer messages are silently truncated to 8 characters. Capacity is read from the checkpoint's msg_bits config (currently 64 bits). Truncation is applied to the UTF-8 bytes, so a non-ASCII message can be cut mid-character and come back with replacement characters โ treat the channel as ASCII-only.
Measured robustness โ lossless only
Recovery is exact (100% bit-accuracy) in memory, through a PNG round-trip, and under mild additive noise (Gaussian ฯ=5). It collapses to chance under the two most common real-world transforms:
| Condition | Bit accuracy |
|---|---|
| In-memory / PNG round-trip | 1.00 |
| Gaussian noise, ฯ=5 | 1.00 |
JPEG, quality=100 |
0.48 |
JPEG, quality=95 |
0.45 |
JPEG, quality=75 |
0.42 |
| Downscale to 64x64 and back | 0.50 |
Whatever JPEG approximation was used in the training noise layer did not transfer to real JPEG encoding. Treat this as a lossless-channel watermark, not a distortion-robust one. No error-correction coding is applied on top of the raw bits โ applications that need near-100% reliability should add redundancy (e.g. a repetition or Hamming code) on top of the raw bit channel, and even that will not rescue a JPEG round-trip.
olaverse.vision.PrismSteganography ¶
Hide/recover a short recoverable message inside an image.
Wraps olaverse/prism-steganography โ a U-Net encoder / CNN decoder pair. Message capacity comes from the checkpoint's msg_bits config (currently 64 bits = 8 ASCII characters); longer input is silently truncated over UTF-8 bytes, so non-ASCII messages can be cut mid-character. Images are resized to 128x128.
Save stego images as PNG. The hidden bits survive a lossless round-trip and mild additive noise, but are destroyed by JPEG at any quality (including quality=100) and by rescaling โ recovery drops to chance.
Requires: pip install olaverse[vision]
Quick start
steg = PrismSteganography() stego_image = steg.hide("cover.jpg", "hi there") stego_image.save("stego.png") # PNG, not JPEG steg.reveal(stego_image) 'hi there'
Methods:¶
hide ¶
Hide a short message inside a cover image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
'str | os.PathLike | Image.Image'
|
Path to an image file, or a PIL.Image. Resized to 128x128. |
required |
message
|
str
|
Up to 8 ASCII characters โ longer input is truncated. |
required |
Returns:
| Type | Description |
|---|---|
'Image.Image'
|
PIL.Image: the stego image with the message hidden inside. Save it |
'Image.Image'
|
losslessly (PNG); a JPEG save destroys the hidden message. |
reveal ¶
Recover a hidden message from a stego image.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
image
|
'str | os.PathLike | Image.Image'
|
Path to an image file, or a PIL.Image. Must be a lossless copy of the stego image โ JPEG or rescaled input decodes to noise. |
required |
Returns:
| Name | Type | Description |
|---|---|---|
str |
str
|
the recovered message. |