#python_3x #алгоритм #изображения
Нужно реализовать алгоритм билинейной интерполяции для черно-белого изображения.
Вроде всё делаю по формулам, но результат получается абсолютно неверным.
По ссылке на github Вы можете увидеть, собственно, результат.
Насколько я понимаю, проблема где-то в цикле (ну, в общем-то, больше и негде ей быть,
наверное).
Вот код:
from PIL import Image
import numpy as np
from matplotlib.pyplot import imshow
%matplotlib inline
img = Image.open("5.jpg", 'r')
img = img.convert('L') # преобразование в изображение в оттенках серого
# imshow(np.asarray(img))
im_array = np.asarray(img)
# img.save("5_resize.jpg")
pix = img.load() # выгрузка значений пикселов
height, width = im_array.shape
result_arr = np.empty((500, 500)) # создание нового массива
for x in range(height-1):
for y in range(width-1):
result_arr[2*x, 2*y] = pix[x,y]
result_arr[2*x, 2*y+1] = pix[x,y] * ((2*y+2)-(2*y+1))/((2*y+2)-2*y)
+ \
pix[x+1, y+1] * ((2*y+1)-2*y)/((2*y+2)-2*y)
result_arr[2*x+1, 2*y] = pix[x,y] * ((2*x+2)-(2*x+1))/((2*x+2)-2*x)
+ \
pix[x+1, y+1] * ((2*x+1)-2*x)/((2*x+2)-2*x)
for y in range(width-1):
result_arr[2*x+1, 2*y+1] = result_arr[2*x+1, 2*y] * ((2*y+2)-
(2*y+1))/((2*y+2)-2*y) + \
result_arr[2*x+1, 2*y+2] * ((2*y+1)-2*y)/((2*y+2)-2*y)
# result_arr[(2*x)+1, (2*y)+0] = (pix[x+1, y] + pix[x,y]) / 2
# result_arr[(2*x)+0, (2*y)+1] = (pix[x, y+1] + pix[x,y]) / 2
# result_arr[(2*x)+1, (2*y)+1] = (pix[x+1, y+1] + pix[x+1, y] +
pix[x, y+1] + pix[x,y]) / 4
print(result_arr)
result_img = Image.fromarray(result_arr, mode = 'L')
imshow(np.asarray(result_img)) # преобразованная картинка
# result_img.save("5_resize.jpg")
Ответы
Ответ 1
Модуль PIL уже умеет все это делать из коробки: from PIL import Image # https://lizzierosswriter.files.wordpress.com/2014/10/3150494-7873411214-5.jpg img = Image.open("c:/download/5.jpg", 'r') img = img.convert('L') factor = 0.5 w, h = img.size new_w = int(w * factor) new_h = int(h * factor) img.resize((new_w,new_h), Image.ANTIALIAS).save('c:/download/res_antialias.jpg') img.resize((new_w,new_h), Image.BILINEAR).save('c:/download/res_bilinear.jpg') Исходное изображение: res_antialias.jpg: res_bilinear.jpg:Ответ 2
Рабочий вариант программы import numpy as np from PIL import Image from scipy.misc import imread, imshow from scipy import ndimage import matplotlib.pyplot as plt def BilinearInterpolation(imArr, pix, posX, posY): X_int = int(posX) Y_int = int(posY) X_float = posX - X_int Y_float = posY - Y_int X_int_inc = min(X_int+1, imArr.shape[1]-1) Y_int_inc = min(Y_int+1, imArr.shape[0]-1) bl = pix[Y_int, X_int] br = pix[Y_int, X_int_inc] tl = pix[Y_int_inc, X_int] tr = pix[Y_int_inc, X_int_inc] b = X_float*br + (1. - X_float)*bl t = X_float*tr + (1. - X_float)*tl result = int(Y_float*t + (1. - Y_float)*b + 0.5) return result path = input("Path to picture: ") img = Image.open(path, 'r') img = img.convert('L') # преобразование в изображение в оттенках # серого imArr = np.asarray(img) pix = img.load() # выгрузка значений пикселов k = input("Resize coefficient : ") k = float(k) newShape = list(map(int, [imArr.shape[0]*k, imArr.shape[1]*k])) resultImg = np.empty(newShape, dtype = np.uint8) rowScale = float(imArr.shape[0]) / float(resultImg.shape[0]) colScale = float(imArr.shape[1]) / float(resultImg.shape[1]) for r in range(resultImg.shape[0]): for c in range(resultImg.shape[1]): old_r = r * rowScale old_c = c * colScale resultImg[c, r] = BilinearInterpolation(imArr, pix, old_c, old_r) plt.imshow(np.uint8(resultImg), cmap = 'gray') plt.show()
Комментариев нет:
Отправить комментарий