问题描述
我正在计算不同形状的单应性,即(四边形、六边形、三角形)。此逻辑适用于四边形,但不适用于六边形或三角形。看起来我的矩阵计算逻辑有问题。你能评论一下吗?
这是我的代码:
#import <Foundation/Foundation.h>
#import "EigenWrapper.h"
#import <Eigen/Dense>
@implementation EigenWrapper
constexpr double W = 800;
constexpr double H = 800;
constexpr size_t NQUAD = 4;
constexpr size_t NTRI = 3;
constexpr size_t NHEX = 6;
Eigen::Matrix3d Homography;
//QUAD
Eigen::Matrix<double,2,NQUAD> DSTQUAD;
Eigen::Matrix<double,2*NQUAD,9> AQUAD;
Eigen::Matrix<double,NQUAD> SRCQUAD;
//Triangle
Eigen::Matrix<double,NTRI> DSTTRI;
Eigen::Matrix<double,2*NTRI,9> ATRI;
Eigen::Matrix<double,NTRI> SRCTRI;
//HEXA
Eigen::Matrix<double,NHEX> DSTHEX;
Eigen::Matrix<double,2*NHEX,9> AHEX;
Eigen::Matrix<double,NHEX> SRCHEX;
- (instancetype)initEigenWrapper:(size_t)sides {
return self;
}
+ (double*)eigenGetHomogprahyMatrix :(double)topLeftX : (double)topLeftY :(double)topRightX :(double)topRightY :(double)bottomLeftX :(double)bottomLeftY :(double)bottomrightX :(double)bottomrightY {
SRCQUAD <<
0,W,H,H;
DSTQUAD <<
topLeftX,topRightX,bottomLeftX,bottomrightX,topLeftY,topRightY,bottomLeftY,bottomrightY;
AQUAD.setZero();
for (size_t i = 0; i < NQUAD; i++) {
const double x_ = DSTQUAD(0,i),y_ = DSTQUAD(1,i);
const double x = SRCQUAD(0,y = SRCQUAD(1,i);
AQUAD(2*i,0) = AQUAD(2*i+1,3) = x_;
AQUAD(2*i,1) = AQUAD(2*i+1,4) = y_;
AQUAD(2*i,2) = AQUAD(2*i+1,5) = 1;
AQUAD(2*i,6) = -x*x_;
AQUAD(2*i,7) = -x*y_;
AQUAD(2*i,8) = -x;
AQUAD(2*i+1,6) = -y*x_;
AQUAD(2*i+1,7) = -y*y_;
AQUAD(2*i+1,8) = -y;
}
Eigen::JacobiSVD<Eigen::Matrix<double,9>> svd(AQUAD,Eigen::ComputeFullV);
Eigen::Matrix<double,9,1> h = svd.matrixV().col(8);
Homography <<
h(0),h(1),h(2),h(3),h(4),h(5),h(6),h(7),h(8);
for (int i = 0; i < 10; i++) {
printf("\n: %f",Homography.array().data()[i]);
}
return Homography.array().data();
}
+ (double *)eigenGetHomogprahyTriangle :(double)middleX :(double)middleY :(double)bottomLeftX :(double)bottomLeftY :(double)bottomrightX :(double)bottomrightY {
SRCTRI <<
0,W/2,0;
DSTTRI <<
bottomLeftX,middleX,bottomrightY,middleY;
ATRI.setZero();
for (size_t i = 0; i < NTRI; i++) {
const double x_ = DSTTRI(0,y_ = DSTTRI(1,i);
const double x = SRCTRI(0,y = SRCTRI(1,i);
ATRI(2*i,0) = ATRI(2*i+1,3) = x_;
ATRI(2*i,1) = ATRI(2*i+1,4) = y_;
ATRI(2*i,2) = ATRI(2*i+1,5) = 1;
ATRI(2*i,6) = -x*x_;
ATRI(2*i,7) = -x*y_;
ATRI(2*i,8) = -x;
ATRI(2*i+1,6) = -y*x_;
ATRI(2*i+1,7) = -y*y_;
ATRI(2*i+1,9>> svd(ATRI,Homography.array().data()[i]);
}
return Homography.array().data();
}
+ (double *)eigenGetHomogprahyMatrixHexa:(double)topLeftX :(double)topLeftY :(double)topRightX :(double)topRightY :(double)middleLeftX :(double)middleLeftY :(double)middleRightX :(double)middleRightY :(double)bottomLeftX :(double)bottomLeftY :(double)bottomrightX :(double)bottomrightY {
SRCHEX <<
0,H/2,H/2;
DSTHEX <<
topLeftX,middleLeftX,middleRightX,middleLeftY,middleRightY;
AHEX.setZero();
for (size_t i = 0; i < NHEX; i++) {
const double x_ = DSTHEX(0,y_ = DSTHEX(1,i);
const double x = SRCHEX(0,y = SRCHEX(1,i);
AHEX(2*i,0) = AHEX(2*i+1,3) = x_;
AHEX(2*i,1) = AHEX(2*i+1,4) = y_;
AHEX(2*i,2) = AHEX(2*i+1,5) = 1;
AHEX(2*i,6) = -x*x_;
AHEX(2*i,7) = -x*y_;
AHEX(2*i,8) = -x;
AHEX(2*i+1,6) = -y*x_;
AHEX(2*i+1,7) = -y*y_;
AHEX(2*i+1,9>> svd(AHEX,Homography.array().data()[i]);
}
return Homography.array().data();
}
@end
计算同构后,我只是用 OpenCV 包装纹理图像。我还想将输出图像的背景从黑色更改为透明。
cv::Mat sourceImage = imread("texture.png",cv::IMREAD_COLOR);
for (int i=0; i<9; i++) {
printf(":- %.7f",homographyMatrix[i]);
}
cv::Matx33d H(homographyMatrix[0],homographyMatrix[3],homographyMatrix[6],homographyMatrix[1],homographyMatrix[4],homographyMatrix[7],homographyMatrix[2],homographyMatrix[5],homographyMatrix[8]);
cv::Mat destimage;
cv::warpPerspective(sourceImage,destimage,cv::Size(width,height),cv::INTER_LINEAR | cv::WARP_INVERSE_MAP);
UIImage * deImage = MatToUIImage(destimage);
这是 Hexagon 的输出
这是三角形的输出
谢谢
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)