【问题标题】:Crop phone screen using contour使用轮廓裁剪手机屏幕
【发布时间】:2018-03-16 09:31:21
【问题描述】:

我想裁剪图片上给出的手机屏幕。我尝试了这段代码,但结果不是我想要的。 Phone Screen

import cv2
import numpy as np

img = cv2.imread('phone_test.jpg')
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
_,thresh = cv2.threshold(gray,1,255,cv2.THRESH_BINARY)

_, contours, _= cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
x,y,w,h = cv2.boundingRect(contours[0])

crop = img[y:y+h,x:x+w]
cv2.imwrite('phone_test_crop.jpg',crop)
cv2.namedWindow('image', cv2.WINDOW_NORMAL)
cv2.imshow('image',img) #show the image
cv2.waitKey(0)

结果就是这样 Crop Result

有什么解决办法吗?

【问题讨论】:

  • 好吧,你基本上是在说任何不是纯黑色的东西(在 jpg 中,你会对结果感到惊讶:))应该在轮廓算法中使用。你看过你的thresh 图像了吗?您可能想要一种更高的价值来将屏幕与其他一切隔离开来。您还可以获取手机的边框,因此您可能会得到多个轮廓......您只需检查轮廓编号 0...您甚至可以检查这是否是您想要使用的正确轮廓。

标签: python opencv contour


【解决方案1】:

好的,这是我为我编写和工作的代码。

import cv2
import numpy as np

img = cv2.imread('phone.jpg')
# cv2.imshow('image', img)
# cv2.waitKey(0)

# Convert BGR to HSV
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)

# define range of blue color in HSV
lower = np.array([20, 20, 20])
upper = np.array([220, 220, 220])

# Threshold the HSV image to get only blue colors
mask = cv2.inRange(hsv, lower, upper)
# cv2.imshow('mask', mask)
# cv2.waitKey(0)

kernel = np.ones((1, 10), np.uint8)
img_dilation = cv2.dilate(mask, kernel, iterations=1)
# cv2.imshow('dilated', img_dilation)
# cv2.waitKey(0)

# find contours
im2, ctrs, hier = cv2.findContours(img_dilation.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# sort contours
sorted_ctrs = sorted(ctrs, key=lambda ctr: cv2.boundingRect(ctr)[0])

for i, ctr in enumerate(sorted_ctrs):
    # Get bounding box
    x, y, w, h = cv2.boundingRect(ctr)

    # Getting ROI
    roi = img[y:y + h, x:x + w]

    # show ROI
    # cv2.imshow('segment no:'+str(i), roi)
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 0), 1)  # put (0,255,0) to see green rectangles
    # cv2.waitKey(0)

    if h > 100 and 350 < w < 450:
        # cv2.imshow('marked areas', img)
        # cv2.waitKey(0)

        # cv2.imshow('roi', roi)
        # cv2.waitKey(0)

        cv2.imwrite('extracted_screen.png', roi)

取决于您调整代码以适应特定需求(例如:屏幕提取的或多或少的精度)。

结果

【讨论】:

  • 我尝试了代码,但它不起作用。我找到了另一个解决方案
【解决方案2】:

这是我解决问题的方法。

import cv2
import numpy as np 

# read and scale down image
img = cv2.pyrDown(cv2.imread('sample_images/phone_test.jpg', 
cv2.IMREAD_UNCHANGED))

# threshold image
ret, threshed_img = cv2.threshold(cv2.cvtColor(img, cv2.COLOR_BGR2GRAY),
            150, 255, cv2.THRESH_BINARY)
# find contours and get the external one
image, contours, hier = cv2.findContours(threshed_img, 
cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

for c in contours:
    # get the bounding rect
    x, y, w, h = cv2.boundingRect(c)
    crop = img[y:y+h+22,x:x+w+5] #give a bit of space, because the boundingRect is not perfect

cv2.imwrite('sample_images/phone_test_crop.jpg', crop)

cv2.destroyAllWindows()

之前: Before crop

之后: After crop

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-06
    • 2021-02-01
    • 2015-04-29
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多