所以问题集是有一个 360x360 像素的图像,并将测试数据中给出的加扰图像恢复为原始图像(原始图像已被老师事先分成 9 块并随机重新排列以形成加扰图像),我在解决问题时遇到了麻烦。 (老师给出的线索是尽量减少相邻片段边缘像素之间的差异,以找到正确的排列方式)
我尝试将给定的图像分解为9个正确的部分,并使用itertools.permutation
找到所有可能的拼图排列情况,并最小化边界差异以找到正确的排列。 但这似乎不是一个好方法,因为它需要大量的计算和数据存储, 此外,我当前的代码无法输出答案。有人可以告诉我下一步该怎么做吗?这是我写的。
import numpy as np
import matplotlib.pyplot as plt
import itertools
def solve_puzzle(img):
ret = img.copy()
ret_ = []
for i in range(3):
for k in range(3):
ret_.append(ret[120*i:120*(i+1),120*k:120*(k+1),:])
ret_per = itertools.permutations(ret_)
def vertical_sum(r):
k = 0.
r0 = r[0]
r1 = r[1]
r2 = r[2]
r3 = r[3]
r4 = r[4]
r5 = r[5]
r6 = r[6]
r7 = r[7]
r8 = r[8]
for i in range(120):
k += sum(r1[i,0,:]-r0[i,119,:])
for i in range(120):
k += sum(r2[i,0,:]-r1[i,119,:])
for i in range(120):
k += sum(r4[i,0,:]-r3[i,119,:])
for i in range(120):
k += sum(r5[i,0,:]-r4[i,119,:])
for i in range(120):
k += sum(r7[i,0,:]-r6[i,119,:])
for i in range(120):
k += sum(r8[i,0,:]-r7[i,119,:])
return k
def horizontal_sum(r):
p = 0.
r0 = r[0]
r1 = r[1]
r2 = r[2]
r3 = r[3]
r4 = r[4]
r5 = r[5]
r6 = r[6]
r7 = r[7]
r8 = r[8]
for i in range(120):
p += sum(r3[0,i,:]-r0[119,i,:])
for i in range(120):
p += sum(r4[0,i,:]-r1[119,i,:])
for i in range(120):
p += sum(r5[0,i,:]-r2[119,i,:])
for i in range(120):
p += sum(r6[0,i,:]-r3[119,i,:])
for i in range(120):
p += sum(r7[0,i,:]-r4[119,i,:])
for i in range(120):
p += sum(r8[0,i,:]-r5[119,i,:])
return p
boundary = {}
for i in ret_per:
t = 0.
t += vertical_sum(i) + horizontal_sum(i)
boundary[t] = i
find = boundary[min(boundary.keys())]
ret[0:120,0:120,:] = find[0]
ret[0:120,120:240,:] = find[1]
ret[0:120,240:360,:] = find[2]
ret[120:240,0:120,:] = find[3]
ret[120:240,120:240,:] = find[4]
ret[120:240,240:360,:] = find[5]
ret[240:360,0:120,:] = find[6]
ret[240:360,120:240,:] = find[7]
ret[240:360,240:360,:] = find[8]
return ret
if __name__ == '__main__':
data = np.load('jigsaw_data.npy')
idx = np.random.randint(10)
ret = solve_puzzle(data[idx])
fig = plt.figure(figsize=(6,6), dpi=80)
plt.imshow(ret)
plt.show()
输出应为正确的图像。
似乎经历所有排列将非常耗时。 我建议你拿一块,计算其余 8 块的 RGB 值的边框(上、左、右、下)之间的差异。任何两个部分的单个边框之间的最小差异应表明这些部分最有可能在该特定方向上彼此相邻。