如何计算三角形和六边形的单应性?

问题描述

我正在计算不同形状的单应性,即(四边形、六边形、三角形)。此逻辑适用于四边形,但不适用于六边形或三角形。看起来我的矩阵计算逻辑有问题。你能评论一下吗?

这是我的代码


#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 的输出

enter image description here

这是三角形的输出

enter image description here

谢谢

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)