python - 如何在 cv2.resize 中找到像素映射到的位置?
问题描述
我想知道,考虑到用于使用 cv2.resize 调整图像大小的插值类型。我怎样才能准确地找出特定像素映射的位置?例如,如果我使用 Linear_interpolation 增加图像的大小并且我为特定像素获取坐标 (785, 251),无论源图像和调整大小的图像之间的纵横比是否发生变化,我怎么能找到在调整大小的版本中,与坐标 == (785, 251) 映射的源图像中的像素到底是什么坐标?我已经在互联网上查看了解决方案,但所有解决方案似乎都是间接方法来找出实际上不适用于不同纵横比的像素图:
https://answers.opencv.org/question/209827/resize-and-remap/
有没有办法通过 cv2 访问像素的映射方式,并通过反转脚本找出新的坐标?
我想要这样做的原因是,我希望能够创建边界框,无论给定图像的纵横比如何变化,都能给我返回相同的信息。到目前为止,我使用的每种方法都没有给我相同的信息。我想如果我能弄清楚 x,y 左上角和右下角的特定像素坐标映射的位置,我可以重新创建一个准确的边界框,而不管纵横比如何变化。
解决方案
当中心坐标为(0, 0)时,缩放坐标有效。
您可以计算x_scaled
和y_scaled
如下:
- 从和中减去
x_original_center
和。 减法后,(0, 0) 就是“新中心”。y_original_center
x_original
y_original
scale_x
通过和缩放“零中心”坐标scale_y
。x_scaled_center
通过添加和将“缩放的零中心”坐标转换为“左上角 (0, 0)”y_scaled_center
。
准确计算中心:
Python转换为:
(0, 0)为左上角,(cols-1, rows-1)为右下角坐标。
准确的中心坐标为:
x_original_center = (original_rows-1)/2
y_original_center = (original_cols-1)/2
Python代码(假设img
是原图):
resized_img = cv2.resize(img, [int(cols*scale_x), int(rows*scale_y)])
rows, cols = img.shape[0:2]
resized_rows, resized_cols = resized_img.shape[0:2]
x_original_center = (cols-1) / 2
y_original_center = (rows-1) / 2
x_scaled_center = (resized_cols-1) / 2
y_scaled_center = (resized_rows-1) / 2
# Subtract the center, scale, and add the "scaled center".
x_scaled = (x_original - x_original_center)*scale_x + x_scaled_center
y_scaled = (y_original - y_original_center)*scale_y + y_scaled_center
测试
以下代码示例在几个原始坐标和缩放坐标处绘制十字:
import cv2
def draw_cross(im, x, y, use_color=False):
""" Draw a cross with center (x,y) - cross is two rows and two columns """
x = int(round(x - 0.5))
y = int(round(y - 0.5))
if use_color:
im[y-4:y+6, x] = [0, 0, 255]
im[y-4:y+6, x+1] = [255, 0, 0]
im[y, x-4:x+6] = [0, 0, 255]
im[y+1, x-4:x+6] = [255, 0, 0]
else:
im[y-4:y+6, x] = 0
im[y-4:y+6, x+1] = 255
im[y, x-4:x+6] = 0
im[y+1, x-4:x+6] = 255
img = cv2.imread('graf.png') # http://man.hubwiz.com/docset/OpenCV.docset/Contents/Resources/Documents/db/d70/tutorial_akaze_matching.html
rows, cols = img.shape[0:2] # cols = 320, rows = 256
# 3 points for testing:
x0_original, y0_original = cols//2-0.5, rows//2-0.5 # 159.5, 127.5
x1_original, y1_original = cols//5-0.5, rows//4-0.5 # 63.5, 63.5
x2_original, y2_original = (cols//5)*3+20-0.5, (rows//4)*3+30-0.5 # 211.5, 221.5
draw_cross(img, x0_original, y0_original) # Center of cross (159.5, 127.5)
draw_cross(img, x1_original, y1_original)
draw_cross(img, x2_original, y2_original)
scale_x = 2.5
scale_y = 2
resized_img = cv2.resize(img, [int(cols*scale_x), int(rows*scale_y)], interpolation=cv2.INTER_NEAREST)
resized_rows, resized_cols = resized_img.shape[0:2] # cols = 800, rows = 512
# Compute center column and center row
x_original_center = (cols-1) / 2 # 159.5
y_original_center = (rows-1) / 2 # 127.5
# Compute center of resized image
x_scaled_center = (resized_cols-1) / 2 # 399.5
y_scaled_center = (resized_rows-1) / 2 # 255.5
# Compute the destination coordinates after resize
x0_scaled = (x0_original - x_original_center)*scale_x + x_scaled_center # 399.5
y0_scaled = (y0_original - y_original_center)*scale_y + y_scaled_center # 255.5
x1_scaled = (x1_original - x_original_center)*scale_x + x_scaled_center # 159.5
y1_scaled = (y1_original - y_original_center)*scale_y + y_scaled_center # 127.5
x2_scaled = (x2_original - x_original_center)*scale_x + x_scaled_center # 529.5
y2_scaled = (y2_original - y_original_center)*scale_y + y_scaled_center # 443.5
# Draw crosses on resized image
draw_cross(resized_img, x0_scaled, y0_scaled, True)
draw_cross(resized_img, x1_scaled, y1_scaled, True)
draw_cross(resized_img, x2_scaled, y2_scaled, True)
cv2.imshow('img', img)
cv2.imshow('resized_img', resized_img)
cv2.waitKey()
cv2.destroyAllWindows()
注意:
在我的回答中,我使用了 Miki 评论的命名约定。
推荐阅读
- angular - RouterLink 不会在单击时导航到组件,而是在加载同一模块中的其他组件后导航
- laravel - 操作总是返回未经授权的
- c - 从输入文件读取数据并放入数组的函数
- mysql - Why is my SQL query not using the table's composite index?
- javascript - 浏览器语言。奇怪的行为 - Javascript
- c# - 将xml反序列化为对象列表
- php - Unable to convert xml into html when passing from a laravel controller
- c# - SQL 代理 - Zipfile.ExtractToDirectory 不起作用
- python - 在 chrome 调试模式下 Selenium-webdriver 打开的现有浏览器会话中打开网页
- python - Return only the first word from a sentence and all other unique words from text file?