【原创】图像无损亮度均衡算法

import glob
import json
import multiprocessing
import os
import time
from concurrent.futures import ThreadPoolExecutor

import cv2
import numpy as np
from matplotlib import pyplot as plt


def load_config(config_path='config.json'):
    with open(config_path, 'r') as file:
        config = json.load(file)
    return config


def enhance_brightness(v, gamma=0.8):
    """
    使用Gamma校正增强图像的亮度。
    参数:
    - v: 一个二维的numpy数组,表示图像的V通道。
    - gamma: Gamma值,小于1可以增亮图像,大于1会使图像变暗。
    返回:
    - 调整后的V通道。
    """
    # 将V通道的数据类型转换为float32以进行计算
    v = v.astype(np.float32)

    # 将V值归一化到[0, 1]
    v_normalized = v / 255.0

    # 应用Gamma校正
    v_corrected = np.power(v_normalized, gamma)

    # 将结果转换回[0, 255]范围内并转换为uint8
    v_enhanced = np.clip(v_corrected * 255, 0, 255).astype(np.uint8)

    return v_enhanced


def sigmoid_special(x, k=1):
    return 1 / (1 + np.exp(-k * x))


def nonlinear_adjust(v):
    avg_v = np.mean(v)
    v_normalized = (v / 255.0 - 0.5) * 10  # 调整尺度和偏移, 第一步均衡,作用是把亮度分为左右两个波峰
    sigmoid = 1 / (1 + np.exp(-v_normalized))
    # Sigmoid 调整
    v_normalized1 = (v / 255.0 - 1) * 25  # 调整尺度和偏移,这一步考虑到质量,作用是把两个亮度波峰尽可能往左右分开
    sigmoid1 = 1 / (1 + np.exp(-v_normalized1))
    new_v = sigmoid1 * (255 - avg_v) + sigmoid * avg_v

    v_normalized3 = (-new_v / 255.0 + 1) * 255 + 1024  # 针对质量的修补
    sigmoid3 = 1 / (1 + np.exp(-v_normalized3))
    new_v = sigmoid3 * new_v


    # 限制值在合理范围内并转换为整数
    return np.clip(new_v, 0, 255).astype(np.uint8)


def process_image(img_path, output_dir, config):
    try:
        basename = os.path.basename(img_path)
        image = cv2.imread(img_path)
        if image is None:
            raise ValueError(f"图像 {img_path} 无法读取或文件不存在")
        hsv = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)
        h, s, v = cv2.split(hsv)

        # 均衡亮度,
        v = nonlinear_adjust(v)

        final_hsv = cv2.merge([h, s, v])
        # plot_histogram(final_hsv)
        final_image = cv2.cvtColor(final_hsv, cv2.COLOR_HSV2BGR)
        output_path = os.path.join(output_dir, basename.replace('.jpg', '_output.png'))

        cv2.imwrite(output_path, final_image)

        # plot_comparison(image, final_image)
        print(f'{img_path} 已处理完毕!')
    except Exception as e:
        print(e)


def plot_histogram(image):
    # 提取 V 通道
    v_channel = image[:, :, 2]

    # 计算 V 通道的直方图
    hist, bins = np.histogram(v_channel.flatten(), bins=256, range=[0, 256])

    # 绘制直方图
    plt.figure(figsize=(8, 6))
    plt.bar(bins[:-1], hist, width=1, color='gray')
    plt.title('Histogram of V Channel')
    plt.xlabel('Value')
    plt.ylabel('Frequency')
    plt.show()


def calculate_loss(original_image, new_image):
    # 计算颜色损失
    color_loss = np.sum(np.abs(original_image.astype(np.float32) - new_image.astype(np.float32)))

    # 计算质量损失(均方误差)
    quality_loss = np.mean((original_image.astype(np.float32) - new_image.astype(np.float32)) ** 2)

    return color_loss, quality_loss


def plot_comparison(original_image, new_image):
    # 计算损失
    color_loss, quality_loss = calculate_loss(original_image, new_image)

    # 创建显示图像
    fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 6))
    ax1.imshow(cv2.cvtColor(original_image, cv2.COLOR_BGR2RGB))
    ax1.axis('off')
    ax1.set_title('Original Image')

    ax2.imshow(cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB))
    ax2.axis('off')
    sum_pixel = np.sum(original_image)
    ax2.set_title(
        'Processed Image\nColor Loss: {:.2f}, Quality Loss (MSE): {:.2f} Total Pixels: {:.2f}'.format(color_loss,
                                                                                                      quality_loss,
                                                                                                      sum_pixel))

    plt.show()


def main():
    config = load_config()
    source_dir = config['input_folder']
    output_dir = config['output_folder']
    if not os.path.exists(output_dir):
        os.makedirs(output_dir)

    images_path = glob.glob(os.path.join(source_dir, '*.jpg'))

    start_time = time.time()
    cpu_cores = max(3, int(multiprocessing.cpu_count() / 2))
    with ThreadPoolExecutor(max_workers=cpu_cores) as executor:
        executor.map(lambda p: process_image(p, output_dir, config), images_path)
    end_time = time.time()
    print(f'Processed all images in {end_time - start_time:.2f}s')


if __name__ == '__main__':
    main()
    # os.system('pause')
{
  "tesseract_path": "E:\\Tesseract-OCR\\tesseract.exe",
  "input_folder": "source_image",
  "output_folder": "output_image",
  "input_path": "input_page",
  "output_path": "output_page",
  "quxijie_path": "quxijie_page",
  "waixiejiaozheng_path": "waixiejiaozheng_page"
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 无损图像压缩算法有很多,其中常见的有: 1. JPEG (Joint Photographic Experts Group):是一种常用的无损图像压缩算法,适用于大多数照片和图像。 2. PNG (Portable Network Graphics):是一种无损图像压缩格式,特别适合用于图形和图像中的透明层。 3. GIF (Graphics Interchange Format):是一种无损图像压缩格式,适用于动画和颜色数量有限的图像。 4. TIFF (Tagged Image File Format):是一种无损图像压缩格式,适用于高质量图像和扫描仪图像。 以上这些算法均有其特定的应用场景,具体选择取决于图像的类型和使用场景。 ### 回答2: 无损图像压缩算法主要包括以下几种: 1. 哈夫曼编码(Huffman Coding):通过统计图像中像素值的频率,将出现频率高的像素值用较短的编码表示,出现频率低的像素值用较长的编码表示,从而实现图像的压缩。 2. 预测编码(Predictive Coding):基于预测像素值的方法,将当前像素值与其相邻像素值之间的差异进行编码,使得重复的信息可以被有效压缩。 3. 差分编码(Differential Coding):将图像中每个像素的值与前一个像素的值之间的差异进行编码,从而减少冗余信息,实现图像的压缩。 4. 等长编码(Run-length Coding):将连续出现的相同像素值序列进行编码,使用像素值和重复的次数来表示,从而实现图像的压缩。 5. 颜色映射编码(Color Mapping Coding):通过将图像的颜色映射到较小的颜色空间中,减少颜色的数量,从而实现图像的压缩。 以上只是常见的无损图像压缩算法,实际应用中还可能有其他算法。每种算法都有其适用的场景和特点,根据不同的需求和压缩效果,可以选择合适的算法进行图像压缩。 ### 回答3: 无损图像压缩算法是指在压缩图像的过程中,保持图像原有的质量,不会出现失真的情况。常见的无损图像压缩算法有以下几种: 1. 预测编码算法:利用像素之间的相关性进行编码,通过对像素值进行预测来减少冗余数据的存储,常见的预测编码算法有差分编码、预测差分编码等。 2. 哈夫曼编码算法:通过对频率较高的符号进行较短的编码,从而减少整个数据的存储空间。哈夫曼编码算法图像中常用于对图像中各个灰度级的出现概率进行编码。 3. 游程编码算法:将连续重复的像素序列以游程的方式来进行编码,从而减少重复的存储数据。游程编码算法适用于对像素值相同的区域进行编码。 4. 基于小波变换的压缩算法:通过对图像进行小波变换,将图像分为低频部分和高频部分,由于图像中的细节信息主要集中在高频部分,可以对高频部分进行较大程度的压缩来减小存储空间。 5. 无损JPEG压缩算法:在JPEG算法的基础上,去掉了量化过程,只保留了离散余弦变换和熵编码等步骤,从而实现无损压缩。这种算法可以保持较高的压缩率和较好的图像质量。 总之,无损图像压缩算法通过对图像中冗余信息和相关性进行处理,从而减小存储空间,同时保持图像的原有质量。不同的无损压缩算法有不同的适用场景,可以根据具体需求选择合适的算法

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值