裁剪图片的纯色背景

裁剪图片的纯色背景

前段时间遇到裁剪图片背景的需求,在网上找了好多方案,有的代码可以裁剪,但是不够准确。后来借鉴同事的思路,我自己写了这个功能。目前可以处理纯色的背景,返回一张裁剪后的图片。

具体实现思路:

  1. 比如一张背景为白色的图片,我们要找到有效图,那么可以考虑到白色与有效图边缘像素rgb的图片,(例如:可能从760左右瞬间变为300多),这时候我们通过对x、y方向上像素的遍历,得到rgb的和,就能判断出哪里是像素rgb突变点,进而也可以很容易的拿到突变点坐标。
  2. 我的代码中,y方向上只遍历了8个坐标点(即把height分为8份),具体情况按照自己的情况来定。
  3. 方法中参数需要根据情况来调整,不能照搬。
  4. 每个宽度上或者高度上,我取的是整个宽度或高度所有像素点rgb和的平均值。

现在把代码贴在下面:

from PIL import Image
import cv2
import os
from common.util import Util


# 图片去除周围白色
def img_cut_white(img_path, cut_img_path, tagrt_rgb_x, tagrt_rgb_y):
    # img_path = "./images/notebook.png"
    img = Image.open(img_path)
    rgb_im = img.convert('RGB')
    width, height = img.size
    # 打印图片的宽高
    print(width, height)

    # 把高度分为8份,后续用这8个点高度作为高度循环
    list_target_height = [height / 8, height / 4, 3 * height / 8, height / 2, 5 * height / 8, 3 * height / 4]

    x0,x1 = get_pointx(bypara="1",width=width,height=height,list_target_height=list_target_height,rgb_im=rgb_im,tagrt_rgb=tagrt_rgb_x)
    y0, y1 = get_pointx(bypara="2", width=width, height=height, list_target_height=list_target_height, rgb_im=rgb_im,
                        tagrt_rgb=tagrt_rgb_y)

    print(x0, x1)
    print(y0, y1)


    # 按照两个对角像素点切割图片
    Util().cut_img_by_point(img_path=img_path,x0=x0,x1=x1,y0=y0,y1=y1,cut_img_path=cut_img_path)


# 获取x0,x1,y0,y1
def get_pointx(bypara=None,width=None,height=None,list_target_height=None,rgb_im=None,tagrt_rgb=None):
    '''
    :param bypara: 1代表进行获取x0,x1的逻辑,2代表进行获取y0,y1的逻辑
    :param width: 图片宽度
    :param height: 图片高度
    :param list_target_height:
    :param rgb_im: 转换为“RGB”通道的图片
    :param tagrt_rgb: rgb突变范围值
    :return:
    '''
    x0 = 0
    x1 = 0
    y0 = 0
    y1 = 0
    # 多个目标高度,每个像素点的rgb之和
    multi_point_rgb_sum = 0
    # 多个目标高度像素点的所有像素点rgb总和的平均值
    list_rgb_sum_avg = []

    if bypara == '1':
        for i in range(width):
            for j in range(len(list_target_height)):
                # print("i:",i)
                # print("list_target_height[j]:",list_target_height[j])
                r, g, b = rgb_im.getpixel((i, list_target_height[j]))
                # 一个点的rgb和
                point_sum = r + g + b
                multi_point_rgb_sum += point_sum
                # print(point_sum, multi_point_rgb_sum)
            list_rgb_sum_avg.append(multi_point_rgb_sum / 6)
            multi_point_rgb_sum = 0

        # 与白色背景图像的差值list
        list_white_sub = get_listwhitesub(list_rgb_sum_avg)
        list_white_sub_dup = list_white_sub.copy()
        list_white_sub.reverse()

        # 获得x0
        for i in range(len(list_white_sub_dup)):
            if list_white_sub_dup[i] > tagrt_rgb:
                x0 = i
                break

        # 获得x1
        for i in range(len(list_white_sub)):
            # print(list_white_sub[i])
            if list_white_sub[i] > tagrt_rgb:
                x1 = (width - i)
                break

        return x0, x1


    elif bypara == '2':
        for i in range(height):
            for j in range(width):
                r, g, b = rgb_im.getpixel((j, i))
                # r, g, b = rgb_im.getpixel(j, i)
                # 一个点的rgb和
                point_sum = r + g + b
                multi_point_rgb_sum += point_sum
                # print(point_sum, multi_point_rgb_sum)
            list_rgb_sum_avg.append(multi_point_rgb_sum / width)
            multi_point_rgb_sum = 0

        # 与白色背景图像的差值list
        list_white_sub = get_listwhitesub(list_rgb_sum_avg)
        list_white_sub_dup = list_white_sub.copy()
        list_white_sub.reverse()

        # 获得y0
        for i in range(len(list_white_sub_dup)):
            if list_white_sub_dup[i] > tagrt_rgb:
                y0 = i
                break
        # 获得y1
        for i in range(len(list_white_sub)):
            # print(list_white_sub[i])
            if list_white_sub[i] > tagrt_rgb:
                y1 = (height - i)
                break

        return y0, y1





# 获得list中相邻元素的差值list
def get_listsub(list2):
    list3 = []
    for i in range(len(list2)):
        if i <= len(list2) - 2:
            cha = list2[i + 1] - list2[i]
            list3.append(abs(cha))
    return list3



# 与白色rgb的差值 list
def get_listwhitesub(list2):
    list3 = []
    for i in range(len(list2)):
        list3.append(abs(list2[i]-765))
    return list3






if __name__=="__main__":
    # img_path = "./images/notebook.png"
    # cut_img_path = './images/notebookcut4.png'
    tagrt_rgb_x = 155
    tagrt_rgb_y = 20
    # tagrt_rgb_x = 180
    # tagrt_rgb_y = 180
    # img_path = "../images/UIyuantu.png"
    # cut_img_path = '../images/yuantucut0.png'

    img_path = "../images/destpng5421045/images_0.png"
    cut_img_path = '../images/cut0.png'
    img_cut_white(img_path, cut_img_path, tagrt_rgb_x, tagrt_rgb_y)

注意:这个代码是基于背景为白色的图片来做的测试,如果你想换成其他背景的图片来测试的话,可以将get_listwhitesub 方法中的765改成自己的背景颜色

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

anmu4200

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值