如何根据蒙版阈值裁剪图像?

Posted

技术标签:

【中文标题】如何根据蒙版阈值裁剪图像?【英文标题】:How to crop images based on mask threshold? 【发布时间】:2021-10-02 08:46:49 【问题描述】:

我必须手动裁剪大量图像。这不是最有趣的事情。所以我想我会尝试使用 Python 来实现。

我可以检测主题,创建蒙版,但我不知道如何从最底部获取点并根据它们进行裁剪。

感谢任何帮助

import cv2

img = cv2.imread('image5.jpg')
h, w = img.shape[:2]

gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)


thr = cv2.threshold(gray, 192, 255, cv2.THRESH_BINARY_INV)[1]
cv2.imwrite('result5.png', thr)

【问题讨论】:

cv.boundingRect 不确定如何使用OpenCVImageMagick 进行标记,但您可以像这样使用后者... ***.com/a/35770591/2836621 很抱歉,您是要裁剪主题还是只裁剪主题下方的部分? 我可以通过查找人体姿态估计(如眼睛、鼻子、鼻梁)来裁剪顶部。那部分很好。我只需要裁剪底部 【参考方案1】:

您可以尝试使用 cv2.RETR_EXTERNAL 查找所有外部轮廓并选择最底部的点,如下所示:

import cv2
import numpy as np
import imutils

im = cv2.imread('images/tennis.jpg')

# Percent of original size
scale_percent = 20 
width = int(im.shape[1] * scale_percent / 100)
height = int(im.shape[0] * scale_percent / 100)
dim = (width, height)
  
# Resize image
im = cv2.resize(im, dim, interpolation = cv2.INTER_AREA)

# Convert to grayscale
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)

# Canny
canny_output = cv2.Canny(im, 120, 240)

# Find external contours
contours, hierarchy = cv2.findContours(canny_output, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#cv2.drawContours(im, [contours[0]], 0, (0,255,0), 3) # Uncomment this line to see what contour opencv is finding

# Pick the bottom most point and add an offset (whatever value you want, this is just for aesthetics)
c = contours[0]
bottommost = tuple(c[c[:, :, 1].argmax()][0])[1] + 5

# Crop image
im = im[:bottommost, :]

# Show image
cv2.imshow('image', im)
cv2.waitKey()

【讨论】:

非常聪明!我只是想了解它是如何工作的。为什么要将图像缩放到 20% ?精明的输出值是什么?那 120,240 人? 此外,在某些情况下,最底点只是一个小点......就像一个像素......比它不是很准确:(关于其他人建议的非零的东西:(但是它越来越接近我的需要了。 嗨@Andie31,缩放没有任何作用,我添加了它,所以我可以在屏幕上看到整个图像,你可以将该变量更改回 100。 当您将 cv2.RETR_EXTERNAL 作为参数传递给 findContours 时,opencv 将返回图像的外部轮廓列表,其中第一个轮廓(索引 0)是最外面的轮廓。因此,如果您对该数组执行 np.amax,您应该能够找到一个好的裁剪点。 @Andie31 在使用精明检测之前尝试模糊图像:code blur = cv.GaussianBlur(gray,(5,5),0) 并且他们确保您参考了模糊图像精巧的检测线【参考方案2】:

我想说的很好!现在执行:

xx,yy = thrs.nonzero()
max_crop_h = xx.max()
crop = img[:max_crop_h,:]

numpy 支持你!

【讨论】:

如果我能实现这个就好了:) 我昨天在与 nonzero() 的聊天中已经得到了这个建议,但我不知道如何实现它。我是一名摄影师,我的编程能力有限。 @Mark Setchell 我试过那个 imagemagick 但这不是我需要的:(

以上是关于如何根据蒙版阈值裁剪图像?的主要内容,如果未能解决你的问题,请参考以下文章

裁剪图像以获取特殊路径

Imagemagick 将透明图像裁剪为蒙版

使用 imagemagick 将垫调整大小的蒙版应用于裁剪调整大小的图像

如何从图像中裁剪或删除白色背景

canvas裁剪图片,蒙版选择框

Fabric JS 2.4.1 如何使用 clipPath 裁剪已缩放为小于或大于 1:1 比例的图像