【问题标题】:Problem in cropping a bounding box out of an image [duplicate]从图像中裁剪边界框的问题[重复]
【发布时间】:2022-01-28 17:29:58
【问题描述】:

我的目标是使用 opencv 的 cv2 库从图像中裁剪出边界框。我从here 找到了一种有趣的方法,但是我收到了类似的错误

>ValueError: not enough values to unpack (expected 3, got 2)

这是完整的回溯:

Traceback (most recent call last):
  File "text_extraction.py", line 13, in <module>
    image, contours, hierarchy = cv2.findContours(mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
ValueError: not enough values to unpack (expected 3, got 2)

这是我的完整代码:

import cv2
import numpy as np
import pytesseract

pytesseract.pytesseract.tesseract_cmd = 'C:/Program Files/Tesseract-OCR/tesseract.exe'
im = cv2.imread('detected-image-2.png')
grayimage = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(grayimage, 170, 255, cv2.THRESH_BINARY)
cv2.imshow('mask', mask)
image, contours, hierarchy = cv2.findContours(mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
    if cv2.contourArea(contour) < 200:
        continue
    rect = cv2.minAreaRect(contour)
    box = cv2.boxPoints(rect)

    ext_left = tuple(contour[contour[:, :, 0].argmin()][0])
    ext_right = tuple(contour[contour[:, :, 0].argmax()][0])
    ext_top = tuple(contour[contour[:, :, 1].argmin()][0])
    ext_bot = tuple(contour[contour[:, :, 1].argmax()][0])

    roi_corners = np.array([box], dtype=np.int32)

    cv2.polylines(im, roi_corners, 1, (255, 0, 0), 3)
    cv2.imshow('image', im)
    cv2.waitKey(0)

    cropped_image = grayimage[ext_top[1]:ext_bot[1], ext_left[0]:ext_right[0]]
    cv2.imwrite('crop.jpg', cropped_image)

这段代码到底有什么问题? 我对 OpenCV 比较陌生,请帮帮我。

编辑:我什至通过参考this 的答案尝试了一种方法,但是问题仍然存在。

EDIT-2:在解决值错误后,脚本无法保存裁剪后的图像(它正在将图像保存为原样)。基于状态机代码,我将代码更改为:

im = cv2.imread('detected-image-2.png')
grayimage = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, mask = cv2.threshold(grayimage, 170, 255, cv2.THRESH_BINARY)
cv2.imshow('mask', mask)
cv2.waitKey(0)
contours, hierarchy = cv2.findContours(mask, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

for contour in contours:
    if cv2.contourArea(contour) < 200:
        continue
    rect = cv2.minAreaRect(contour)
    box = cv2.boxPoints(rect)
    X, Y, W, H = cv2.boundingRect(contour)
    cropped_image = im[Y:Y + H, X:X + W]
    print([X, Y, W, H])
    plt.imshow(cropped_image)
    cv2.imwrite('contour1.png', cropped_image)

但是输出仍然相同(没有进行裁剪)。

【问题讨论】:

  • 您使用的是哪个版本的OpenCV?在我看来,您正在使用版本。 4.+,在这种情况下,findContours 只返回两个值:contours, hierarchy。对于OpenCV 版本。 3.+ 它返回三个值。更多信息here.
  • Opencv 版本是 4.5,从 findContours 中删除了 image 变量,它可以工作..但是保存的crop.jpg 文件没有被裁剪。
  • 计算contourbounding rectangle,它会返回左上角坐标及其heightwidth,像这样:x, y, w, h = cv2.boundingRect(countour)。您可以使用此信息对原始图像进行切片(裁剪)。
  • 这仍然没有帮助:让我用更新的代码编辑问题。 @stateMachine
  • 您找到了答案,但您只能说您“尝试过”并且“问题仍然存在”。你的尝试的一些细节会帮助你。 - 然后继续“无法保存裁剪的图像”意味着您完全改变了问题的精神。这应该是一个新问题。

标签: python opencv image-processing cv2


【解决方案1】:

在找出我犯错的地方后自己解决了它,以防万一有人遇到类似的问题,这段代码会有所帮助。

def crop():
    # reading image
    image = cv2.imread("detected-image-1.png")

    # converting to gray scale
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

    # applying canny edge detection
    edged = cv2.Canny(gray, 10, 250)

    # finding contours
    (cnts, _) = cv2.findContours(edged.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
    idx = 0
    for c in cnts:
        x, y, w, h = cv2.boundingRect(c)
        if w > 50 and h > 50:
            idx += 1
            new_img = image[y:y + h, x:x + w]
            # cropping images
            cv2.imwrite("cropped/" + str(idx) + '.png', new_img)
    print('Objects Cropped Successfully!')

【讨论】:

    猜你喜欢
    • 2018-10-24
    • 1970-01-01
    • 2020-12-26
    • 1970-01-01
    • 2022-01-05
    • 2020-08-12
    • 2017-06-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多