在Python中分割和合并图像 [英] Split and Join images in Python

查看:500
本文介绍了在Python中分割和合并图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用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')

解决方案

研究了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).还要注意,我已经通过删除生成文件名的第一个循环来略微更新了您的代码,相反,第二个循环直接位于磁贴上,因为它们已包含所有必要的信息.

I am trying to split an image using image slicer in python and then apply histogram equalization on each of them and combine them back. I am able to split the images into smaller blocks and I can see them being updated but after stitching them together I end up with the same image as the original one. Can someone point out what I am doing wrong. The file name is 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')

解决方案

After looking into the image_slicer code, I can see the confusion. The main problem is that each Tile object, contains both the image data and metadata, such as filename and position in final image. However, the image data is not updated when the files pointed to are updated.

Thus, when updating the files pointed to by the metadata also the image object of the tile needs to be updated. I imagine the simplest way to do this, is to reopen the image in the tile whenever the file on disk is changed. This is likely to do the trick:

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')

Thus, the main change is to add tile.image = Image.open(tile.filename) at the end of the loop. Note also that I have updated your code slightly, by removing the first loop that generates the filenames, and instead the second loop is over the tiles directly, as they contain the needed information all ready.

这篇关于在Python中分割和合并图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆