OpenCV 在大图像上调整大小失败,出现“错误:(-215) ssize.area() > 0 in function cv::resize”

Posted

技术标签:

【中文标题】OpenCV 在大图像上调整大小失败,出现“错误:(-215) ssize.area() > 0 in function cv::resize”【英文标题】:OpenCV resize fails on large image with "error: (-215) ssize.area() > 0 in function cv::resize" 【发布时间】:2015-11-06 21:38:00 【问题描述】:

我正在使用 OpenCV 3.0.0 和 Python 3.4.3 来处理一个非常大的 RGB 图像 (107162,79553,3)。当我尝试使用以下代码调整它的大小时:

import cv2
image = cv2.resize(img, (0,0), fx=0.5, fy=0.5, interpolation=cv2.INTER_AREA)

我收到了这条错误消息:

cv2.error: C:\opencv-3.0.0\source\modules\imgproc\src\imgwarp.cpp:3208: 错误: (-215) ssize.area() > 0 in function cv::resize

我确定图像数组中有图像内容,因为我可以将它们保存到 jpg 格式的小图块中。当我尝试只调整图像的一小部分时,没有问题,我最终得到了正确调整大小的图像。 (取一个相当大的块 (50000,50000,3) 仍然不起作用,但它会在 (10000,10000,3) 块上起作用)

什么可能导致这个问题,我该如何解决这个问题?

【问题讨论】:

猜测:整数范围为 +/- 2.147.483.647,而 cols x 行在您的示例中为 8.525.058.586。所以可能在 cv::resize 中存在整数溢出。您可以通过测试 cols x rows == 2.147.483.647 周围的图像大小来测试这一点 嘿米卡,你是对的!它适用于 (46340,46340,3) 但不适用于 (46341,46341,3)。这是否意味着将 int 更改为 int64 应该可以解决问题? 我不知道在 cv::resize 中计算区域的位置。我觉得你得看看opencv resize source code... 在macos哪里可以找到这个文件,我没有找到同名的文件? 【参考方案1】:

原来问题出在modules\imgproc\src\imgwarp.cpp中的一行:

CV_Assert( ssize.area() > 0 );

当要调整大小的图像的行列乘积大于2^31时,ssize.area()结果为负数。这似乎是 OpenCV 中的一个错误,希望在未来的版本中得到修复。一个临时的解决方法是构建 OpenCV 并注释掉这一行。虽然不理想,但它对我有用。

我最近才发现,上述内容仅适用于宽度大于高度的图像。对于高度大于宽度的图像,以下行会导致错误:

CV_Assert( dsize.area() > 0 );

所以这也必须被注释掉。

【讨论】:

这行代码怎么改?文件在哪里? 是的,这很好,但我们在哪里可以找到文件 是否有解决方案来修复曾经发布/找到的这行代码? 请告知相应文件的位置。 只要在主目录'/'中搜索'imgwrap.cpp'就可以找到该文件!【参考方案2】:

对我来说,这个错误实际上是在说实话 - 我试图调整 Null 图像的大小,这通常是视频文件的“最后”帧,所以断言是有效的。

现在我在尝试调整大小操作之前有一个额外的步骤,即自己进行断言:

def getSizedFrame(width, height):
"""Function to return an image with the size I want"""    
    s, img = self.cam.read()

    # Only process valid image frames
    if s:
            img = cv2.resize(img, (width, height), interpolation = cv2.INTER_AREA)
    return s, img

现在我没有看到错误。

【讨论】:

我不认为这是一般情况。由于 OpenCV 错误,有效图像确实会发生此错误。 这是 Google 上的第一个热门歌曲,应该点赞!!在开始注释openCV代码之前检查你的imgs,我在预处理中解析几十张图像时遇到了完全相同的问题。【参考方案3】:

还要注意你的 numpy 数组的对象类型,使用.astype('uint8') 转换它为我解决了这个问题。

【讨论】:

我多次偶然发现这个 *** 答案。这对我每次都有帮助。我不知道为什么这个答案没有足够的支持。 为我工作。就我而言,我的图像是 int16。我将它转换为 uint16 并且它有效。【参考方案4】:

我知道这是一个非常古老的线程,但我遇到了同样的问题,即图像名称中的空格。

例如

图片名称:“hello o.jpg”

奇怪的是,通过删除空格,该函数工作得很好。

图片名称:“hello_o.jpg”

【讨论】:

【参考方案5】:

我在 MacOS 上安装了 OpenCV 3.4.3 版。 我遇到了与上述相同的错误。

我更改了我的代码

frame = cv2.resize(frame, (0,0), fx=0.5, fy=0.5)   

frame = cv2.resize(frame, None, fx=0.5, fy=0.5)    

现在它对我来说工作正常。

【讨论】:

【参考方案6】:

这种类型的错误也会发生,因为resize无法简单地获取图像 图片的目录可能是错误的。在我的情况下,我在提供文件位置的过程中留下了正斜杠,这个错误是在我解决斜杠问题后发生的。

【讨论】:

【参考方案7】:

对我来说,以下解决方法有效:

将数组拆分为更小的子数组 调整子数组的大小 再次合并子数组

代码如下:

def split_up_resize(arr, res):
    """
    function which resizes large array (direct resize yields error (addedtypo))
    """

    # compute destination resolution for subarrays
    res_1 = (res[0], res[1]/2)
    res_2 = (res[0], res[1] - res[1]/2)

    # get sub-arrays
    arr_1 = arr[0 : len(arr)/2]
    arr_2 = arr[len(arr)/2 :]

    # resize sub arrays
    arr_1 = cv2.resize(arr_1, res_1, interpolation = cv2.INTER_LINEAR)
    arr_2 = cv2.resize(arr_2, res_2, interpolation = cv2.INTER_LINEAR)

    # init resized array
    arr = np.zeros((res[1], res[0]))

    # merge resized sub arrays
    arr[0 : len(arr)/2] = arr_1
    arr[len(arr)/2 :] = arr_2

    return arr

【讨论】:

这对我不起作用,我遇到了同样的错误! “错误:(-215) ssize.area() > 0 in function resize”。注意:我不得不修改你的代码,因为索引值必须是一个整数。 "使用 // 而不是 /"。【参考方案8】:

原来我在读取所有图像的文件夹末尾有一个 .csv 文件。 一旦我删除它就可以了

确保都是图片,并且您没有任何其他类型的文件

【讨论】:

【参考方案9】:

在我的情况下,我对图像进行了错误的修改。

我能够在检查图像形状时找到问题。

print img.shape

【讨论】:

【参考方案10】:

就我而言,

image = cv2.imread(filepath)
final_img = cv2.resize(image, size_img)

文件路径不正确,在这种情况下 cv2.imshow 没有给出任何错误,但由于路径错误 cv2.resize 给了我错误。

【讨论】:

【参考方案11】:

您可以手动检查您的代码。像这样:

if result != []:
    for face in result:
        bounding_box = face['box']
        x, y, w, h = bounding_box[0], bounding_box[1], bounding_box[2], bounding_box[3]
        rect_face = cv2.rectangle(frame, (x, y), (x+w, y+h), (46, 204, 113), 2)
        face = rgb[y:y+h, x:x+w]
        
        #CHECK FACE SIZE (EXIST OR NOT)
        if face.shape[0]*face.shape[1] > 0:
            
            predicted_name, class_probability = face_recognition(face)

            print("Result: ", predicted_name, class_probability)

【讨论】:

【参考方案12】:

我在尝试放大图像尺寸时遇到了相同的错误消息。将图像类型分配为 uint8 为我完成了工作,我能够将图像大小调整为原始大小的 30 倍。这是一个示例,供遇到此类问题的其他人参考。

scale_percent = 3000
width = int(img.shape[1] * scale_percent / 100)
height = int(img.shape[0] * scale_percent /100)

dim = (width, height)
image = cv2.resize(img.astype('uint8'), dim, interpolation=cv2.INTER_AREA)

【讨论】:

【参考方案13】:

我正在处理 3 个文件:python 脚本、图像和经过训练的模型。

我将这 3 个文件移到它们自己的文件夹中而不是放在其他 python 脚本所在的目录中时,一切正常。

【讨论】:

【参考方案14】:

我有同样的错误。调整图像大小解决了这个问题。但是,我使用在线工具调整图像大小,因为使用枕头调整图像大小并没有解决我的问题。

【讨论】:

以上是关于OpenCV 在大图像上调整大小失败,出现“错误:(-215) ssize.area() > 0 in function cv::resize”的主要内容,如果未能解决你的问题,请参考以下文章

调整在Python中使用Numpy和OpenCV绘制的多边形的大小

在大图像上保存形状

大图像的 OpenCV CvSeq 递归元素访问失败?

opencv的cvCreateImage函数 创建大图像报错

使用 gimp 在大图像上为视屏设置动画

Android NDK开发OpenCV系列:图像融合