You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python实现Photoshop式色阶调整(黑场值设为13)

实现Photoshop色阶调整(黑场设为13)的Python方案

Absolutely! You can totally replicate Photoshop's Levels adjustment (specifically setting the black point to 13) using scikit-image, OpenCV, or even plain NumPy—all perfect for batch processing. Let's walk through each approach with practical code examples you can adapt for bulk edits.

1. 基础方案:NumPy + Pillow

This approach gives you full control over the pixel math, mirroring exactly what Photoshop does when you drag the black point slider to 13: all pixels darker than 13 get crushed to pure black, and the remaining pixel range (13–255) gets stretched linearly to fill 0–255.

import numpy as np
from PIL import Image
import os

def set_black_point(image_path, output_path, black_point=13):
    # Open image and convert to numpy array
    img = Image.open(image_path).convert("RGB")
    img_array = np.array(img, dtype=np.float32)
    
    # Crush pixels below black point to 0
    img_array[img_array < black_point] = 0
    # Stretch remaining values to fill 0-255
    scale_factor = 255 / (255 - black_point)
    img_array = img_array * scale_factor
    # Ensure values stay within valid pixel range and convert back to uint8
    img_array = np.clip(img_array, 0, 255).astype(np.uint8)
    
    # Save processed image
    Image.fromarray(img_array).save(output_path)

# Batch processing example
input_folder = "your_input_directory"
output_folder = "your_output_directory"
os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(input_folder):
    if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        input_path = os.path.join(input_folder, filename)
        output_path = os.path.join(output_folder, filename)
        set_black_point(input_path, output_path)

2. OpenCV方案

If your workflow already uses OpenCV, this implementation follows the same logic—just remember to handle the BGR-to-RGB color channel conversion (OpenCV reads images in BGR by default).

import cv2
import numpy as np
import os

def adjust_black_point_cv2(image_path, output_path, black_point=13):
    img = cv2.imread(image_path)
    # Convert BGR to RGB for consistent processing (optional, skip if working with BGR)
    img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    
    img_float = img.astype(np.float32)
    # Apply black point adjustment
    img_float[img_float < black_point] = 0
    scale_factor = 255 / (255 - black_point)
    img_float = img_float * scale_factor
    img_processed = np.clip(img_float, 0, 255).astype(np.uint8)
    
    # Convert back to BGR for saving with OpenCV
    img_processed_bgr = cv2.cvtColor(img_processed, cv2.COLOR_RGB2BGR)
    cv2.imwrite(output_path, img_processed_bgr)

# Batch processing
input_folder = "your_input_directory"
output_folder = "your_output_directory"
os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(input_folder):
    if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        adjust_black_point_cv2(os.path.join(input_folder, filename),
                               os.path.join(output_folder, filename))

3. scikit-image方案

scikit-image has a built-in function exposure.rescale_intensity that handles the pixel stretching automatically, making this the most concise option.

from skimage import io, exposure
import numpy as np
import os

def adjust_black_point_skimage(image_path, output_path, black_point=13):
    img = io.imread(image_path)
    # Convert to uint8 if image is read as float (0-1 range)
    if img.dtype != np.uint8:
        img = (img * 255).astype(np.uint8)
    
    # Rescale intensity: map [black_point, 255] to [0, 255]
    img_processed = exposure.rescale_intensity(img, in_range=(black_point, 255), out_range=(0, 255))
    
    io.imsave(output_path, img_processed)

# Batch processing
input_folder = "your_input_directory"
output_folder = "your_output_directory"
os.makedirs(output_folder, exist_ok=True)

for filename in os.listdir(input_folder):
    if filename.lower().endswith(('.png', '.jpg', '.jpeg')):
        adjust_black_point_skimage(os.path.join(input_folder, filename),
                                   os.path.join(output_folder, filename))

Quick Notes

  • All these methods produce identical results to Photoshop's Levels adjustment with black point set to 13.
  • For grayscale images, simply remove any color channel conversion code.
  • Add a progress bar (e.g., using tqdm) to track batch processing for large image sets.

内容的提问来源于stack exchange,提问作者anon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 08:52:39