图像缩放攻击

今天在B站上看到一个关于图像缩放攻击的挺有意思的视频
他的GitHub上复制了源代码来看了看,原理特别简单,核心就是算出缩放点的位置。

比如说有一个8个元素的列表[1, 1, 1, 1, 1, 1, 1, 1],现在我想把其中的两个元素改成0,而且要求这两个0均匀分布在列表之中。
问题就在于选择哪两个位置进行插入了。

可以很简单地看出,第3个位置和第6个位置的1改成0即可,即[1, 1, 0, 1, 1, 0, 1, 1]。
所以现在问题在于,怎么让计算机得到类似的结果。因为计算机只能计算,不能像人一样“一眼看出”,所以结果的产生还是得依赖于计算。

首先第一步,原本有8个元素,改变2个,直观地想,8/2 = 4,每隔4个位置改变一个元素即可。
所以会变成[0, 1, 1, 1, 0, 1, 1, 1]但可以看到,这样的分布并不均匀,总体看,0的分布过于偏左。
因此可以让0们整体往右移动一些。
这其实就是让每一个点位往后挪一些。
那么挪多少呢,我们可以看出挪1或者挪2个位置会比较合适[1, 0, 1, 1, 1, 0, 1, 1]或者[1, 1, 0, 1, 1, 1, 0, 1]。

如果取2,那么刚好是8/2的一半,于是0的位置的通式可以写为map_x = (i + 0.5)*large_length/small_length。当然因为点位是能是整数,所以这个值实际上还需要取个整。

这也就是计算机中图像缩放近邻法的处理方式了,如果有一张1×8像素的图像,我们把它缩放为1×2像素的图片,那么计算机会只取“0”所在的位置的像素,而直接舍去“1”所在位置的像素,形成一张缩放后的图片。

可以看到和人眼“一眼看出”的结果还是有些差异的。

利用这一特性,我们就可以在缩放后会被保留的点位上篡改一下像素,比如把另一张图片的像素放在这些点位上,于是原图缩小后,就会变成我们加入的这“另一张图片”了

下面是up主在GitHub上留下的源码:

import sys
from PIL import Image

#将small_img中的像素用近邻法嵌入到big_img中
def my_nearest_resize(big_img, small_img):

    big_w, big_h = big_img.size 
    small_w, small_h = small_img.size 

    dst_im = big_img.copy()

    stepx = big_w/small_w
    stepy = big_h/small_h

    for i in range(0, small_w):
        for j in range(0, small_h):
            map_x = int( i*stepx + stepx*0.5 )
            map_y = int( j*stepy + stepy*0.5 )

            if map_x < big_w and map_y < big_h :
                # 这里是往大图的缩放点所在位置插入小图的像素点
                # 但上面这个判断我是真没看懂有什么必要。
                dst_im.putpixel( (map_x, map_y), small_img.getpixel( (i, j) ) )

    return dst_im


if __name__ == '__main__':
    big_img=Image.open(sys.argv[1])     # 大图
    small_img=Image.open(sys.argv[2])   # 小图

    dst_im = my_nearest_resize(big_img, small_img)
    dst_im.save(sys.argv[3])            # 嵌入小图像素的大图

posted @ 2023-11-13 11:41  码鸽  阅读(35)  评论(0编辑  收藏  举报