图像分块与置乱(Arnold)

把图像的某一块看作是一个元素,应用Arnold。(注意要对数组进行扩充)
代码如下:

import numpy as np

class Arnold:
    def __init__(self,img,width,height,count,a,b):
        self.img = img
        self.x,self.y,self.c = img.shape    #保存原图的尺寸,用于恢复
        self.width = width
        self.height = height
        self.count = count
        self.a = a
        self.b = b
    #实现数组扩充
    def completion(self):
        row,col,n = self.img.shape
        rh = row%self.height
        cw = col%self.width
        #数组扩充为相应width和height的倍数
        if rh==0 and cw == 0:
            return self.img
        else:
            if(cw != 0):    #添加列
                num = self.width - cw
                a = np.zeros([row,n])
                for i in range(num):
                    self.img = np.insert(self.img,col,a,axis = 1)
            row,col,n = self.img.shape
            if rh != 0:     #添加行
                num = self.height-rh
                a = np.zeros([col,n])
                for i in range(num):
                    self.img = np.insert(self.img,row,a,axis = 0)
            #数组扩充为M与N大小相同(把每个块看作一个元素,类似与正方形)
            row,col,n = self.img.shape
            M = row//self.height
            N = col//self.width
            if(M == N):
                return self.img
            elif M>N:   #添加num列
                num = (M-N)*self.width
                a = np.zeros([row,n])
                for i in range(num):
                    self.img = np.insert(self.img,col,a,axis = 1)
            else:       #添加num行
                num = (N-M)*self.height
                a = np.zeros([col,n])
                for i in range(num):
                    self.img = np.insert(self.img,row,a,axis = 0) 
            return self.img
    # arnold置乱
    def arnold1(self):
        newImg = np.zeros(self.img.shape)   #用于保存置乱后的图像
        row,col,n = self.img.shape
        M = row//self.height
        N = col//self.width
        while(self.count > 0):  #置乱次数
            for i in range(N):
                xx = i*self.width
                for j in range(M):
                    yy = j*self.height
                    subarr = self.img[yy:yy+self.height,xx:xx+self.width] #某个块
                    newI = (i+self.b*j)%N
                    newJ = (self.a*i+(self.a*self.b+1)*j)%M
                    newX = newI*self.width
                    newY = newJ*self.height
                    newImg[newY:newY+self.height,newX:newX+self.width] = subarr
            self.count -=1
        newImg = newImg.astype(np.uint8)
        return newImg

    def inverseArnold1(self,Img,count):
        newImg = np.zeros(Img.shape)
        row,col,n = Img.shape
        M = row//self.height
        N = col//self.width
        while(count > 0):
            for i in range(N):
                xx = i*self.width
                for j in range(M):
                    yy = j*self.height
                    subarr = Img[yy:yy+self.height,xx:xx+self.width]
                    newI = ((self.a*self.b+1)*i-self.b*j)%M
                    newJ = (-self.a*i+j)%N
                    newX = newI*self.width
                    newY = newJ*self.height
                    newImg[newY:newY+self.height,newX:newX+self.width] = subarr
            count -=1
        newImg = newImg.astype(np.uint8)
        return newImg[:self.y,:self.y]

应用:

#merged为图像(彩色)
count = 5
a = 3
b = 4
width = 128
height = 128
ar = Arnold(merged,width,height,count,a,b)
ar.completion()
newImg = ar.arnold1()   #置乱
InverseImg = ar.inverseArnold1(newImg,count)    #恢复

#显示图像
plt.figure("Result",figsize = (10,5))
str = "width = {}    height = {}    count = {}    a = {}    b = {}"
plt.suptitle(str.format(width,height,count,a,b))
plt.subplot(131)
plt.title("Origin Image")
plt.imshow(merged[:,:,(2,1,0)])
plt.subplot(132)
plt.title("Arnold Image")
plt.imshow(newImg[:,:,(2,1,0)])
plt.subplot(133)
plt.title("InverseArnold Image")
plt.imshow(InverseImg[:,:,(2,1,0)])
plt.show()

结果如下:
原图大小为512 * 512
分块大小为128 * 128
在这里插入图片描述
在这里插入图片描述

  • 7
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值