鱼C论坛

 找回密码
 立即注册
12
返回列表 发新帖
楼主: wgij007

[已解决]请问怎样按色差抠图

[复制链接]
发表于 2022-8-26 23:43:57 | 显示全部楼层
wgij007 发表于 2022-8-26 23:34
这个PIC文件夹里有图片的。
  这个没有图片,空的

看一下pic和result两个目录下面有什么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-26 23:46:49 | 显示全部楼层
我的问题,抱歉
    shutil.rmtree("result/" + filename, ignore_errors = True)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-8-27 00:35:35 | 显示全部楼层

可以了,但每张图都一个独立文件夹整合还要做多一次,如都在一个文件夹最好了。还是非常感谢。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-27 00:45:48 | 显示全部楼层
wgij007 发表于 2022-8-27 00:35
可以了,但每张图都一个独立文件夹整合还要做多一次,如都在一个文件夹最好了。还是非常感谢。
#!/usr/bin/env python
#coding=utf-8

from PIL import Image
import numpy as np
import sys
from glob import glob
import os

bg_color = (0, 0, 0xfe)

def max(a, b): return a if a > b else b
def min(a, b): return a if a < b else b

def is_background(pic, y, x, tolerance = 0x30):
    color = pic.getpixel((x, y))
    for i in range(3):
        if bg_color[i] + tolerance < color[i]: return False
        if bg_color[i] - tolerance > color[i]: return False
    return True

def is_contain(location, y, x):
    for i in location:
        if (i[0] <= x <= i[2]) and (i[1] <= y <= i[3]): return True
    return False

def find_block_sub(pic, y, x, buff):
    if is_background(pic, y, x): return None
    if buff[y][x]: return None
    result = [x, y, x, y]
    buff[y][x] = 1
    for i in [[0, -1], [-1, 0], [0, 1], [1, 0]]:
        temp = find_block_sub(pic, y + i[0], x + i[1], buff)
        if temp:
            result[0] = min(result[0], temp[0])
            result[1] = min(result[1], temp[1])
            result[2] = max(result[2], temp[2])
            result[3] = max(result[3], temp[3])
    #buff[y][x] = 0     # 我感觉不复位,对这个程序也问题不大
    return result

def find_block(pic, y, x, size): return find_block_sub(pic, y, x, np.zeros(size))

def format(location, margin = 5):
    for i in location:
        i[0] -= margin
        i[1] -= margin
        i[2] += margin
        i[3] += margin
        width = i[2] - i[0]
        height = i[3] - i[1]
        distance = abs(width - height) / 2
        if width == height: continue
        if width > height:
            i[1] -= distance
            i[3] += distance
        else:
            i[0] -= distance
            i[2] += distance

def generate_pic(result_path, filename):
    location = []
    pic = Image.open(filename)
    width, height = pic.size
    for y in range(height):
        for x in range(width):
            if not is_background(pic, y, x):
                if not is_contain(location, y, x):
                    location.append(find_block(pic, y, x, (height, width)))

    format(location)
    for i in range(len(location)):
        pic.crop(location[i]).save(result_path + "_" + str(i) + ".jpg")

sys.setrecursionlimit(10000)
for i in glob("pic/*.jpg"):
    filename = os.path.splitext(os.path.split(i)[-1])[0]
    generate_pic("result/" + filename, i)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-8-27 08:16:44 | 显示全部楼层

真的非常感谢,只是刚学有点东东不怎么好理解,有的事还真的会的不难,不会的就是不会,可能一点点都会搞好久。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-8-27 10:22:11 | 显示全部楼层

老大,抠出来的图好多差一1的,如33*34 或 40*39 , 还有靠边那种,补的是黑色的。能补回RGB设定的色吗。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-27 12:39:59 | 显示全部楼层
wgij007 发表于 2022-8-27 10:22
老大,抠出来的图好多差一1的,如33*34 或 40*39 , 还有靠边那种,补的是黑色的。能补回RGB设定的色吗。

?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-8-27 21:11:20 | 显示全部楼层

正常应该是正矩形的,如50*50那样,便抠出来的是50*49或49*50那个,差一像素。还有刚好在边上,那边上那条边就会有一条黑边图,就是补回去的图。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-7 00:01:18 | 显示全部楼层

20220906.jpg

老大,出现这种内侧有同色的就不抠出来了,不用处理内侧,就把黄色与内孔一起抠出(如图),有办法解决吗。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-9-7 01:03:15 | 显示全部楼层
wgij007 发表于 2022-9-7 00:01
老大,出现这种内侧有同色的就不抠出来了,不用处理内侧,就把黄色与内孔一起抠出(如图),有办法解 ...

不应该,我写代码的时候考虑过这种情况的

tmp.zip (65.11 KB, 下载次数: 1)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-7 23:08:16 | 显示全部楼层
人造人 发表于 2022-9-7 01:03
不应该,我写代码的时候考虑过这种情况的

感谢老大,还是好多不明,慢慢学了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-19 23:27:28 | 显示全部楼层
人造人 发表于 2022-9-7 01:03
不应该,我写代码的时候考虑过这种情况的

xxx.jpg

老大为什么这样的图失败呢。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-9-19 23:58:57 | 显示全部楼层
wgij007 发表于 2022-9-19 23:27
老大为什么这样的图失败呢。

调试程序呀
#!/usr/bin/env python
#coding=utf-8

from PIL import Image
import numpy as np
import sys

bg_color = (0, 0, 0xfe)

def max(a, b): return a if a > b else b
def min(a, b): return a if a < b else b

def is_background(pic, y, x, tolerance = 0x30):
    color = pic.getpixel((x, y))
    for i in range(3):
        if bg_color[i] + tolerance < color[i]: return False
        if bg_color[i] - tolerance > color[i]: return False
    return True

def is_contain(location, y, x):
    for i in location:
        if (i[0] <= x <= i[2]) and (i[1] <= y <= i[3]): return True
    return False

def find_block_sub(y, x, buff):
    if is_background(pic, y, x): return None
    if buff[y][x]: return None
    result = [x, y, x, y]
    buff[y][x] = 1
    for i in [[0, -1], [-1, 0], [0, 1], [1, 0]]:
        temp = find_block_sub(y + i[0], x + i[1], buff)
        if temp:
            result[0] = min(result[0], temp[0])
            result[1] = min(result[1], temp[1])
            result[2] = max(result[2], temp[2])
            result[3] = max(result[3], temp[3])
    #buff[y][x] = 0     # 我感觉不复位,对这个程序也问题不大
    return result

def find_block(y, x): return find_block_sub(y, x, np.zeros((height, width)))

def format(location, margin = 5):
    for i in location:
        i[0] -= margin
        i[1] -= margin
        i[2] += margin
        i[3] += margin
        width = i[2] - i[0]
        height = i[3] - i[1]
        distance = abs(width - height) / 2
        if width == height: continue
        if width > height:
            i[1] -= distance
            i[3] += distance
        else:
            i[0] -= distance
            i[2] += distance


old_pic = Image.open("pic.jpg")
new_pic = Image.new("RGB", old_pic.size)
width, height = old_pic.size
for y in range(height):
    for x in range(width):
        if not is_background(old_pic, y, x):
            new_pic.putpixel((x, y), (255, 255, 255))
new_pic.save("new_pic.png")

exit(1)

sys.setrecursionlimit(1000000)
location = []
pic = Image.open("pic.jpg")
width, height = pic.size
for y in range(height):
    for x in range(width):
        if not is_background(pic, y, x):
            if not is_contain(location, y, x):
                location.append(find_block(y, x))

format(location)
for i in range(len(location)):
    pic.crop(location[i]).save(str(i) + ".png")

new_pic.png


上面的代码生成了这样一张图片,说明了什么问题?
说明 is_background 函数有问题
查看一下 pic.jpg 的背景色是 183cdb
所以 is_background 函数有什么问题呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-20 08:16:18 | 显示全部楼层

非常感谢,我找了很久,大约找到位置,看不明是怎样算了。主要还是不会。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-20 16:28:28 | 显示全部楼层

老大,你这个程序把要抠的删了,不是把图抠出来。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-9-20 19:58:01 | 显示全部楼层
wgij007 发表于 2022-9-20 16:28
老大,你这个程序把要抠的删了,不是把图抠出来。

所以为什么会这样呢?
是不是 is_background 函数的问题?
那就修改这个函数
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-20 22:02:40 | 显示全部楼层
人造人 发表于 2022-9-20 19:58
所以为什么会这样呢?
是不是 is_background 函数的问题?
那就修改这个函数

好的,谢谢,我试试
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-22 08:18:35 | 显示全部楼层

老大,能不能再帮一下,搞不了呀,新的程序 有几个DEF 没用了, 后面那段也是用一个跳过去了。。
new_pic.putpixel((x, y), (255, 255, 255))  这段不明怎样改
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-9-22 09:18:13 | 显示全部楼层
wgij007 发表于 2022-9-22 08:18
老大,能不能再帮一下,搞不了呀,新的程序 有几个DEF 没用了, 后面那段也是用一个跳过去了。。
new_pi ...

这一段程序是用来调试的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-9-22 22:31:04 | 显示全部楼层
人造人 发表于 2022-9-22 09:18
这一段程序是用来调试的

好的,再试试,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-1-10 17:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表