我正在尝试从(x,y)坐标开始缩小图像的一部分,并将宽度和高度设置为500,将其调整为40x40。通过这样做,我将周围的像素平均为一个。 (我能找到的最简单的方法)但结果很奇怪。
原始图片为512x512 png
原始图片:
预期结果:
实际结果:
以下是代码段:
from PIL import Image
import numpy as np
defined_size = 40
img = Image.open("lena.png")
pix = np.array(img)
changed_img = shrink(pix, 0, 0, 500)
changed_img = np.array(changed_img)
resized = Image.fromarray(changed_img, 'RGB')
def shrink(img, x, y, size):
result = [[0 for width in xrange(defined_size)] for height in xrange(defined_size)]
scale_factor = size/defined_size
for i in xrange(defined_size):
for j in xrange(defined_size):
temp = np.array([0,0,0])
for t in xrange(scale_factor):
print img[i*scale_factor+x, j*scale_factor+y]
temp = np.add(temp, img[i*scale_factor+x, j*scale_factor+y])
result[i][j] = np.divide(temp, scale_factor)
print result[i][j]
return result
答案 0 :(得分:1)
@rayryeng-恢复莫妮卡的最新代码来自您的答案,但现在将通过平均周围像素将任何尺寸的输入图像调整为尺寸的四分之一。早期版本仅适用于正方形图像。谢谢你的帖子!
def quarter_res_avg(im):
original_width = im.shape[1]
original_height = im.shape[0]
width = original_width / 4
height = original_height / 4
resized_image = np.zeros(shape=(height, width, 3), dtype=np.uint8)
scale = 4
for i in range(height):
for j in range(width):
temp = np.array([0, 0, 0])
for x in range(scale):
for y in range(scale):
temp += im[i*scale + x, j*scale + y]
resized_image[i, j] = temp/(scale*scale)
return resized_image
im = cv2.imread('Lenna_test_image.png', 1)
cv2.imwrite('Lenna_test_image_resized.png', quarter_res_avg(im))
另一种方法:
def quarter_res_avg(im):
original_width = im.shape[1]
original_height = im.shape[0]
width = original_width / 4
height = original_height / 4
resized_image = np.zeros(shape=(height, width, 3), dtype=np.uint8)
scale = 4
for i in range(0, original_height, scale):
for j in range(0, original_width, scale):
resized_image[i/scale, j/scale] = np.mean(im[i:i + scale, j:j+scale], axis=(0, 1))
return resized_image
答案 1 :(得分:0)
为什么不使用库函数? Python库非常棒。
import PIL.Image
import scipy.misc
lena = scipy.misc.lena()
resized = scipy.misc.imresize(lena, (40, 40), interp='bilinear')
image = PIL.Image.fromarray(resized)
答案 2 :(得分:0)
您的代码存在一些问题。让我们一次解决一个问题:
(x,y)
在shrink
定义我知道你要去哪里(x,y)
。您正在使用它来遍历每个较大的块,对所有像素求和并除以条目总数以获得平均RGB像素。对于图像中的每个块,您将此设置为(0,0)
,因此您实际上并未获得块中的所有像素。您需要使用一对for
循环来允许遍历每个块。我也冒昧地删除了(x,y)
输入,并将所需大小作为输入添加到您的函数中。
您初始化了一个二维列表,但图片有三个频道。因为您正在使用numpy
为您执行计算...为什么不首先通过zeros
声明np.zeros
数组?这样,您就不必在完成后转换回numpy
数组。我已经更改了输出图像的声明,因此它是numpy
类型为uint8
的数组。这个演员很重要!
正如我们在问题#1中所讨论的那样,您不是每个子采样块正确收集像素。我为您插入了另一对for
循环...枚举为x
和y
。我还删除了np.add
并使用+
为您执行操作,因为它更容易阅读。
因为它是您尝试计算的子样本的平均值,所以必须除以每个块中的值的总数。这等于scale_factor*scale_factor
。你只是除以scale_factor
。
我还冒昧地显示已调整大小的图像并将其保存到文件中。没有进一步的麻烦这里是更正的代码。我还将您的测试代码放在__main__
块中,以便于测试:
from PIL import Image
import numpy as np
def shrink(img, size, defined_size): # Change - Issue #1
result = np.zeros((defined_size, defined_size, 3), dtype=np.uint8) # Change - Issue #2
scale_factor = size/defined_size
for i in xrange(defined_size):
for j in xrange(defined_size):
temp = np.array([0,0,0])
for x in xrange(scale_factor): # Change - Issue #3
for y in xrange(scale_factor): # Change - Issue #3
temp += img[i*scale_factor + x, j*scale_factor + y] # Change - Issue #3
result[i,j] = temp / (scale_factor*scale_factor) # Change
return result
if __name__ == '__main__':
img = Image.open("lena.png")
pix = np.array(img)
changed_img = shrink(pix, 512, 40) # Change - Issue #1
resized = Image.fromarray(changed_img, 'RGB')
resized.show() # Change
resized.save("lena_resize.png")
...我们得到了这张已调整大小的图片: