鱼C论坛

 找回密码
 立即注册
查看: 2238|回复: 10

[已解决]60鱼币求助!算法不理解,请各位大佬帮忙看看。

[复制链接]
发表于 2022-8-1 19:03:08 | 显示全部楼层 |阅读模式
60鱼币
图片像素化,算法不理解
from PIL import Image  # 导入图像处理库
# 打开头像图片文件
pic = Image.open("images\image1.jpg")
w_pic, h_pic = pic.size  # 获得图像文件尺寸
px = pic.load()  # 导入图片像素

num = 10 # 小方格的长宽
for i in range(w_pic):
    for j in range(h_pic):
        # 每个格子内取一个代表像素
        I = i - (i%num)/2
        J = j - (j%num)/2
        # 格子内所有像素的颜色都设为代表像素的颜色
        px[i, j] = px[I, J]

for i in range(w_pic):
    for j in range(h_pic):
        # 每个小格子间加一条白色线
        if i % num == 0 or j % num == 0:
            px[i, j] = 255, 255, 255

pic.save('images\\image1_像素化.jpg')
最佳答案
2022-8-1 19:03:09
首先,这段代码的作用是模糊图片,实现方法是将(i,j)位置的像素,修改成(I,J)的像素值。那么先分析一下I,J的计算原理。I = i - (i%num)/2 后一项由于i%num 的取值可以是(0-9) 因此 后一项的取值范围是(0,4.5)。也就是说,I就是i减去一个0-4.5的数字。J同理。这里有一个代码bug,I,J用于索引,因此不可以是小数。建议对I,J进行floor操作向下取整,代码没报错的原因可能是内部做了这个事情,但是还是不要这样写。
接下来简单说一下我对为什么这个可以产生模糊效果的理解。所谓的模糊,在题主的算法里可以大致看出来,是用附近的像素来替换当前像素。我们平常用的高斯模糊也就是对邻域像素取平均值。这两者其实是想通的。高斯模糊是取平均,而你这个算法更直接一些,属于选取单个像素值。他等价于邻域内的像素值有比较极端的权重,被选取的权重为1,其他的为0。至于如何选取,我觉得这里可以近似看成是随机选取。因为不同i.j计算出来的偏移项不同((i%num)/2)。
如果你仔细思考一下,会发现i,j一直是做减法。因此他其实模糊后的图片有会图像上的偏移。整体偏移几个像素。做个实验,如果将num设的更大,模糊效果就会更强,并且偏移效果更明显。

算法模糊后的图片

算法模糊后的图片

原图

原图

最佳答案

查看完整内容

首先,这段代码的作用是模糊图片,实现方法是将(i,j)位置的像素,修改成(I,J)的像素值。那么先分析一下I,J的计算原理。I = i - (i%num)/2 后一项由于i%num 的取值可以是(0-9) 因此 后一项的取值范围是(0,4.5)。也就是说,I就是i减去一个0-4.5的数字。J同理。这里有一个代码bug,I,J用于索引,因此不可以是小数。建议对I,J进行floor操作向下取整,代码没报错的原因可能是内部做了这个事情,但是还是不要这样写。 接下来简单说一下 ...
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-1 19:03:09 | 显示全部楼层    本楼为最佳答案   
首先,这段代码的作用是模糊图片,实现方法是将(i,j)位置的像素,修改成(I,J)的像素值。那么先分析一下I,J的计算原理。I = i - (i%num)/2 后一项由于i%num 的取值可以是(0-9) 因此 后一项的取值范围是(0,4.5)。也就是说,I就是i减去一个0-4.5的数字。J同理。这里有一个代码bug,I,J用于索引,因此不可以是小数。建议对I,J进行floor操作向下取整,代码没报错的原因可能是内部做了这个事情,但是还是不要这样写。
接下来简单说一下我对为什么这个可以产生模糊效果的理解。所谓的模糊,在题主的算法里可以大致看出来,是用附近的像素来替换当前像素。我们平常用的高斯模糊也就是对邻域像素取平均值。这两者其实是想通的。高斯模糊是取平均,而你这个算法更直接一些,属于选取单个像素值。他等价于邻域内的像素值有比较极端的权重,被选取的权重为1,其他的为0。至于如何选取,我觉得这里可以近似看成是随机选取。因为不同i.j计算出来的偏移项不同((i%num)/2)。
如果你仔细思考一下,会发现i,j一直是做减法。因此他其实模糊后的图片有会图像上的偏移。整体偏移几个像素。做个实验,如果将num设的更大,模糊效果就会更强,并且偏移效果更明显。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-8-1 19:04:36 | 显示全部楼层
8-14行 选取每个格子内的代表像素的算法不理解 求助各位大佬
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-1 19:55:19 | 显示全部楼层
本帖最后由 ba21 于 2022-8-1 19:58 编辑

把指定的像素点改成白色,下面为没改前和改后对比图。

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

使用道具 举报

 楼主| 发表于 2022-8-1 20:04:48 | 显示全部楼层
ba21 发表于 2022-8-1 19:55
把指定的像素点改成白色,下面为没改前和改后对比图。

谢谢 但是你这里提到的功能是我上述代码中 16-20 行实现的功能
我不理解的是 8-14行 部分是如何得到区域块代表像素的
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-1 20:12:36 | 显示全部楼层
清芷在沅湘 发表于 2022-8-1 20:04
谢谢 但是你这里提到的功能是我上述代码中 16-20 行实现的功能
我不理解的是 8-14行 部分是如何得到区 ...

在原图每个方块大小为10px*10px中取一个像素点。然后再把大小为10px*10px方块所有像素,改为取到的像素颜色。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-8-1 20:21:38 | 显示全部楼层
ba21 发表于 2022-8-1 20:12
在原图每个方块大小为10px*10px中取一个像素点。然后再把大小为10px*10px方块所有像素,改为取到的像素颜 ...

这个我知道,我想知道的是这个代表像素的颜色是如何通过 8-14行 部分代码找到的?10px*10px范围内的100个像素在最糟糕的情况下可能有100个不同的RGB值,那么该取用哪一个值呢?8-14行 部分代码实现的功能就是找出这个代表值。无法理解这个算法背后的数学原理。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-1 20:29:12 | 显示全部楼层
清芷在沅湘 发表于 2022-8-1 20:21
这个我知道,我想知道的是这个代表像素的颜色是如何通过 8-14行 部分代码找到的?10px*10px范围内的100个 ...

        I = i - (i%num)/2
        J = j - (j%num)/2
这2句你i,j代几个数字进去不就明白它取的是这里的哪一个了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2022-8-1 20:35:39 | 显示全部楼层
ba21 发表于 2022-8-1 20:29
I = i - (i%num)/2
        J = j - (j%num)/2
这2句你i,j代几个数字进去不就明白它取的是这里 ...

我在纸上试过 我也知道在具体情景下是取哪个像素点 但是我想知道的是为什么取到这个点的颜色时可以实现拟合而为什么不是取其他的点  
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-2 09:56:50 | 显示全部楼层
我来抛出几个问题(完全不是像想来解答的样子呢)
第一、这个像素化的方法,好吗?
第二、这个方法能保证一个方格内的取的是代表像素吗?(尤其是那个\2,加上了以后一个方格里的真的是一样的?)
我个人的看法是这个方法真的不是一个很好的选取的方法,只是一个简单实现的方法,目的只是为了在一个方格内选取(至少你给我的式子里甚至不是同一个像素)
如果是选像素点,其实没有很通用的讲究,只要选取的规则一致就可以了。如果是数据特殊的另外考虑
我个人倾向于认为这个式子长这样:i-(i%10)+num/2#取中间的像素,最倾向这个啦,一般不会有什么偏差
或者这样:i-(i%10)#取左上角
或者这样:i-(i%10)+num#取右下角
你说要是对像素的值求和或者用一些高级一点的数学方法得出值,还比较好解释。这里就只是随便挑一个映射吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2022-8-2 10:28:28 | 显示全部楼层
不是回复。请问,这个图片像素化是我学习C语言的原因之一,我想要实现这个功能。请问,在小甲鱼的哪节课才会涉及到这个问题?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

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

本版积分规则

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

GMT+8, 2024-11-17 06:51

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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