" SystemError:tile无法扩展到图像外部"保存图片期间在PIL中

时间:2017-03-30 15:15:59

标签: python image image-processing computer-vision

我有这个Image =>

enter image description here

这里是上面黄色框的所有坐标,用3.txt文件写成。

#Y   X Height     Width 

46 135 158 118 
46 281 163 104 
67 494 188 83 
70 372 194 101 
94 591 207 98 
252 132 238 123 
267 278 189 105 
320 741 69 141 
322 494 300 135 
323 389 390 124 
380 726 299 157 
392 621 299 108 
449 312 227 93 
481 161 425 150 
678 627 285 91 
884 13 650 437 
978 731 567 158 
983 692 60 43 
1402 13 157 114 

我的意图是裁剪这些框并将所有框保存为图像。我已经为此编写了代码,但却收到了错误。

这是我的代码=>

from PIL import Image
import matplotlib.pyplot as plt
import numpy as np
from os import listdir
#from scipy.misc import imsave

ARR = np.empty([1,4])
# print(ARR)

i = 0
k = 0
img = Image.open('3.png')

fo = open("3.txt", "r")
for line in fo:
    if not line.startswith('#'):
        for word in line.split():

            ARR[0][i] = int(word)
            print(int(word))
            # ARR[0][i] = int(word)
            i = i +1

    img2 = img.crop((int(ARR[0][1]), int(ARR[0][0]), int(ARR[0][0] + ARR[0][2]), int(ARR[0][1] + ARR[0][3])))
    name = "new-img" + str(k) + ".png"
    img2.save(name)
    k = k + 1
    i = 0

我收到这些错误=>

  

回溯(最近一次呼叫最后一次):文件" reshape.py",第26行,在          img2.save(name)File" /usr/lib/python2.7/dist-packages/PIL/Image.py" ;,第1468行,保存       save_handler(self,fp,filename)文件" /usr/lib/python2.7/dist-packages/PIL/PngImagePlugin.py" ;,第624行,in   _保存       ImageFile._save(im,_idat(fp,chunk),[(" zip",(0,0)+ im.size,0,rawmode)])File" / usr / lib / python2.7 / DIST-包/ PIL / ImageFile.py&#34 ;,   第462行,在_save中       e.setimage(im.im,b)SystemError:tile无法扩展到图像外

如何解决这些问题?

4 个答案:

答案 0 :(得分:4)

参考评论,由于将坐标不正确地传递给PIL的crop()功能而发生错误。

the documentation中所述,该函数返回一个四元组(xywidthheight)的图像。

在给定的文本文件中,第一列中提到了y坐标,第二列中提到了x坐标。但是,crop()函数接受x坐标值作为第一个参数,y坐标作为第二个参数。

同样适用于OpenCV

以下是ANOTHER POST

答案 1 :(得分:4)

在互联网上提到的方式是这样的:

imageScreenshot.crop((x, y, width, height))

但是正确的方法是这样:

imageScreenshot.crop((x, y, x + width, y + height))

意味着您应将x添加到width,将y添加到height
这是一个简单的示例(driver用于python硒):

def screenShotPart(x, y, width, height) -> str:
    screenshotBytes = driver.get_screenshot_as_png()
    imageScreenshot = Image.open(BytesIO(screenshotBytes))
    imageScreenshot = imageScreenshot.crop((x, y, x + width, y + height))
    imagePath = pathPrefix + "_____temp_" + str(time.time()).replace(".", "") + ".png"
    imageScreenshot.save(imagePath)

希望有帮助。

答案 2 :(得分:0)

在我的情况下,问题是我指定了起点和终点坐标,其中起点X和起点Y并不总是小于终点X和Y。

例如,

开始:(0,50) 结束:(50,0)

这些坐标对我来说很有意义,但实际上应指定为:

开始:(0,0) 结束:(50,50)

外观上是相同的矩形,但是枕头是裁剪所必需的。

答案 3 :(得分:0)

如果您使用 DeepLearning 软件来检测图像中的对象并且您正在尝试删除检测 - 您很可能会看到这个

我在使用 ImageAI 检测图像中的对象时遇到了同样的错误。 我设法通过在我的虚拟环境中编辑 ImageFile.py 包中的 PIL 来解决它。

ImageFile 位于

\home\myuser\anaconda3\envs\envsName\lib\python3.7\site-packages\PIL\ImageFile.py

查找以 _save 开头的函数行:

def _save(im, fp, tile, bufsize=0):

之后:

 tile.sort(key=_tilesort)
    # FIXME: make MAXBLOCK a configuration parameter
    # It would be great if we could have the encoder specify what it needs
    # But, it would need at least the image size in most cases. RawEncode is
    # a tricky case.

插入:

tile = [e for e in tile if e[1][2] > 0 and e[1][3]>0]

这将跳过保存所有图像(平铺)宽度和高度大小不正确的检测,有时报告为 0,可能是因为检测到的对象仅部分显示在图像的边缘。

------------

但是,例如,如果您知道您的所有图像都是 1920x1080,并且您想丢弃所有未报告的尺寸大致相同的图像,那么您可以执行类似的操作。

tile = [e for e in tile if e[1][2] > 1720 and e[1][3]>880]

宽度和高度减少了 200 像素,以允许保存更小但可能仍然正确的图像(图块),这将丢弃所有其他图像。

Source