把图像的某一块看作是一个元素,应用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