Python 脚本:基于像素颜色识别水印

以下 Python 脚本可用于基于像素颜色识别图像中的水印。它检查匹配指定颜色的像素百分比是否超过给定阈值。

OpenCV 版本

watermark_detector_opencv.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
import cv2
import sys

def parse_html_color(s):
    s = s.lstrip('#')
    if len(s) != 6:
        raise ValueError("Color must be in format #RRGGBB")
    return tuple(int(s[i:i+2], 16) for i in (0, 2, 4))

def fraction_color_pixels(image_path, target_rgb):
    img = cv2.imread(image_path)
    if img is None:
        raise FileNotFoundError(f"Could not open image: {image_path}")
    img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    mask = (img_rgb[:, :, 0] == target_rgb[0]) & \
           (img_rgb[:, :, 1] == target_rgb[1]) & \
           (img_rgb[:, :, 2] == target_rgb[2])
    count = mask.sum()
    total = img_rgb.shape[0] * img_rgb.shape[1]
    return count / total if total > 0 else 0

def main():
    parser = argparse.ArgumentParser(description="Compute the fraction of pixels with a given color in an image.")
    parser.add_argument("image", help="Path to the image file")
    parser.add_argument("-t", "--threshold", type=float, default=0.05,
                        help="Threshold fraction (default: 0.05 for 5%%)")
    parser.add_argument("--color", default="#6f7918",
                        help="HTML color string to match (default: #6f7918)")
    args = parser.parse_args()

    try:
        target_rgb = parse_html_color(args.color)
    except ValueError as e:
        print(f"Invalid color: {e}")
        sys.exit(2)

    fraction = fraction_color_pixels(args.image, target_rgb)
    print(fraction)

    if fraction > args.threshold:
        print("Threshold exceeded")
        sys.exit(1)
    else:
        print("Below threshold")
        sys.exit(0)

if __name__ == "__main__":
    main()

PIL 版本(较慢,不推荐)

watermark_detector_pil.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import argparse
from PIL import Image
import sys

def parse_html_color(s):
    s = s.lstrip('#')
    if len(s) != 6:
        raise ValueError("Color must be in format #RRGGBB")
    return tuple(int(s[i:i+2], 16) for i in (0, 2, 4))

def fraction_color_pixels(image_path, target_rgb):
    img = Image.open(image_path).convert('RGB')
    pixels = list(img.getdata())
    total = len(pixels)
    count = sum(1 for pixel in pixels if pixel == target_rgb)
    return count / total if total > 0 else 0

def main():
    parser = argparse.ArgumentParser(description="Compute the fraction of pixels with a given color in an image.")
    parser.add_argument("image", help="Path to the image file")
    parser.add_argument("-t", "--threshold", type=float, default=0.05,
                        help="Threshold fraction (default: 0.05 for 5%%)")
    parser.add_argument("--color", default="#6f7918",
                        help="HTML color string to match (default: #6f7918)")
    args = parser.parse_args()

    try:
        target_rgb = parse_html_color(args.color)
    except ValueError as e:
        print(f"Invalid color: {e}")
        sys.exit(2)

    fraction = fraction_color_pixels(args.image, target_rgb)
    print(fraction)

    if fraction > args.threshold:
        print("Threshold exceeded")
        sys.exit(1)
    else:
        print("Below threshold")
        sys.exit(0)

if __name__ == "__main__":
    main()

Check out similar posts by category: Python