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)