如何从该图像裁剪手机?

时间:2021-04-13 06:49:18

标签: python opencv crop

我想从下面的图片中裁剪手机:

crop mobile phone

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

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 个答案:

答案 0 :(得分: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])

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

Output with transparency

在您的原始代码中,您在 cv2.CHAIN_APPROX_NONE 调用中有 cv2.threshold。碰巧的是,该值等于 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
----------------------------------------