- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
最近,我一直在尝试通过从 4 个检测到的 4 个真实 2D 点生成单应性 3x3 矩阵来完成我的项目的一个阶段。我已经尝试了几种不同的算法和几种不同的 SVD 实现,但仍然无法获得好的结果。
我使用了 Openframework's homography implementation(IIRC 从 opencv 中获取)并接近……但仍然没有正确的结果。我很确定所有的矩阵用法都是正确的,但让我搞砸了某个地方(甚至可能是最终的转换??)
这是我尝试匹配的点的图像,左边是 src(matches),右边是 dst (truth)。 (如果需要,我可以获得坐标,但图像大小约为 640x1000)。最右边(白色)是转换到 dst/truth 的匹配项,以及由测试代码中使用的相同单应性扭曲的图像。
注意:忽略 opencl 类型,这些都是正确使用的(为了简洁起见,这里只是删减)。 std::Debug 只是一个 ostream。这是一个 16 float 数组,但我只使用前 9 个
void gaussian_elimination(float *input, int n)
{
// ported to c from pseudocode in
// http://en.wikipedia.org/wiki/Gaussian_elimination
float * A = input;
int i = 0;
int j = 0;
int m = n-1;
while (i < m && j < n){
// Find pivot in column j, starting in row i:
int maxi = i;
for(int k = i+1; k<m; k++){
if(fabs(A[k*n+j]) > fabs(A[maxi*n+j])){
maxi = k;
}
}
if (A[maxi*n+j] != 0){
//swap rows i and maxi, but do not change the value of i
if(i!=maxi)
for(int k=0;k<n;k++){
float aux = A[i*n+k];
A[i*n+k]=A[maxi*n+k];
A[maxi*n+k]=aux;
}
//Now A[i,j] will contain the old value of A[maxi,j].
//divide each entry in row i by A[i,j]
float A_ij=A[i*n+j];
for(int k=0;k<n;k++){
A[i*n+k]/=A_ij;
}
//Now A[i,j] will have the value 1.
for(int u = i+1; u< m; u++){
//subtract A[u,j] * row i from row u
float A_uj = A[u*n+j];
for(int k=0;k<n;k++){
A[u*n+k]-=A_uj*A[i*n+k];
}
//Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
}
i++;
}
j++;
}
//back substitution
for(int i=m-2;i>=0;i--){
for(int j=i+1;j<n-1;j++){
A[i*n+m]-=A[i*n+j]*A[j*n+m];
//A[i*n+j]=0;
}
}
}
cl_float16 of_findHomography(cl_float2 src[4], cl_float2 dst[4])
{
// create the equation system to be solved
//
// from: Multiple View Geometry in Computer Vision 2ed
// Hartley R. and Zisserman A.
//
// x' = xH
// where H is the homography: a 3 by 3 matrix
// that transformed to inhomogeneous coordinates for each point
// gives the following equations for each point:
//
// x' * (h31*x + h32*y + h33) = h11*x + h12*y + h13
// y' * (h31*x + h32*y + h33) = h21*x + h22*y + h23
//
// as the homography is scale independent we can let h33 be 1 (indeed any of the terms)
// so for 4 points we have 8 equations for 8 terms to solve: h11 - h32
// after ordering the terms it gives the following matrix
// that can be solved with gaussian elimination:
float P[8][9]={
{-src[0][0], -src[0][1], -1, 0, 0, 0, src[0][0]*dst[0][0], src[0][1]*dst[0][0], -dst[0][0] }, // h11
{ 0, 0, 0, -src[0][0], -src[0][1], -1, src[0][0]*dst[0][1], src[0][1]*dst[0][1], -dst[0][1] }, // h12
{-src[1][0], -src[1][1], -1, 0, 0, 0, src[1][0]*dst[1][0], src[1][1]*dst[1][0], -dst[1][0] }, // h13
{ 0, 0, 0, -src[1][0], -src[1][1], -1, src[1][0]*dst[1][1], src[1][1]*dst[1][1], -dst[1][1] }, // h21
{-src[2][0], -src[2][1], -1, 0, 0, 0, src[2][0]*dst[2][0], src[2][1]*dst[2][0], -dst[2][0] }, // h22
{ 0, 0, 0, -src[2][0], -src[2][1], -1, src[2][0]*dst[2][1], src[2][1]*dst[2][1], -dst[2][1] }, // h23
{-src[3][0], -src[3][1], -1, 0, 0, 0, src[3][0]*dst[3][0], src[3][1]*dst[3][0], -dst[3][0] }, // h31
{ 0, 0, 0, -src[3][0], -src[3][1], -1, src[3][0]*dst[3][1], src[3][1]*dst[3][1], -dst[3][1] }, // h32
};
gaussian_elimination(&P[0][0],9);
/*
// gaussian elimination gives the results of the equation system
// in the last column of the original matrix.
// opengl needs the transposed 4x4 matrix:
float aux_H[]=
{
P[0][8],P[3][8],0,P[6][8], // h11 h21 0 h31
P[1][8],P[4][8],0,P[7][8], // h12 h22 0 h32
0 , 0,0,0, // 0 0 0 0
P[2][8],P[5][8],0,1 // h13 h23 0 h33
};
*/
// non transposed 3x3
cl_float16 Result;
Result.s[0] = P[0][8];
Result.s[1] = P[1][8];
Result.s[2] = P[2][8];
Result.s[3] = P[3][8];
Result.s[4] = P[4][8];
Result.s[5] = P[5][8];
Result.s[6] = P[6][8];
Result.s[7] = P[7][8];
Result.s[8] = 1;
//Result.s[8] = P[8][8];
// test
for ( int i=0; i<4; i++ )
{
auto H = Result.s;
float x = H[0]*src[i][0] + H[1]*src[i][1] + H[2];
float y = H[3]*src[i][0] + H[4]*src[i][1] + H[5];
float z = H[6]*src[i][0] + H[7]*src[i][1] + H[8];
x /= z;
y /= z;
float diffx = dst[i][0] - x;
float diffy = dst[i][1] - y;
std::Debug << "err src->dst #" << i << ": " << diffx << "," << diffy << std::endl;
}
for ( int i=0; i<4; i++ )
{
auto H = Result.s;
float x = H[0]*dst[i][0] + H[1]*dst[i][1] + H[2];
float y = H[3]*dst[i][0] + H[4]*dst[i][1] + H[5];
float z = H[6]*dst[i][0] + H[7]*dst[i][1] + H[8];
x /= z;
y /= z;
float diffx = src[i][0] - x;
float diffy = src[i][1] - y;
std::Debug << "err src->dst #" << i << ": " << diffx << "," << diffy << std::endl;
}
return Result;
}
图像的输出是
err src->dst #0: 0.00195,0.0132
err src->dst #1: 0,6.1e-05
err src->dst #2: -0.00161,-8.96e-05
err src->dst #3: 1.91e-06,0.000122
err dst->src #0: 2.31e+03,551
err dst->src #1: -3.34e+03,-4.23e+03
err dst->src #2: 1.07e+03,1.25e+04
err dst->src #3: 456,771
我的矩阵转换代码有什么明显的错误吗?或者我是否以错误的行/列顺序将 SVD 结果放入矩阵?也许整个算法不是我所需要的? (当然它应该生成一个非常简单、小的旋转矩阵?)
最佳答案
我一如既往的坏。这个实现似乎完美地工作(到目前为止)并且非常适合 GPU 并行化。
我输入了错误的坐标。呈现的点与输入算法的点不同(新代码与旧代码)。
警告 future 总是先生成数据,然后渲染,而不是使用[曾经]相同的代码渲染和生成。
关于algorithm - 单应性算法未按预期工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32958020/
我找到了 this excellent question and answer它以 x/y(加上 center x/y 和 degrees/radians)开始并计算旋转- 到 x'/y'。这个计算很
全部: 我已经创建了一个 Windows 窗体和一个按钮。在另一个线程中,我试图更改按钮的文本,但它崩溃了;但是如果我尝试更改按钮的颜色,它肯定会成功。我认为如果您更改任何 Windows 窗体控件属
本网站的另一个问题已证实,C 中没有缩写的字面后缀,并且可以执行以下操作: short Number = (short)1; 但是转换它和不这样做有什么区别: short Number = 1; 您使
我有下表: ID (int) EMAIL (varchar(50)) CAMPAIGNID (int) isSubscribe (bit) isActionByUser (bit) 此表存储了用户对事
也就是说,无需触发Javascript事件即可改变的属性,如何保留我手动选中或取消选中的复选框的状态,然后复制到另一个地方? 运行下面的代码片段并选中或取消选中其中的一些,然后点击“复制”: $('#
我在网上找到的所有关于递增指针导致段错误的示例都涉及指针的取消引用 - 如果我只想递增它(例如在 for 循环的末尾)并且我不在乎它是否最终进入无效内存,因为我不会再使用它。例如,在这个程序中,每次迭
我有一个 Spring MVC REST 服务,它使用 XStream 将消息与 XML 相互转换。 有什么方法可以将请求和响应中的 xml(即正文)打印到普通的 log4j 记录器? 在 Contr
做我的任务有一个很大的挑战,那就是做相互依赖的任务我在这张照片中说的。假设我们有两个任务 A 和 B,执行子任务 A1、A2 和 B1、B2,假设任务 B 依赖于 A。 要理想地执行任务 B,您应该执
通过阅读该网站上的几个答案,我了解到 CoInitialize(Ex) should be called by the creator of a thread 。然后,在该线程中运行的任何代码都可以使
这个问题已经困扰我一段时间了。我以前从未真正使用过 ListViews,也没有使用过 FirebaseListAdapters。我想做的就是通过显示 id 和用户位置来启动列表的基础,但由于某种原因,
我很难解释这两个(看似简单)句子的含义: “受检异常由编译器在编译时检查” 这是什么意思?编译器检查是否捕获了所有已检查的异常(在代码中抛出)? “未经检查的异常在运行时检查,而不是编译时” 这句话中
我有一个包含排除子字符串的文本文件,我想迭代该文件以检查并返回不带排除子字符串的输入项。 这里我使用 python 2.4,因此下面的代码可以实现此目的,因为 with open 和 any 不起作用
Spring 的缓存框架能否了解请求上下文的身份验证状态,或者更容易推出自己的缓存解决方案? 最佳答案 尽管我发现这个用例 super 奇怪,但您可以为几乎任何与 SpEL 配合使用的内容设置缓存条件
我有以下函数模板: template HeldAs* duplicate(MostDerived *original, HeldAs *held) { // error checking omi
如果我的应用程序具有设备管理员/设备所有者权限(未获得 root 权限),我如何才能从我的应用程序中终止(或阻止启动)另一个应用程序? 最佳答案 设备所有者可以阻止应用程序: DevicePolicy
非常简单的问题,但我似乎无法让它正常工作。 我有一个组件,其中有一些 XSLT(用于导航)。它通过 XSLT TBB 使用 XSLT Mediator 发布。 发布后
我正在将一个对象拖动到一个可拖放的对象内,该对象也是可拖动的。放置对象后,它会嵌套在可放置对象内。同样,如果我将对象拖到可放置的外部,它就不再嵌套。 但是,如果我经常拖入和拖出可放置对象,则可拖动对象
我正在尝试为按钮和弹出窗口等多个指令实现“取消选择”功能。也就是说,我希望当用户单击不属于指令模板一部分的元素时触发我的函数。目前,我正在使用以下 JQuery 代码: $('body').click
我从 this question 得到了下面的代码,该脚本用于在 Google tasks 上更改 iframe[src="about:blank"] 内的 CSS使用 Chrome 扩展 Tempe
我有一些 @Mock 对象,但没有指定在该对象上调用方法的返回值。该方法返回 int (不是 Integer)。我很惊讶地发现 Mockito 没有抛出 NPE 并返回 0。这是预期的行为吗? 例如:
我是一名优秀的程序员,十分优秀!