【问题标题】:Cropping greyscale images within larger images using OpenCV and python使用 OpenCV 和 python 在较大的图像中裁剪灰度图像
【发布时间】:2018-06-08 11:29:44
【问题描述】:

您好,我是 python 和 opencv 的新手。我有这张图片:

我正在尝试从图片中裁剪灰度图像。目前,代码找到最大的边界框,即右上角的图像,然后对其进行裁剪。我想要做的是找到所有灰度图像,即使图片中有超过 4 个并裁剪所有图像。我正在考虑使用循环来执行此操作,但我不想设置一个循环,它会找到最大的边界框 4 次,然后停止,因为我正在处理的其他图像将包含超过 4 个图像。任何帮助将不胜感激!

import cv2
import numpy as np

# load image
img = cv2.imread('multi.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # convert to grayscale
# threshold to get just the signature (INVERTED)
retval, thresh_gray = cv2.threshold(gray, thresh=100, maxval=255, \
                                    type=cv2.THRESH_BINARY_INV)

image, contours, hierarchy = cv2.findContours(thresh_gray,cv2.RETR_LIST, \
                                              cv2.CHAIN_APPROX_SIMPLE)

# Find object with the biggest bounding box
mx = (0,0,0,0)      # biggest bounding box so far
mx_area = 0
for cont in contours:
    x,y,w,h = cv2.boundingRect(cont)
    area = w*h
    if area > mx_area:
        mx = x,y,w,h
        mx_area = area
x,y,w,h = mx

# Find object with the biggest bounding box

mx = (0,0,0,0)      # biggest bounding box so far
mx_area = 0
for cont in contours:
    x,y,w,h = cv2.boundingRect(cont)
    area = w*h
    if area > mx_area:
        mx = x,y,w,h
        mx_area = area
x,y,w,h = mx

# Output to files
roi=img[y:y+h,x:x+w]
cv2.imwrite('Image_crop.jpg', roi)

cv2.rectangle(img,(x,y),(x+w,y+h),(200,0,0),2)
cv2.imwrite('Image_cont.jpg', img)

【问题讨论】:

  • 您可以使用HERE 中的cv.contourArea(cnt) 找到轮廓区域。为必须找到轮廓的区域设置阈值并裁剪它们
  • 问题是灰度图像大小不一样。有大有小,但都比底部显示的文字和范围大。
  • 我添加了一个以 10000 作为区域阈值的答案。您可以使用不同的值,因为框大于文本和范围

标签: python numpy opencv image-processing crop


【解决方案1】:

我已经详细说明了我的评论。

在您提供的代码中,使用cv2.RETR_LIST 找到轮廓,其中图像中的每个可能轮廓包括轮廓内的轮廓。我使用了cv2.RETR_EXTERNAL,它忽略了其他轮廓中的那些轮廓。

image = cv2.imread(r'C:\Users\Desktop\g.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

retval, thresh_gray = cv2.threshold(gray, thresh=100, maxval=255, \
                                    type=cv2.THRESH_BINARY_INV)
cv2.imshow('thresh_gray.png', thresh_gray)

image, contours, hierarchy = cv2.findContours(thresh_gray,cv2.RETR_EXTERNAL,                                                 cv2.CHAIN_APPROX_SIMPLE)

for i, c in enumerate(contours):
    if cv2.contourArea(c) > 10000:
        x, y, w, h = cv2.boundingRect(c)
        roi = image[y  :y + h, x : x + w ]

        cv2.imshow('Region_{}.jpg'.format(i), roi)
        cv2.waitKey(0)

cv2.destroyAllWindows()

【讨论】:

  • 谢谢!它现在完美运行。唯一的问题是正在生成的图像具有不同的编号,而不是 Image_crop 1.jpg、Image_crop 2.jpg、Image_crop 3.jpg 和 Image_crop 4.jpg,它显示 Image_crop 5.jpg、Image_crop 6.jpg、Image_crop 20。 jpg 和 Image_crop 67.jpg。
  • @AbidAbdulGafoor 所以你想用实际名称和数字重命名新图像?
  • 如果你明白我的意思,我希望这些数字是一致的并且是连续的,而不是随机的?
  • 为此,您可以使用实际文件名后跟一个数字来保存生成的图像,例如:cv2.imwrite('{}_region_{}'.format(filename, st), img)
  • 可能是个愚蠢的问题,但我不确定 st 是什么?
猜你喜欢
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-31
  • 1970-01-01
  • 1970-01-01
  • 2013-03-13
相关资源
最近更新 更多