Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Python] 简单实现将红印章从白底中抠出来效果 #34

Open
yangruihan opened this issue Dec 31, 2020 · 1 comment
Open

[Python] 简单实现将红印章从白底中抠出来效果 #34

yangruihan opened this issue Dec 31, 2020 · 1 comment

Comments

@yangruihan
Copy link
Owner

简单实现将红印章从白底中抠出来效果

问题描述

想把红色印章从白底中抠出来,用 PS 当然效果可能更好,不过由于本人 PS 不是很熟,所以就用 Python 处理了一下,效果也还不错,分享记录一下

解决方案

通过制定一些规则来过滤某些像素,比如白色像素直接删除,红色像素保留等

开发环境:

  • macOS:10.15.4
  • Python:3.8.5
  • Pillow: 8.0.1

源码如下:

#!/usr/bin/env python3
# -*- coding:utf8 -*-

import os

from PIL import Image
im = Image.open('test.png')  # 打开图片
pix = im.load()  # 导入像素
width = im.size[0]  # 获取宽度
height = im.size[1]  # 获取长度

dir = [(1, 0), (0, -1), (-1, 0), (0, 1)]


def is_red(r, g, b):
    """
    判断是否为红色
    """
    return r > 200 and g < 200 and b < 200


pixel_list = []

for x in range(width):
    for y in range(height):

        pixel = im.getpixel((x, y))
        r, g, b = pixel
        a = 1
        if len(pixel) > 3:
            a = pixel[3]

        if a == 0: # 如果当前像素是透明的,则保持
            pixel_list.append(((x, y), (0, 0, 0, 0)))
        elif r == g == b: # 如果当前颜色是灰色,则删除
            pixel_list.append(((x, y), (0, 0, 0, 0)))
        elif is_red(r, g, b): # 如果当前颜色是红色,则保留
            pixel_list.append(((x, y), (r, g, b, a)))
        elif r >= 220 and g >= 220 and b >= 220: # 如果当前颜色接近白色,则删除
            pixel_list.append(((x, y), (0, 0, 0, 0)))
        else:
            # 取周围像素值来决定当前颜色
            color = (0, 0, 0, 0)
            count = 0
            for d in dir:
                nx, ny = x + d[0], y + d[1]
                if nx >= 0 and nx < width and ny >= 0 and ny < height:
                    count += 1
                    nc = im.getpixel((nx, ny))

                    if len(nc) > 3 and nc[3] == 0:
                        color = (0, 0, 0, 0)
                        break
                    elif is_red(nc[0], nc[1], nc[2]):
                        color = nc
                        break

            pixel_list.append(((x, y), color))

for item in pixel_list:
    im.putpixel(item[0], item[1])

im = im.convert('RGBA')
im.save('ret.png')

效果如下:

原图(来源于网络,图侵删):

image

处理后(黑色为透明部分):

image

@yangruihan
Copy link
Owner Author

坚持原创、翻译技术文章心得体会日常笔记,您的支持将鼓励我继续创作!

感谢你的阅读,如果文章对你有帮助,你可以选择打赏~

image
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant