- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
这是 remap() 最简单的测试用例:
import cv2
import numpy as np
inimg = np.arange(2*2).reshape(2,2).astype(np.float32)
inmap = np.array([[0,0],[0,1],[1,0],[1,1]]).astype(np.float32)
outmap = np.array([[10,10],[10,20],[20,10],[20,20]]).astype(np.float32)
outimg = cv2.remap(inimg,inmap,outmap,cv2.INTER_LINEAR)
print "inimg:",inimg
print "inmap:",inmap
print "outmap:",outmap
print "outimg:", outimg
这是输出:
inimg: [[ 0. 1.]
[ 2. 3.]]
inmap: [[ 0. 0.]
[ 0. 1.]
[ 1. 0.]
[ 1. 1.]]
outmap: [[ 10. 10.]
[ 10. 20.]
[ 20. 10.]
[ 20. 20.]]
outimg: [[ 0. 0.]
[ 0. 0.]
[ 0. 0.]
[ 0. 0.]]
如您所见,outimg 生成 0,0,而且它的形状甚至都不正确。我希望 20x20 或 10x10 的图像具有 0 到 3 范围内的插值。
我已经阅读了所有文档。它和 SO 上的每个人都声明你输入一个起点数组( map ),一个终点 map ,然后 remap() 会将 img 中的所有值放入它们的新位置,插入任何空白空间。我正在这样做,但它不起作用。为什么?大多数示例适用于 C++。它在python中坏了吗?
最佳答案
这只是对文档的一个简单误解,我不怪你——我也花了一些时间才理解它。文档很清楚,但是这个函数可能不会按照你期望的方式工作;事实上,它的工作方向与我最初预期的相反。
remap()
不会做的是获取源图像的坐标、转换点,然后进行插值。 remap()
做的是,对于目标图像中的每个像素,在源图像中查找它来自哪里,然后分配一个插值。它需要以这种方式工作,因为为了进行插值,它需要在每个像素处查看源图像周围的值。让我扩展一下(可能会重复一下,但不要误会)。
来自remap()
docs :
map1 – The first map of either
(x,y)
points or justx
values having the typeCV_16SC2
,CV_32FC1
, orCV_32FC2
. SeeconvertMaps()
for details on converting a floating point representation to fixed-point for speed.map2 – The second map of
y
values having the typeCV_16UC1
,CV_32FC1
, or none (empty map ifmap1
is(x,y)
points), respectively.
map1
上的“the first map of...”的措辞可能令人困惑。请记住,这些是您的图像从 映射的严格坐标...这些点是 从 src
at map_x (x, y), map_y(x, y)
然后放入dst
at x, y
。而且它们应该与您要将它们变形为 的图像形状相同。请注意文档中显示的等式:
dst(x,y) = src(map_x(x,y),map_y(x,y))
此处 map_x(x, y)
在 x, y
给出的行和列中查找 map_x
。然后在这些像素处评估图像值。它在 src
中查找 x, y
的映射坐标,然后将该值赋给 dst
x, y
。如果你盯着它看的时间足够长,它就会开始变得有意义。在新目标图像中的像素 (0, 0)
处,我查看 map_x
和 map_y
,它们告诉我相应像素在源图像,然后我可以通过查看源图像中的附近值在目标图像中的 (0, 0)
处分配一个插值。这是 remap()
以这种方式工作的根本原因;它需要知道一个像素来自哪里才能让相邻像素进行插值。
img = np.uint8(np.random.rand(8, 8)*255)
#array([[230, 45, 153, 233, 172, 153, 46, 29],
# [172, 209, 186, 30, 197, 30, 251, 200],
# [175, 253, 207, 71, 252, 60, 155, 124],
# [114, 154, 121, 153, 159, 224, 146, 61],
# [ 6, 251, 253, 123, 200, 230, 36, 85],
# [ 10, 215, 38, 5, 119, 87, 8, 249],
# [ 2, 2, 242, 119, 114, 98, 182, 219],
# [168, 91, 224, 73, 159, 55, 254, 214]], dtype=uint8)
map_y = np.array([[0, 1], [2, 3]], dtype=np.float32)
map_x = np.array([[5, 6], [7, 10]], dtype=np.float32)
mapped_img = cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR)
#array([[153, 251],
# [124, 0]], dtype=uint8)
那么这里发生了什么?在这种情况下,最容易检查矩阵:
map_y
=====
0 1
2 3
map_x
=====
5 6
7 10
因此 (0, 0) 处的目标图像与 map_y(0, 0)、map_x(0, 0) = 0, 5
处的源图像和源图像具有相同的值在第 0 行和第 5 列是 153。请注意,在目标图像中 mapped_img[0, 0] = 153
。因为我的 map 坐标是精确的整数,所以这里没有插值。我还包含了一个越界索引(map_x[1, 1] = 10
,它大于图像宽度),并注意到它刚刚被分配了值 0
越界时。
这是一个完整的代码示例,使用地面实况单应性,手动扭曲像素位置,然后使用 remap()
从转换后的点映射图像。请注意,我的单应变换 true_dst
到 src
。因此,我制作了一组我想要的点,然后通过单应性变换计算这些点在源图像中的位置。然后使用 remap()
在源图像中查找这些点,并将它们映射到目标图像中。
import numpy as np
import cv2
# read images
true_dst = cv2.imread("img1.png")
src = cv2.imread("img2.png")
# ground truth homography from true_dst to src
H = np.array([
[8.7976964e-01, 3.1245438e-01, -3.9430589e+01],
[-1.8389418e-01, 9.3847198e-01, 1.5315784e+02],
[1.9641425e-04, -1.6015275e-05, 1.0000000e+00]])
# create indices of the destination image and linearize them
h, w = true_dst.shape[:2]
indy, indx = np.indices((h, w), dtype=np.float32)
lin_homg_ind = np.array([indx.ravel(), indy.ravel(), np.ones_like(indx).ravel()])
# warp the coordinates of src to those of true_dst
map_ind = H.dot(lin_homg_ind)
map_x, map_y = map_ind[:-1]/map_ind[-1] # ensure homogeneity
map_x = map_x.reshape(h, w).astype(np.float32)
map_y = map_y.reshape(h, w).astype(np.float32)
# remap!
dst = cv2.remap(src, map_x, map_y, cv2.INTER_LINEAR)
blended = cv2.addWeighted(true_dst, 0.5, dst, 0.5, 0)
cv2.imshow('blended.png', blended)
cv2.waitKey()
来自 Visual Geometry Group at Oxford 的图像和地面真实单应性.
关于python - 如何使用 OpenCV 的重映射功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46520123/
我在网上搜索但没有找到任何合适的文章解释如何使用 javascript 使用 WCF 服务,尤其是 WebScriptEndpoint。 任何人都可以对此给出任何指导吗? 谢谢 最佳答案 这是一篇关于
我正在编写一个将运行 Linux 命令的 C 程序,例如: cat/etc/passwd | grep 列表 |剪切-c 1-5 我没有任何结果 *这里 parent 等待第一个 child (chi
所以我正在尝试处理文件上传,然后将该文件作为二进制文件存储到数据库中。在我存储它之后,我尝试在给定的 URL 上提供文件。我似乎找不到适合这里的方法。我需要使用数据库,因为我使用 Google 应用引
我正在尝试制作一个宏,将下面的公式添加到单元格中,然后将其拖到整个列中并在 H 列中复制相同的公式 我想在 F 和 H 列中输入公式的数据 Range("F1").formula = "=IF(ISE
问题类似于this one ,但我想使用 OperatorPrecedenceParser 解析带有函数应用程序的表达式在 FParsec . 这是我的 AST: type Expression =
我想通过使用 sequelize 和 node.js 将这个查询更改为代码取决于在哪里 select COUNT(gender) as genderCount from customers where
我正在使用GNU bash,版本5.0.3(1)-发行版(x86_64-pc-linux-gnu),我想知道为什么简单的赋值语句会出现语法错误: #/bin/bash var1=/tmp
这里,为什么我的代码在 IE 中不起作用。我的代码适用于所有浏览器。没有问题。但是当我在 IE 上运行我的项目时,它发现错误。 而且我的 jquery 类和 insertadjacentHTMl 也不
我正在尝试更改标签的innerHTML。我无权访问该表单,因此无法编辑 HTML。标签具有的唯一标识符是“for”属性。 这是输入和标签的结构:
我有一个页面,我可以在其中返回用户帖子,可以使用一些 jquery 代码对这些帖子进行即时评论,在发布新评论后,我在帖子下插入新评论以及删除 按钮。问题是 Delete 按钮在新插入的元素上不起作用,
我有一个大约有 20 列的“管道分隔”文件。我只想使用 sha1sum 散列第一列,它是一个数字,如帐号,并按原样返回其余列。 使用 awk 或 sed 执行此操作的最佳方法是什么? Accounti
我需要将以下内容插入到我的表中...我的用户表有五列 id、用户名、密码、名称、条目。 (我还没有提交任何东西到条目中,我稍后会使用 php 来做)但由于某种原因我不断收到这个错误:#1054 - U
所以我试图有一个输入字段,我可以在其中输入任何字符,但然后将输入的值小写,删除任何非字母数字字符,留下“。”而不是空格。 例如,如果我输入: 地球的 70% 是水,-!*#$^^ & 30% 土地 输
我正在尝试做一些我认为非常简单的事情,但出于某种原因我没有得到想要的结果?我是 javascript 的新手,但对 java 有经验,所以我相信我没有使用某种正确的规则。 这是一个获取输入值、检查选择
我想使用 angularjs 从 mysql 数据库加载数据。 这就是应用程序的工作原理;用户登录,他们的用户名存储在 cookie 中。该用户名显示在主页上 我想获取这个值并通过 angularjs
我正在使用 autoLayout,我想在 UITableViewCell 上放置一个 UIlabel,它应该始终位于单元格的右侧和右侧的中心。 这就是我想要实现的目标 所以在这里你可以看到我正在谈论的
我需要与 MySql 等效的 elasticsearch 查询。我的 sql 查询: SELECT DISTINCT t.product_id AS id FROM tbl_sup_price t
我正在实现代码以使用 JSON。 func setup() { if let flickrURL = NSURL(string: "https://api.flickr.com/
我尝试使用for循环声明变量,然后测试cols和rols是否相同。如果是,它将运行递归函数。但是,我在 javascript 中执行 do 时遇到问题。有人可以帮忙吗? 现在,在比较 col.1 和
我举了一个我正在处理的问题的简短示例。 HTML代码: 1 2 3 CSS 代码: .BB a:hover{ color: #000; } .BB > li:after {
我是一名优秀的程序员,十分优秀!