我正在尝试使用python中的图像切片器分割图像,然后对每个图像应用直方图均衡并将它们组合回来。我能够将图像分割成更小的块,我可以看到它们被更新但是在将它们拼接在一起后,我最终得到的图像与原始图像相同。有人可以指出我做错了什么。文件名是watch.png
import cv2
import numpy as np
from matplotlib import pyplot as plt
from scipy.misc import imsave
# import scipy
from scipy import ndimage
from scipy import misc
import scipy.misc
import scipy
import sys
import argparse
import image_slicer
from image_slicer import join
img = 'watch.png'
num_tiles = 64
tiles = image_slicer.slice(img, num_tiles)
file = "watch"
k = 0
filelist =[]
for i in range(1,9):
for j in range(1,9):
filelist.insert(k, file+"_"+str(i).zfill(2)+"_"+str(j).zfill(2)+".png")
k=k+1
for i in range(0,num_tiles):
img = scipy.misc.imread(filelist[i])
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf *hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'g')
plt.hist(img.flatten(),256,[0,256], color = 'g')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
cdf_m = np.ma.masked_equal(cdf,0)
cdf_o = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_o,0).astype('uint8')
img3 = cdf[img]
cv2.imwrite(filelist[i],img3)
image = join(tiles)
image.save('watch-join.png')
答案 0 :(得分:2)
在查看image_slicer
代码后,我可以看到混乱。主要问题是每个Tile
对象都包含图像数据和元数据,例如最终图像中的文件名和位置。但是,当指向的文件更新时,图像数据不会更新。
因此,当更新元数据指向的文件时,也需要更新图块的图像对象。我想最简单的方法是,每当磁盘上的文件发生变化时,重新打开磁贴中的图像。这很可能会成功:
import cv2
import numpy as np
from matplotlib import pyplot as plt
from scipy.misc import imsave
from scipy import ndimage
from scipy import misc
import scipy.misc
import scipy
import image_slicer
from image_slicer import join
from PIL import Image
img = 'watch.png'
num_tiles = 64
tiles = image_slicer.slice(img, num_tiles)
for tile in tiles:
img = scipy.misc.imread(tile.filename)
hist,bins = np.histogram(img.flatten(),256,[0,256])
cdf = hist.cumsum()
cdf_normalized = cdf *hist.max()/ cdf.max()
plt.plot(cdf_normalized, color = 'g')
plt.hist(img.flatten(),256,[0,256], color = 'g')
plt.xlim([0,256])
plt.legend(('cdf','histogram'), loc = 'upper left')
cdf_m = np.ma.masked_equal(cdf,0)
cdf_o = (cdf_m - cdf_m.min())*255/(cdf_m.max()-cdf_m.min())
cdf = np.ma.filled(cdf_o,0).astype('uint8')
img3 = cdf[img]
cv2.imwrite(tile.filename,img3)
tile.image = Image.open(tile.filename)
image = join(tiles)
image.save('watch-join.png')
因此,主要的变化是在循环结束时添加tile.image = Image.open(tile.filename)
。另请注意,我已经稍微更新了您的代码,删除了生成文件名的第一个循环,而第二个循环直接覆盖了磁贴,因为它们包含所有准备好的所需信息。
答案 1 :(得分:1)
这是image_slicer.join()
的源代码:
def join(tiles):
"""
@param ``tiles`` - Tuple of ``Image`` instances.
@return ``Image`` instance.
"""
im = Image.new('RGB', get_combined_size(tiles), None)
columns, rows = calc_columns_rows(len(tiles))
for tile in tiles:
im.paste(tile.image, tile.coords)
return im
正如您所看到的,它使用程序中存储的Tile
个对象(在您的情况下,在列表tiles
内),但尚未更改。您需要更改内存中的对象,而不是从文件加载和重写,或者将文件加载到tiles
。
我认为简单的方法是修改你的for循环(我希望我的语法正确):
for i in range(0, num_tiles):
img = tiles[i].image
hist, bins = np.histogram(img.flatten(), 256, [0, 256])
cdf = hist.cumsum()
cdf_normalized = cdf * hist.max() / cdf.max()
plt.plot(cdf_normalized, color = 'g')
plt.hist(img.flatten(), 256, [0, 256], color='g')
plt.xlim([0, 256])
plt.legend(('cdf', 'histogram'), loc='upper left')
cdf_m = np.ma.masked_equal(cdf, 0)
cdf_o = (cdf_m - cdf_m.min()) * 255 / (cdf_m.max() - cdf_m.min())
cdf = np.ma.filled(cdf_o, 0).astype('uint8')
img3 = cdf[img]
tiles[i].image = img3