@zsh-o
2019-06-19T14:58:30.000000Z
字数 6177
阅读 1267
图像处理
from matplotlib import pylab as plt
import numpy as np
from PIL import Image
import cv2
image_src = Image.open('./test2_src.png').convert('RGB')
image_target = Image.open('./test2_target.png').convert('RGB')
im_src = np.array(image_src)
im_target = np.array(image_target)
plt.subplot(1,2,1)
plt.imshow(im_src)
plt.subplot(1,2,2)
plt.imshow(im_target)
<matplotlib.image.AxesImage at 0x7f68f7c34b38>
im_src.shape, im_target.shape
((120, 180, 3), (356, 418, 3))
# 转换后的位置,0点算起,非中心点
position = (150, 150)
# 区域mask
omega = np.zeros((im_target.shape[0], im_target.shape[1]), dtype=np.bool)
# 删除最外面一圈点,防止边缘计算梯度错误
omega[position[0] + 1: position[0] + im_src.shape[0] -1, position[1] + 1: position[1] + im_src.shape[1] - 1] = 1
mask_target = im_target.copy()
mask_target[position[0]: position[0] + im_src.shape[0], position[1]: position[1] + im_src.shape[1], :] = im_src
plt.subplot(1,2,1)
plt.imshow(omega)
plt.subplot(1,2,2)
plt.imshow(mask_target)
<matplotlib.image.AxesImage at 0x7f68f639e8d0>
def in_omega(omega, position):
x, y = position
if omega[x, y] == True:
return True
else:
return False
def get_neighbors(position):
x, y = position
return (x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)
def laplace(X, position):
x, y = position
res = -4 * X[x, y]
neighbors = get_neighbors(position)
for near_x, near_y in neighbors:
res += X[near_x, near_y]
return res
maps = {}
index = 0
for i in range(im_target.shape[0]):
for j in range(im_target.shape[1]):
maps[(i, j)] = index
index += 1
# 稀疏矩阵来保存系数矩阵
import scipy.sparse as sp
A = sp.lil_matrix((len(maps), len(maps)))
for i in range(im_target.shape[0]):
for j in range(im_target.shape[1]):
point_c = maps[(i, j)]
if in_omega(omega, (i, j)) is not True:
# 不在范围内
A[point_c, point_c] = 1
else:
# 离散拉普拉斯算子
A[point_c, point_c] = -4
c_neighbors = get_neighbors((i, j))
for neighbor in c_neighbors:
near_x, near_y = neighbor
point_near = maps[(near_x, near_y)]
A[point_c, point_near] = 1
# 与A过程相同,可以合并
b = np.zeros((len(maps), 3))
for i in range(im_target.shape[0]):
for j in range(im_target.shape[1]):
point_c = maps[(i, j)]
if in_omega(omega, (i, j)) is not True:
# 不在范围内
b[point_c, :] = im_target[i, j, :]
else:
b[point_c, :] = laplace(mask_target, (i, j))
import scipy.sparse.linalg as spl
# 解方程组Af = b
f = spl.spsolve(A.tocsc(), b)
final_target = np.zeros(im_target.shape, dtype=np.uint8)
final_target[:,:,0] = f[:,0].reshape(omega.shape)
final_target[:,:,1] = f[:,1].reshape(omega.shape)
final_target[:,:,2] = f[:,2].reshape(omega.shape)
plt.figure(figsize=(20,40), dpi=50)
plt.subplot(1,2,1)
plt.imshow(mask_target)
plt.subplot(1,2,2)
plt.imshow(final_target)
<matplotlib.image.AxesImage at 0x7f689a5e7f60>
np.where(final_target == 0)
(array([153, 157, 157, 165, 172, 221, 229, 239, 242, 243, 248, 248, 251,
255, 256, 257, 258, 258, 258, 258, 259, 260, 260, 261, 262, 262,
262, 262, 262, 263, 263, 263, 263, 264, 265, 265, 265, 265, 266,
266, 267, 267, 267, 267, 267, 268, 268, 268]),
array([326, 317, 324, 322, 296, 168, 158, 162, 160, 167, 159, 160, 161,
168, 160, 159, 155, 157, 164, 166, 163, 156, 168, 171, 156, 163,
164, 166, 174, 154, 159, 164, 165, 152, 163, 170, 173, 237, 169,
214, 178, 179, 199, 235, 239, 177, 230, 234]),
array([0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0]))
np.where(f > 255)
(array([ 63439, 63444, 63445, 63446, 63860, 63861, 63862, 64276,
64280, 64281, 64282, 65535, 65943, 65948, 65950, 66370,
67196, 67626, 68035, 69292, 70502, 71751, 71756, 72171,
72178, 72595, 73014, 82187, 82188, 82189, 82605, 82605,
82605, 82606, 82606, 82607, 82607, 83023, 83023, 83023,
83024, 83024, 83025, 83025, 83026, 83026, 83441, 83442,
83442, 83443, 83443, 83444, 83444, 83859, 83860, 83860,
83861, 83861, 83862, 83862, 84277, 84277, 84278, 84278,
84279, 84279, 84280, 84280, 84695, 84695, 84696, 84696,
84697, 84697, 84698, 84698, 85113, 85113, 85114, 85114,
85115, 85115, 85116, 85116, 85532, 85532, 85533, 85533,
86404, 88767, 90864, 90875, 91277, 91289, 91294, 91711,
91713, 92130, 92131, 92545, 92546, 92954, 92959, 92961,
93380, 93381, 93799, 93801, 94212, 94632, 94737, 95037,
95041, 95053, 95151, 95455, 95880, 96712, 96715, 97135,
97550, 97557, 97967, 98387, 98390, 99642, 99644, 99645,
99646, 100061, 100062, 100063, 100064, 100480, 100484, 101316,
101318, 101319, 101728, 101741, 102147, 102154, 102565, 102566,
102988, 103401, 103408, 103412, 103822, 103823, 103824, 103833,
104234, 104235, 104237, 104238, 104242, 104653, 104658, 104661,
104662, 104664, 105069, 105071, 105077, 105079, 105080, 105491,
105492, 105493, 105496, 105498, 105499, 105912, 105913, 106328,
106331, 106334, 106746, 106748, 106758, 107164, 107168, 107172,
107173, 107174, 107178, 107582, 107583, 107585, 107586, 107592,
107999, 108000, 108001, 108002, 108005, 108006, 108007, 108008,
108010, 108416, 108417, 108420, 108421, 108422, 108424, 108425,
108426, 108427, 108430, 108432, 108434, 108835, 108836, 108840,
108841, 108842, 108843, 108844, 108845, 108848, 108849, 108853,
109254, 109255, 109258, 109259, 109261, 109265, 109267, 109269,
109329, 109667, 109672, 109673, 109674, 109676, 109679, 109680,
109682, 109689, 109690, 110088, 110093, 110094, 110095, 110096,
110098, 110099, 110104, 110504, 110508, 110515, 110517, 110518,
110521, 110523, 110524, 110527, 110598, 110932, 110933, 110934,
110940, 110941, 110943, 110974, 110978, 110991, 111007, 111346,
111351, 111352, 111355, 111357, 111361, 111392, 111393, 111402,
111410, 111420, 111426, 111427, 111761, 111767, 111768, 111769,
111771, 111772, 111773, 111775, 111777, 111783, 111784, 111785,
111805, 111826, 111830, 111833, 111834, 111841, 111842, 111845,
111847, 111851, 112179, 112185, 112186, 112187, 112189, 112193,
112195, 112201, 112203, 112223, 112249, 112254, 112258, 112260,
112261, 112262, 112264, 112265, 112266, 112267, 112268, 112271,
112275]),
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 2, 0, 1, 0, 1, 0, 1, 2, 0, 1, 0, 1,
0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]))
# 计算出的f存在大于255的像素,转换成unit8时变成了0
f[f > 255] = 255
f[f < 0] = 0
final_target_corr = np.zeros(im_target.shape, dtype=np.uint8)
final_target_corr[:,:,0] = f[:,0].reshape(omega.shape)
final_target_corr[:,:,1] = f[:,1].reshape(omega.shape)
final_target_corr[:,:,2] = f[:,2].reshape(omega.shape)
plt.figure(figsize=(20,40), dpi=50)
plt.subplot(1,2,1)
plt.imshow(mask_target)
plt.subplot(1,2,2)
plt.imshow(final_target_corr)
<matplotlib.image.AxesImage at 0x7f689a1d3668>