Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何从屏幕中提取选定的矩形作为俯视图图像?_Python_Opencv_Computer Vision_Cv2 - Fatal编程技术网

Python 如何从屏幕中提取选定的矩形作为俯视图图像?

Python 如何从屏幕中提取选定的矩形作为俯视图图像?,python,opencv,computer-vision,cv2,Python,Opencv,Computer Vision,Cv2,我写了一些代码来检测图像中的计算机屏幕。我需要对选定矩形中心的像素进行一些处理。如何将选定的矩形提取为矩形图像 import imutils import cv2 image = cv2.imread('test-img/imgRec3.jpg') ratio = image.shape[0] / 300.0 image = imutils.resize(image, height=300) realImage = image.copy() # convert the image to gra

我写了一些代码来检测图像中的计算机屏幕。我需要对选定矩形中心的像素进行一些处理。如何将选定的矩形提取为矩形图像

import imutils
import cv2
image = cv2.imread('test-img/imgRec3.jpg')
ratio = image.shape[0] / 300.0
image = imutils.resize(image, height=300)
realImage = image.copy()

# convert the image to grayscale, blur it, and find edges in the image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
edged = cv2.Canny(gray, 30, 200)

cnts = cv2.findContours(edged.copy(), cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:10]
screenCnt = None

# loop over our contours
for c in cnts:
   # approximate the contour
   peri = cv2.arcLength(c, True)
   approx = cv2.approxPolyDP(c, 0.015 * peri, True)

   if len(approx) == 4:
        screenCnt = approx
        break

cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 3)
cv2.imshow("image", realImage)
cv2.imshow("Screen Rec", image)
cv2.waitKey(0)

提前感谢您的帮助。

使用skimage,您可以这样做:

def transform(intersections, image):
    w,h = get_orientation()
    a = np.array([0,h])
    b = np.array([w,h])
    c = np.array([w,0])
    d = np.array([0,0])
    tf = skimage.transform.estimate_transform("projective",
        dst=np.vstack((a,b,c,d)),
        src=intersections)
    invtf = tf.inverse
    transformedImage = skimage.transform.warp(image=image,inverse_map=invtf, output_shape=(h,w))
    return transformedImage

fig,(ax0,ax1) = plt.subplots(ncols=2, figsize=(15,8))

transformed_image = transform(sorted_intersec, img[index] )
ax0.imshow(transformed_image,cmap="gray")

ax1.imshow(img[index])

交点是你的4条边。记住,你必须把它们按正确的顺序排列

要将选定的矩形提取为矩形图像,我们可以使用获取图像的自顶向下视图。因为您能够找到矩形的边界框,所以我们可以使用这些坐标作为新图像的角点。首先,我们将四个角分成
cv2.approxPolyDP()
提供给我们的各个点。我们使用此函数将点重新排序为顺时针方向(左上、右上、右下、左下):

def order_corner_points(corners):
    # Separate corners into individual points
    # Index 0 - top-right
    #       1 - top-left
    #       2 - bottom-left
    #       3 - bottom-right
    corners = [(corner[0][0], corner[0][1]) for corner in corners]
    top_r, top_l, bottom_l, bottom_r = corners[0], corners[1], corners[2], corners[3]
    return (top_l, top_r, bottom_r, bottom_l)
现在使用孤立的角点,我们找到自顶向下图像的新宽度和长度尺寸。我们可以使用
cv2.getPerspectiveTransform()
获得变换矩阵,并使用
cv2.warpPerspective()
实际获得变换后的图像

获得的边界框坐标

提取的矩形

完整代码

import imutils
import cv2
import numpy as np

def order_corner_points(corners):
    # Separate corners into individual points
    # Index 0 - top-right
    #       1 - top-left
    #       2 - bottom-left
    #       3 - bottom-right
    corners = [(corner[0][0], corner[0][1]) for corner in corners]
    top_r, top_l, bottom_l, bottom_r = corners[0], corners[1], corners[2], corners[3]
    return (top_l, top_r, bottom_r, bottom_l)

def perspective_transform(image, corners):

    # Order points in clockwise order
    ordered_corners = order_corner_points(corners)
    top_l, top_r, bottom_r, bottom_l = ordered_corners

    # Determine width of new image which is the max distance between 
    # (bottom right and bottom left) or (top right and top left) x-coordinates
    width_A = np.sqrt(((bottom_r[0] - bottom_l[0]) ** 2) + ((bottom_r[1] - bottom_l[1]) ** 2))
    width_B = np.sqrt(((top_r[0] - top_l[0]) ** 2) + ((top_r[1] - top_l[1]) ** 2))
    width = max(int(width_A), int(width_B))

    # Determine height of new image which is the max distance between 
    # (top right and bottom right) or (top left and bottom left) y-coordinates
    height_A = np.sqrt(((top_r[0] - bottom_r[0]) ** 2) + ((top_r[1] - bottom_r[1]) ** 2))
    height_B = np.sqrt(((top_l[0] - bottom_l[0]) ** 2) + ((top_l[1] - bottom_l[1]) ** 2))
    height = max(int(height_A), int(height_B))

    # Construct new points to obtain top-down view of image in 
    # top_r, top_l, bottom_l, bottom_r order
    dimensions = np.array([[0, 0], [width - 1, 0], [width - 1, height - 1], 
                    [0, height - 1]], dtype = "float32")

    # Convert to Numpy format
    ordered_corners = np.array(ordered_corners, dtype="float32")

    # Find perspective transform matrix
    matrix = cv2.getPerspectiveTransform(ordered_corners, dimensions)

    # Return the transformed image
    return cv2.warpPerspective(image, matrix, (width, height))

image = cv2.imread('1.jpg')
ratio = image.shape[0] / 300.0
image = imutils.resize(image, height=300)
realImage = image.copy()

# convert the image to grayscale, blur it, and find edges in the image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
edged = cv2.Canny(gray, 30, 200)

cnts = cv2.findContours(edged.copy(), cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:10]
screenCnt = None

# loop over our contours
for c in cnts:
    # approximate the contour
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.015 * peri, True)

    if len(approx) == 4:
        screenCnt = approx
        transformed = perspective_transform(realImage, screenCnt)
        break

cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 3)
cv2.imshow("image", realImage)
cv2.imshow("Screen Rec", image)
cv2.imshow("transformed", transformed)
cv2.waitKey(0)

使用透视变换:查看这篇文章,它可能会帮助你处理类似的问题。你能发布原始图像吗?@nathancy我添加了itthanks,但什么是get_orientation()?这是在简历或其他地方定义的功能?对不起,我上床睡觉了。忘记添加这个函数了。这与@Nathance的做法非常相似。因为他的回答很好,所以我会这样做。没问题:考虑接受答案,让别人知道你的问题已经解决了。
import imutils
import cv2
import numpy as np

def order_corner_points(corners):
    # Separate corners into individual points
    # Index 0 - top-right
    #       1 - top-left
    #       2 - bottom-left
    #       3 - bottom-right
    corners = [(corner[0][0], corner[0][1]) for corner in corners]
    top_r, top_l, bottom_l, bottom_r = corners[0], corners[1], corners[2], corners[3]
    return (top_l, top_r, bottom_r, bottom_l)

def perspective_transform(image, corners):

    # Order points in clockwise order
    ordered_corners = order_corner_points(corners)
    top_l, top_r, bottom_r, bottom_l = ordered_corners

    # Determine width of new image which is the max distance between 
    # (bottom right and bottom left) or (top right and top left) x-coordinates
    width_A = np.sqrt(((bottom_r[0] - bottom_l[0]) ** 2) + ((bottom_r[1] - bottom_l[1]) ** 2))
    width_B = np.sqrt(((top_r[0] - top_l[0]) ** 2) + ((top_r[1] - top_l[1]) ** 2))
    width = max(int(width_A), int(width_B))

    # Determine height of new image which is the max distance between 
    # (top right and bottom right) or (top left and bottom left) y-coordinates
    height_A = np.sqrt(((top_r[0] - bottom_r[0]) ** 2) + ((top_r[1] - bottom_r[1]) ** 2))
    height_B = np.sqrt(((top_l[0] - bottom_l[0]) ** 2) + ((top_l[1] - bottom_l[1]) ** 2))
    height = max(int(height_A), int(height_B))

    # Construct new points to obtain top-down view of image in 
    # top_r, top_l, bottom_l, bottom_r order
    dimensions = np.array([[0, 0], [width - 1, 0], [width - 1, height - 1], 
                    [0, height - 1]], dtype = "float32")

    # Convert to Numpy format
    ordered_corners = np.array(ordered_corners, dtype="float32")

    # Find perspective transform matrix
    matrix = cv2.getPerspectiveTransform(ordered_corners, dimensions)

    # Return the transformed image
    return cv2.warpPerspective(image, matrix, (width, height))

image = cv2.imread('1.jpg')
ratio = image.shape[0] / 300.0
image = imutils.resize(image, height=300)
realImage = image.copy()

# convert the image to grayscale, blur it, and find edges in the image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
gray = cv2.bilateralFilter(gray, 11, 17, 17)
edged = cv2.Canny(gray, 30, 200)

cnts = cv2.findContours(edged.copy(), cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnts = sorted(cnts, key = cv2.contourArea, reverse = True)[:10]
screenCnt = None

# loop over our contours
for c in cnts:
    # approximate the contour
    peri = cv2.arcLength(c, True)
    approx = cv2.approxPolyDP(c, 0.015 * peri, True)

    if len(approx) == 4:
        screenCnt = approx
        transformed = perspective_transform(realImage, screenCnt)
        break

cv2.drawContours(image, [screenCnt], -1, (0, 255, 0), 3)
cv2.imshow("image", realImage)
cv2.imshow("Screen Rec", image)
cv2.imshow("transformed", transformed)
cv2.waitKey(0)