Python script to identify watermarks based on pixel color

The following Python script can be used to identify watermarks in images based on pixel color. It checks if the percentage of pixels that match a specified color exceeds a given threshold.

OpenCV variant

#!/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()
#!/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()