我看不到 numpy 数组的问题(图像处理)
I can't see the problem with numpy array (image-processing)
我尝试手动调整图像的对比度。第二个代码对我来说工作正常,但它使用循环 -> 它很慢所以我更改为第一个代码但得到不同的输出。
我不知道出了什么问题,因为我认为这两个是相似的。有人能告诉我我错过了什么吗?非常感谢。
无循环代码
from PIL import Image
# level should be in range of -255 to +255 to decrease or increase contrast
def change_contrast(img, level):
def truncate(v):
v[v<0] = 0
v[v>255] = 255
return v
img_c = np.reshape(img,(1,img.shape[0] *img.shape[1],3))[0].copy()
factor = (259 * (level+255)) / (255 * (259-level))
img_c = factor * (img_c-128) + 128
img_c = truncate(img_c)
return np.reshape(img_c,(img.shape[0] ,img.shape[1],3)).astype(np.uint8)
带循环的代码
from PIL import Image
# level should be in range of -255 to +255 to decrease or increase contrast
def change_contrast(img, level):
def truncate(v):
v[v<0] = 0
v[v>255] = 255
return v
img_c = np.reshape(img,(1,img.shape[0] *img.shape[1],3))[0].copy()
factor = (259 * (level+255)) / (255 * (259-level))
for x in range(img_c.shape[0]):
color = img_c[x]
new_color = truncate(np.asarray([int(factor * (c-128) + 128) for c in color]))
img_c[x]= new_color
return np.reshape(img_c,(img.shape[0] ,img.shape[1],3))
测试代码
a = PIL.Image.open('Test.jpg')
b = np.asarray(a)
Image.fromarray(change_contrast(b , 128))
结果:
non_loop:
循环:
解决方案:我的原始数组有 uint8
类型,它不会让你有负数(例如:img_c - 128)。更改为 int
应该会有帮助!
要更仔细地检查类型。
问题在于 img
是一个无符号整数 uint8
,因此当您减去 128 时,它会被截断为 0 而不是负数。
如果将图像转换为 int
,它将按预期工作:
a = PIL.Image.open('test.jpeg')
b = np.asarray(a).astype(int)
Image.fromarray(change_contrast(b, 128))
这里还有一个较短的函数版本(您可以使用 np.clip
而不是自定义 truncate
函数):
def change_contrast(img, level):
img_c = img.astype(int).copy()
factor = (259 * (level+255)) / (255 * (259-level))
img_c = factor * (img_c - 128) + 128
img_c = np.clip(img_c, 0, 255)
return img_c.astype(np.uint8)
P.S。我在这个函数中包含了 astype(int)
以确保它是有符号整数,因此您不必在将图像传递给函数之前进行转换。
我尝试手动调整图像的对比度。第二个代码对我来说工作正常,但它使用循环 -> 它很慢所以我更改为第一个代码但得到不同的输出。
我不知道出了什么问题,因为我认为这两个是相似的。有人能告诉我我错过了什么吗?非常感谢。
无循环代码
from PIL import Image
# level should be in range of -255 to +255 to decrease or increase contrast
def change_contrast(img, level):
def truncate(v):
v[v<0] = 0
v[v>255] = 255
return v
img_c = np.reshape(img,(1,img.shape[0] *img.shape[1],3))[0].copy()
factor = (259 * (level+255)) / (255 * (259-level))
img_c = factor * (img_c-128) + 128
img_c = truncate(img_c)
return np.reshape(img_c,(img.shape[0] ,img.shape[1],3)).astype(np.uint8)
带循环的代码
from PIL import Image
# level should be in range of -255 to +255 to decrease or increase contrast
def change_contrast(img, level):
def truncate(v):
v[v<0] = 0
v[v>255] = 255
return v
img_c = np.reshape(img,(1,img.shape[0] *img.shape[1],3))[0].copy()
factor = (259 * (level+255)) / (255 * (259-level))
for x in range(img_c.shape[0]):
color = img_c[x]
new_color = truncate(np.asarray([int(factor * (c-128) + 128) for c in color]))
img_c[x]= new_color
return np.reshape(img_c,(img.shape[0] ,img.shape[1],3))
测试代码
a = PIL.Image.open('Test.jpg')
b = np.asarray(a)
Image.fromarray(change_contrast(b , 128))
结果:
non_loop:
循环:
解决方案:我的原始数组有 uint8
类型,它不会让你有负数(例如:img_c - 128)。更改为 int
应该会有帮助!
要更仔细地检查类型。
问题在于 img
是一个无符号整数 uint8
,因此当您减去 128 时,它会被截断为 0 而不是负数。
如果将图像转换为 int
,它将按预期工作:
a = PIL.Image.open('test.jpeg')
b = np.asarray(a).astype(int)
Image.fromarray(change_contrast(b, 128))
这里还有一个较短的函数版本(您可以使用 np.clip
而不是自定义 truncate
函数):
def change_contrast(img, level):
img_c = img.astype(int).copy()
factor = (259 * (level+255)) / (255 * (259-level))
img_c = factor * (img_c - 128) + 128
img_c = np.clip(img_c, 0, 255)
return img_c.astype(np.uint8)
P.S。我在这个函数中包含了 astype(int)
以确保它是有符号整数,因此您不必在将图像传递给函数之前进行转换。