python实现误差扩散、Floyd-Steinberg 抖动、有序抖动、Riemersma 抖动算法

1.误差扩散算法详解

误差扩散算法(Error Diffusion Algorithm)是一种用于图像抖动(Dithering)和半色调(Halftoning)的技术。它通过将像素的量化误差扩散到邻近像素,从而在整体上保持图像的灰度特性。这种方法通常用于图像打印和显示,特别是将灰度图像转换为二值图像时。

算法步骤
  1. 遍历图像:逐像素处理图像,从左到右,从上到下。
  2. 量化像素:将当前像素的灰度值量化为目标值(通常是0或255)。
  3. 计算误差:计算当前像素的量化误差。
  4. 扩散误差:将误差分配给邻近像素。

常见的误差扩散算法有:

  • Floyd-Steinberg算法
  • Jarvis, Judice, and Ninke算法
  • Stucki算法
Floyd-Steinberg 算法

Floyd-Steinberg 算法是最常用的误差扩散算法之一。其扩散矩阵如下:

在这里插入图片描述

这里,* 表示当前处理的像素,其他值表示扩散给邻近像素的误差比例。

公式

在这里插入图片描述

Python 实现

以下是Floyd-Steinberg误差扩散算法的Python实现代码:

import numpy as np
from PIL import Image
import matplotlib.pyplot as plt

def floyd_steinberg_dithering(image):
    """
    Floyd-Steinberg 误差扩散算法实现

    参数:
    image (PIL.Image): 灰度图像

    返回:
    PIL.Image: 二值化后的图像
    """
    # 将图像转换为灰度图像
    grayscale_image = image.convert("L")
    image_array = np.array(grayscale_image, dtype=float)
    
    # 获取图像的行和列
    rows, cols = image_array.shape
    
    # 遍历图像
    for y in range(rows):
        for x in range(cols):
            old_pixel = image_array[y, x]
            new_pixel = 0 if old_pixel < 128 else 255
            image_array[y, x] = new_pixel
            quant_error = old_pixel - new_pixel
            
            if x + 1 < cols:
                image_array[y, x + 1] += quant_error * 7 / 16
            if x - 1 >= 0 and y + 1 < rows:
                image_array[y + 1, x - 1] += quant_error * 3 / 16
            if y + 1 < rows:
                image_array[y + 1, x] += quant_error * 5 / 16
            if x + 1 < cols and y + 1 < rows:
                image_array[y + 1, x + 1] += quant_error * 1 / 16
    
    # 将处理后的数组转换为图像
    dithered_image = Image.fromarray(np.clip(image_array, 0, 255).astype(np.uint8))
    
    return dithered_image

# 示例用法
if __name__ == "__main__":
    image = Image.open('example.jpg')  # 打开原始图像
    dithered_image = floyd_steinberg_dithering(image)  # 调用Floyd-Steinberg误差扩散算法
    dithered_image.show()  # 显示二值化后的图像
    dithered_image.save('dithered_example.jpg')  # 保存二值化后的图像

    # 显示原始图像和二值化后的图像
    plt.figure(figsize=(12, 6))
    plt.subplot(1, 2, 1)
    plt.title('Original Image')
    plt.imshow(image.convert("L"), cmap='gray')
    plt.axis('off')
    
    plt.subplot(1, 2, 2)
    plt.title('Dithered Image')
    plt.imshow(dithered_image, cmap='gray')
    plt.axis('off')
    plt.show()
详细解释
  1. 读取图像和转换为灰度图像

    image = Image.open('example.jpg')
    grayscale_image = image.convert("L")
    
  2. 将灰度图像转换为NumPy数组

    image_array = np.array(grayscale_image, dtype=float)
    
  3. 遍历图像并进行量化和误差扩散

    for y in range(rows):
        for x in range(cols):
            old_pixel = image_array[y, x]
            new_pixel = 0 if old_pixel < 128 else 255
            image_array[y, x] = new_pixel
            quant_error = old_pixel - new_pixel
            
            if x + 1 < cols:
                image_array[y, x + 1] += quant_error * 7 / 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

闲人编程

你的鼓励就是我最大的动力,谢谢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值