Motion Blur Filters
Motion Blur Custom Kernel Filter in Python
You can create a custom kernel by placing elements in a specific way, like along a horizontal line. In this setup, the central pixel value is figured out by looking at the average of these pixels, creating the 'Motion Blur' effect. When certain elements have higher importance, they impact the final pixel value more in the Motion Blur effect. Making sure the total of all these elements adds up to 1 helps keep the original brightness of the picture. The freedom to arrange elements in different directions lets you make various motion effects in the image.
# custom MotionBlur horizontal 7x7 kernel
[
[ 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0 ],
[ 0.15, 0.15, 0.15, 0.1, 0.15, 0.15, 0.15],
[ 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0 ],
[ 0, 0, 0, 0, 0, 0, 0 ],
]
This effect imitates the case of a camera moving horizontally while capturing a photo, generating the illusion of motion in the image.


Python code example
The provided Python code example demonstrates how to utilize the Aspose.Imaging Python API. You can use the `ConvolutionFilter` class, which provides pre-defined kernel filters like get_blur_motion() with customizable size and angle parameters. Moreover, you retain the freedom to design your custom kernel matrix. In this instance, image templates in raster PNG and as well as vector SVG formats are loaded from the "templates" directory, and a set of filters is applied from the `kernel_filters` list.
import os, random | |
import aspose.pycore as aspycore | |
from aspose.imaging import Image, RasterImage, VectorImage | |
from aspose.imaging.imagefilters.complexutils import Complex | |
from aspose.imaging.imagefilters.convolution import * | |
from aspose.imaging.imagefilters.filteroptions import * | |
if 'TEMPLATE_DIR' in os.environ: | |
templates_folder = os.environ['TEMPLATE_DIR'] | |
else: | |
templates_folder = r"C:\Users\USER\Downloads\templates" | |
delete_output = 'SAVE_OUTPUT' not in os.environ | |
def delete_file(file): | |
if delete_output: | |
os.remove(file) | |
# Example code: | |
def filter(raster, options, output_path): | |
raster.filter(raster.bounds, options) | |
raster.save(output_path) | |
def get_random_kernel(cols, rows): | |
custom_kernel = [0.0] * (cols * rows) | |
for y in range(rows): | |
for x in range(cols): | |
custom_kernel[y*cols + x] = random.random() | |
return custom_kernel | |
size: int = 5 | |
sigma: float = 1.5 | |
angle: float = 45 | |
custom_kernel = get_random_kernel(size, 7) | |
custom_complex = ConvolutionFilter.to_complex(custom_kernel) | |
kernel_filters = [ | |
# convolution filters | |
ConvolutionFilterOptions(ConvolutionFilter.get_emboss_3x3()), | |
ConvolutionFilterOptions(ConvolutionFilter.get_emboss_5x5()), | |
ConvolutionFilterOptions(ConvolutionFilter.get_sharpen_3x3()), | |
ConvolutionFilterOptions(ConvolutionFilter.get_sharpen_5x5()), | |
ConvolutionFilterOptions(ConvolutionFilter.get_blur_box(size)), | |
ConvolutionFilterOptions(ConvolutionFilter.get_blur_motion(size, angle)), | |
ConvolutionFilterOptions(ConvolutionFilter.get_gaussian(size, sigma)), | |
ConvolutionFilterOptions(custom_kernel), | |
GaussianBlurFilterOptions(size, sigma), | |
SharpenFilterOptions(size, sigma), | |
MedianFilterOptions(size), | |
# deconvolution filters | |
DeconvolutionFilterOptions(ConvolutionFilter.get_gaussian(size, sigma)), | |
DeconvolutionFilterOptions(custom_kernel), | |
DeconvolutionFilterOptions(custom_complex), | |
GaussWienerFilterOptions(size, sigma), | |
MotionWienerFilterOptions(size, sigma, angle) | |
] | |
data_dir = templates_folder | |
input_paths = [ | |
os.path.join(data_dir, "template.png"), | |
os.path.join(data_dir, "template.svg") | |
] | |
outputs = [] | |
for input_path in input_paths: | |
for i, options in enumerate(kernel_filters): | |
with Image.load(input_path) as image: | |
output_path = f"{input_path}-{i}.png" | |
if aspycore.is_assignable(image, RasterImage): | |
raster = aspycore.as_of(image, RasterImage) | |
filter(raster, options, output_path) | |
outputs.append(output_path) | |
elif aspycore.is_assignable(image, VectorImage): | |
vector = aspycore.as_of(image, VectorImage) | |
vector_as_png = input_path + ".png" | |
if not os.path.exists(vector_as_png): | |
vector.save(vector_as_png) | |
outputs.append(vector_as_png) | |
with Image.load(vector_as_png) as png: | |
filter(aspycore.as_of(png, RasterImage), options, output_path) | |
outputs.append(output_path) | |
# Removing all output files | |
for p in outputs: | |
delete_file(p) |