gpt4 book ai didi

python - 使用 OpenCV Python 以与引用图像相同的方向和尺寸转换和显示裁剪图像

转载 作者:太空宇宙 更新时间:2023-11-03 21:39:39 25 4
gpt4 key购买 nike

我有一张引用图像,我正在使用 ORB 检测在更大的测试图像中找到该引用图像。找到后,我只想将裁剪区域中的区域保存为新图像。我想将其转换为与引用图像相同的尺寸并以相同的方向保存。

到目前为止,我已经匹配了较大图像中的引用图像并将其屏蔽掉。但我无法弄清楚如何以正确的方向和尺寸仅将裁剪区域显示为自己的图片。我想保存裁剪中的东西并摆脱其余部分。

如有任何帮助,我们将不胜感激。谢谢。

enter image description here enter image description here enter image description here enter image description here

import cv2
import numpy as np

#minimum ORB matches required to make a match
MIN_MATCH_COUNT = 10

img1 = cv2.imread("reference.jpg")
img2 = cv2.imread("1.jpg")

orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2, None)

# sorts matches
good = []
for i, m in enumerate(matches):
if i < len(matches) - 1 and m.distance < 0.7 * matches[i+1].distance:
good.append(m)

if len(good)>MIN_MATCH_COUNT:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w,d = img1.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)
mask = np.ones(img2.shape[:2], dtype="uint8") * 255
rect = cv2.minAreaRect(dst)
box = cv2.boxPoints(rect)
box = np.int0(box)
new = cv2.drawContours(mask, [box], -1, 0, -1)
# remove the contours from the image and show the resulting images
img = cv2.bitwise_and(img2, img2, mask=mask)
cv2.imshow("Mask", mask)
cv2.imshow("After", img)
else:
print( "Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT) )
matchesMask = None

#This is for drawing the match lines inbetween the ref and 1.jpg images
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
singlePointColor = None,
matchesMask = matchesMask, # draw only inliers
flags = 2)
img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
cv2.imshow("Matches", img3)

最佳答案

您走在正确的轨道上,并且已经完成了大部分工作。由于您已经找到了 ROI 掩码,您可以执行透视变换以获得正确的方向。之后,您可以调整图像大小以匹配您的引用/模板图像。

首先我们反转蒙版以获得所需的白色 ROI,然后在此蒙版上找到轮廓。从这里我们使用 cv2.arcLength()cv2.approxPolyDP() 找到角点。接下来我们透视变换得到这个

enter image description here

template shape: (210, 236, 3)
transformed shape: (288, 279, 3)

现在我们有了正确的方向,我们只需要简单地调整大小以匹配模板图像。这是结果(左)和模板图像(右)

enter image description here enter image description here

template shape: (210, 236, 3)
resized shape: (210, 236, 3)

代码

import cv2
import numpy as np

def perspective_transform(image, corners):
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)

# 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))

#minimum ORB matches required to make a match
MIN_MATCH_COUNT = 10

img1 = cv2.imread("reference.jpg")
img2 = cv2.imread("1.jpg")

orb = cv2.ORB_create()
kp1, des1 = orb.detectAndCompute(img1,None)
kp2, des2 = orb.detectAndCompute(img2,None)

bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
matches = bf.match(des1, des2, None)

# sorts matches
good = []
for i, m in enumerate(matches):
if i < len(matches) - 1 and m.distance < 0.7 * matches[i+1].distance:
good.append(m)

if len(good)>MIN_MATCH_COUNT:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w,d = img1.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)
mask = np.ones(img2.shape[:2], dtype="uint8") * 255
rect = cv2.minAreaRect(dst)
box = cv2.boxPoints(rect)
box = np.int0(box)
new = cv2.drawContours(mask, [box], -1, 0, -1)
# remove the contours from the image and show the resulting images
img = cv2.bitwise_and(img2, img2, mask=mask)
mask = 255 - mask
cv2.imshow("After", img)
else:
print( "Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT) )
matchesMask = None

#This is for drawing the match lines inbetween the ref and 1.jpg images
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
singlePointColor = None,
matchesMask = matchesMask, # draw only inliers
flags = 2)
img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
cv2.imshow("Matches", img3)

cv2.imshow("Mask", mask)

# Find contour on mask and perform perspective transform
cnts = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]

for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.015 * peri, True)
if len(approx) == 4:
transformed = perspective_transform(img2, approx)

cv2.imshow("transformed", transformed)

print('template shape:', img1.shape)
print('transformed shape:',transformed.shape)

resized = cv2.resize(transformed, (img1.shape[1], img1.shape[0]))
cv2.imshow("resized", resized)
print('template shape:', img1.shape)
print('resized shape:',resized.shape)
cv2.waitKey()

关于python - 使用 OpenCV Python 以与引用图像相同的方向和尺寸转换和显示裁剪图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57930961/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com