如何从该图像中裁剪手机?

Posted

技术标签:

【中文标题】如何从该图像中裁剪手机?【英文标题】:How to crop the mobile from that image? 【发布时间】:2021-04-13 06:49:18 【问题描述】:

我想从下图裁剪手机:

为此,我尝试检测图像中的矩形形状,然后使用以下代码裁剪图像:

import cv2
import numpy as np

img = cv2.imread('rt1.jpg')

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

ret , thrash = cv2.threshold(imgGry, 240 , 255, cv2.CHAIN_APPROX_NONE)
contours , hierarchy = cv2.findContours(thrash, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
j=0
for contour in contours:
    approx = cv2.approxPolyDP(contour, 0.01* cv2.arcLength(contour, True), True)
    cv2.drawContours(img, [approx], 0, (0, 0, 0), 5)
    if len(approx) == 4 :
        x, y , w, h = cv2.boundingRect(approx)
        cv2.putText(img, "mobile", (x, y), cv2.FONT_HERSHEY_COMPLEX, 0.5, (0, 0, 0))
        out = img[y:y+h,x:x+w]
        cv2.imwrite('cropped'+str(j)+'.jpg', out)
        j = j+1
cv2.imshow('shapes', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

但它没有裁剪手机。您能否建议对代码进行任何改进以获得所需的结果?

【问题讨论】:

【参考方案1】:

无需对轮廓进行近似。对于该特定图像,您将获得一个大轮廓,您可以简单地从中获取边界矩形,然后裁剪所需的部分。我可以选择添加设置背景透明。

import cv2
import numpy as np

# Read image, convert to grayscale
img = cv2.imread('images/2EZyS.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# Threshold image, attention: cv2.THRESH_BINARY_INV!
thr = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)[1]

# Find contours w.r.t. the OpenCV version, attention: cv2.RETR_EXTERNAL!
cnts = cv2.findContours(thr, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

# Filter contours by size
cnts = [cnt for cnt in cnts if cv2.contourArea(cnt) > 2000]
thr = cv2.drawContours(np.zeros_like(thr), cnts, -1, 255, cv2.FILLED)

# Prepare output
out = img.copy()

# Optional: Set background transparent.
out = cv2.cvtColor(img, cv2.COLOR_BGR2BGRA)
out[..., 3] = thr

# Crop
x, y, w, h = cv2.boundingRect(thr)
out = out[y:y+h, x:x+w]

# Save with and without transparency
cv2.imwrite('crop_w.png', out)
cv2.imwrite('crop_wo.png', out[..., :3])

那将是具有透明度的输出图像:

在您的原始代码中,您在 cv2.threshold 调用中有 cv2.CHAIN_APPROX_NONE。偶然地,该值等于1,这也是cv2.THRESH_BINARY_INV。不过,您应该注意这些细节。

另外,我会在这里使用cv2.RETR_EXTERNAL 而不是cv2.RETR_TREE,因为您只有一个对象,因此找到最外侧的轮廓就足够了。

----------------------------------------
System information
----------------------------------------
Platform:      Windows-10-10.0.16299-SP0
Python:        3.9.1
NumPy:         1.20.2
OpenCV:        4.5.1
----------------------------------------

【讨论】:

以上是关于如何从该图像中裁剪手机?的主要内容,如果未能解决你的问题,请参考以下文章

裁剪图像并将图像保存为圆形 JCrop

用 python 裁剪手机图像

使用 php 保存裁剪的图像

android如何使用现有图像进行裁剪

使用 java image.getSubimage 裁剪图像的问题

1.图像裁剪、加边框、旋转(Python PIL)