You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Python3的OpenCV中实现Pinetools网站的Glow发光滤镜效果?

Implementing Pinetools' Glow Effect with Python & OpenCV

Hey there, let's figure out how to replicate that glow effect from Pinetools using Python and OpenCV, based on the Pixastic JavaScript algorithm you're referencing.

First, let's break down what the original JS code actually does—this is why your current attempt isn't matching the expected result:

  • Step 1: Apply a Gaussian blur to the original image (the blur intensity is set by the blurAmount parameter)
  • Step 2: Brighten the blurred image to make that soft, glowing area stand out (controlled by the brightness value)
  • Step 3: Overlay this brightened blur onto the original image using the Screen blend mode (with an opacity parameter to adjust how strong the glow feels)

Your current code only tweaks channel brightness on the blurred image and concatenates it to the original, missing the critical blending step that makes the glow look natural. Here's the full working implementation:

Full Working Code

import cv2
import numpy as np

def apply_glow(image_path, blur_amount=4, brightness=100, opacity=0.7):
    # Load the image (OpenCV uses BGR format by default)
    original = cv2.imread(image_path, cv2.IMREAD_COLOR)
    if original is None:
        raise ValueError("Couldn't load the image—double-check your file path!")
    
    # Step 1: Apply Gaussian Blur
    # We use an odd-sized kernel matching the blur amount (matches Pixastic's behavior)
    kernel_size = (blur_amount * 2 + 1, blur_amount * 2 + 1)
    blurred = cv2.GaussianBlur(original, kernel_size, sigmaX=0)  # Auto-calculate sigma
    
    # Step 2: Brighten the blurred image safely
    # Using convertScaleAbs avoids pixel value overflow issues
    brightened_blur = cv2.convertScaleAbs(blurred, alpha=1, beta=brightness)
    
    # Step 3: Screen Blend Mode + Opacity
    # Convert images to 0-1 float range for calculations
    original_float = original.astype(np.float32) / 255.0
    brightened_float = brightened_blur.astype(np.float32) / 255.0
    
    # Screen blend formula: result = 1 - (1 - src1) * (1 - src2)
    screen_blend = 1 - (1 - original_float) * (1 - brightened_float)
    
    # Mix with original using opacity: original*(1-opacity) + blended*(opacity)
    result_float = (original_float * (1 - opacity)) + (screen_blend * opacity)
    
    # Convert back to 8-bit unsigned integer (0-255)
    result = (result_float * 255).astype(np.uint8)
    
    return original, result

# Example usage
if __name__ == "__main__":
    IMAGE_PATH = "your_image_file.jpg"  # Replace with your image path
    original_img, glow_img = apply_glow(IMAGE_PATH, blur_amount=4, brightness=100, opacity=0.7)
    
    # Show original vs side-by-side with glow effect
    side_by_side = np.concatenate((original_img, glow_img), axis=1)
    cv2.imshow("Original vs Glow Effect", side_by_side)
    cv2.waitKey(0)
    cv2.destroyAllWindows()
    
    # Save the result if needed
    cv2.imwrite("glow_effect_result.jpg", glow_img)

Key Details Explained

  1. Gaussian Blur: We use a kernel size tied to blur_amount to match how the JS algorithm handles blur intensity—this ensures the soft glow spreads the right amount.
  2. Safe Brightening: cv2.convertScaleAbs automatically clamps pixel values to 0-255, which is way more reliable than manually checking for overflow like your original code did.
  3. Screen Blend Mode: This is the magic behind the glow! Screen blending makes bright areas brighter while preserving dark details from the original image, just like the Pinetools effect.
  4. Opacity Control: The opacity parameter lets you dial the glow up or down—higher values make the glow more intense, lower values keep it subtle.

What Was Missing in Your Original Code?

  • You didn't blend the brightened blur back onto the original image—this is the core step that creates the glowing effect instead of just showing a separate bright blur.
  • Your code adjusted red, green, and blue channels by different amounts, but glow effects should brighten all channels evenly for a natural look.
  • Manual overflow checks (like r_n.any() >255) don't work as intended—they set the entire channel to 255 if any pixel exceeds it, instead of clamping individual pixels.

Tweak the blur_amount, brightness, and opacity parameters to match exactly what you see on Pinetools!

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

火山引擎 最新活动