perspective transform透视矩阵快速求法+矩形矫正
算了半天一直在思考如何快速把矩阵算出来,网上基本都是在说边长为1的正方形的变换方式=。= 不怎么用得上…… 公式推导推半天,计算还麻烦。。。。
++++++++++++++++++++++++++++++
对于透视变换:

其中我们在使用的时候最重要的是算出系数…………………… 这里我们按照i=1计算
找了半天找到了这一篇论文:http://www.ixueshu.com/document/027c165d22e18077318947a18e7f9386.html
里面提到我们可以将公式
改写成
的模式。
那么根据矩形矫正前后的8个顶点可以得到公式:

那么只要计算中间8x8矩阵的逆,乘上变换后的uv矩阵,就可以求出所有待定系数。其中点的检测需要用到hough算法,点和点之间的对应我做了个交互,不然太麻烦了。。。。
矩阵求逆代码:其中N为8
#include <iostream>
using namespace std;
#define N 8 //测试矩阵维数定义 //按第一行展开计算|A|
double getA(double arcs[N][N], int n)
{
if (n == )
{
return arcs[][];
}
double ans = ;
double temp[N][N] = { 0.0 };
int i, j, k;
for (i = ; i<n; i++)
{
for (j = ; j<n - ; j++)
{
for (k = ; k<n - ; k++)
{
temp[j][k] = arcs[j + ][(k >= i) ? k + : k]; }
}
double t = getA(temp, n - );
if (i % == )
{
ans += arcs[][i] * t;
}
else
{
ans -= arcs[][i] * t;
}
}
return ans;
} //计算每一行每一列的每个元素所对应的余子式,组成A*
void getAStart(double arcs[N][N], int n, double ans[N][N])
{
if (n == )
{
ans[][] = ;
return;
}
int i, j, k, t;
double temp[N][N];
for (i = ; i<n; i++)
{
for (j = ; j<n; j++)
{
for (k = ; k<n - ; k++)
{
for (t = ; t<n - ; t++)
{
temp[k][t] = arcs[k >= i ? k + : k][t >= j ? t + : t];
}
} ans[j][i] = getA(temp, n - ); //此处顺便进行了转置
if ((i + j) % == )
{
ans[j][i] = -ans[j][i];
}
}
}
} //得到给定矩阵src的逆矩阵保存到des中。
bool GetMatrixInverse(double src[N][N], int n, double des[N][N])
{
double flag = getA(src, n);
double t[N][N];
if ( == flag)
{
cout << "原矩阵行列式为0,无法求逆。请重新运行" << endl;
return false;//如果算出矩阵的行列式为0,则不往下进行
}
else
{
getAStart(src, n, t);
for (int i = ; i<n; i++)
{
for (int j = ; j<n; j++)
{
des[i][j] = t[i][j] / flag;
} }
} return true;
}
主函数内代码:(仅部分)
vector<pair<int, int>> P ,newPoint; //P 变换后标准A4的点 newPoint 变换前的点 计算时候计算变换后变换到变换前 //省略中间数值插入和输出图片构成 P.push_back(make_pair(, ));
P.push_back(make_pair((int)len1, ));
P.push_back(make_pair((int)len1, (int)len2));
P.push_back(make_pair(, (int)len2)); int uv[] = { newPoint[].first, newPoint[].second,
newPoint[].first, newPoint[].second,
newPoint[].first, newPoint[].second,
newPoint[].first, newPoint[].second }; double src[][] =
{ { P[].first, P[].second, , , , , -newPoint[].first*P[].first, -newPoint[].first*P[].second },
{ , , , P[].first, P[].second, , -newPoint[].second*P[].first, -newPoint[].second*P[].second }, { P[].first, P[].second, , , , , -newPoint[].first*P[].first, -newPoint[].first*P[].second },
{ , , , P[].first, P[].second, , -newPoint[].second*P[].first, -newPoint[].second*P[].second }, { P[].first, P[].second, , , , , -newPoint[].first*P[].first, -newPoint[].first*P[].second },
{ , , , P[].first, P[].second, , -newPoint[].second*P[].first, -newPoint[].second*P[].second }, { P[].first, P[].second, , , , , -newPoint[].first*P[].first, -newPoint[].first*P[].second },
{ , , , P[].first, P[].second, , -newPoint[].second*P[].first, -newPoint[].second*P[].second } }; double matrix_after[N][N]{};
bool flag = GetMatrixInverse(src, N, matrix_after);
if (false == flag) {
cout << "求不出系数" << endl;
return;
} cout << "逆矩阵:" << endl; for (int i = ; i<; i++)
{
for (int j = ; j<; j++)
{
cout << matrix_after[i][j] << " ";
//cout << *(*(matrix_after+i)+j)<<" ";
}
cout << endl;
} double xs[];
for (int i = ; i < ; i++) {
double sum = ;
for (int t = ; t < ; t++) {
sum += matrix_after[i][t] * uv[t];
}
xs[i] = sum;
}
//矩形矫正 没有用双线性插值
cimg_forXY(outputimg, x, y) {
double px = xs[] * x + xs[] * y + xs[];
double py = xs[] * x + xs[] * y + xs[];
double p = xs[] * x + xs[] * y + ; int u = px / p;
int v = py / p; outputimg(x, y, ) = paint(u, v, );
outputimg(x, y, ) = paint(u, v, );
outputimg(x, y, ) = paint(u, v, );
}
以上~
基本实验了一下:

结果:

还可以吧。。。
perspective transform透视矩阵快速求法+矩形矫正的更多相关文章
- 【CImg】简单的畸变矩形矫正
三个角点确定一个平面,畸变的平面可以看成是不同基底下同一图像的表示 ============================我是分割线============================= 1. ...
- CSS3打造3D效果——perspective transform的深度剖析
声明:此篇博文虽是自己手写,但大量资源取自 张鑫旭 的博文.想看更详细 更专业的剖析请看张鑫旭的博文. 昨天对css3的transform做了初步的分析和认识,突然看到perspective属性,调了 ...
- hdu3306 Another kind of Fibonacci【矩阵快速幂】
转载请注明出处:http://www.cnblogs.com/KirisameMarisa/p/4187670.html 题目链接:http://acm.hdu.edu.cn/showproblem. ...
- [技术]浅谈OI中矩阵快速幂的用法
前言 矩阵是高等代数学中的常见工具,也常见于统计分析等应用数学学科中,矩阵的运算是数值分析领域的重要问题. 基本介绍 (该部分为入门向,非入门选手可以跳过) 由 m行n列元素排列成的矩形阵列.矩阵里的 ...
- HDU 6185 Covering 矩阵快速幂
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6185 题意:用 1 * 2 的小长方形完全覆盖 4 * n的矩形有多少方案. 解法:小范围是一个经典题 ...
- hdu4549 M斐波那契数列 矩阵快速幂+快速幂
M斐波那契数列F[n]是一种整数数列,它的定义如下: F[0] = aF[1] = bF[n] = F[n-1] * F[n-2] ( n > 1 ) 现在给出a, b, n,你能求出F[n]的 ...
- 五校联考R1 Day1T3 平面图planar(递推 矩阵快速幂)
题目链接 我们可以把棱柱拆成有\(n\)条高的矩形,尝试递推. 在计算的过程中,第\(i\)列(\(i\neq n\))只与\(i-1\)列有关,称\(i-1\)列的上面/下面为左上/左下,第\(i\ ...
- BZOJ2476: 战场的数目(矩阵快速幂)
题意 题目链接 Sol 神仙题Orzzz 考虑两边是否有\(1\) 设\(f[i]\)表示周长为\(2i\)的方案数 第一种情况:左侧或右侧有一个1,那么把这个1删去,对应的方案数为\(f[i - 1 ...
- HDU - 6185 Covering(暴搜+递推+矩阵快速幂)
Covering Bob's school has a big playground, boys and girls always play games here after school. To p ...
随机推荐
- C++虚函数与虚表
有一定面向对象知识的朋友对继承与多态一定很熟悉,C++想实现继承的话就要使用虚函数,那么什么是虚函数,其原理是什么,下面尽量给大家分析一下C++中其运行机制: 首先,基础,什么是虚函数,什么是多态? ...
- 04 body中的相关标签
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JVM 参数类型
标准参数 -help -server -client -version -showversion -cp -classpath X参数 非标准化参数(在各个JDK版本中可能会变,但是变动比较小) -X ...
- java8 异步api、循环、日期
java8 异步api.循环.日期 转载请注明出处:https://www.cnblogs.com/funnyzpc/p/10801470.html 异步api 对于多任务耗时的业务场景,一般我们会用 ...
- 【时间工具】整理下java时间换算专题
首先总结了一下日期转换基础,最常用的两个工具类Date与calender,转换方法如下: package com.zzt.spider; import java.text.SimpleDateForm ...
- docker 获取镜像
之前提到过,Docker Hub 上有大量的高质量的镜像可以用,这里我们就说一下怎么获取这些镜像. 从 Docker 镜像仓库获取镜像的命令是 docker pull.其命令格式为: docker p ...
- "You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''zhaoqiuyu' (`NAME`,`PRICE`,`COUNT`) values('电脑',1999,1)' at lin
"You have an error in your SQL syntax; check the manual that corresponds to your MySQL server v ...
- Vue技术点整理-安装引入
Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的渐进式框架 所谓渐进式是指: 1,如果你有一个现成的web应用,你可以将vue作为该应用的一部分嵌入其中,带来更丰富的交互体验 ...
- Profibus 接线
无论是组成MPI还是RPOFIBUS-DP网络,用到的主要部件都是一样的: PROFIBUS电缆:电缆型号有多种,其中最基本的是PROFIBUS FC(Fast Connect快速连接)Standar ...
- 嵊州D3T3 light
嵊州D3T3 light 光恰似水 兄弟俩曾经 k 次受到过父母的物质激励. 一开始,兄弟俩的能力值为 1,最后,兄弟俩的能力值是 1 + (2 ^k−1)/ n . 当兄弟俩受到价值为 mi 的物质 ...