如何使用 opencv 映射相机图像来创建现场游乐场镜子?

发布于 2024-11-17 15:55:31 字数 141 浏览 2 评论 0原文

我想使用 Opencv 和 Linux 创建一个有趣的镜子效果,使用实时网络摄像头创建矮矮、高瘦的效果。我女儿喜欢这些东西,我想用相机制作一个。我不太确定这些效果所需的变换。任何帮助将不胜感激。我有很多框架正在运行,实时视频播放等,只是没有转换。

谢谢

Using Opencv and Linux I would like to create a fun-house mirror effect, short and squat, tall and thin effect using a live webcamera. My daughter loves those things and I would like to create one using a camera. I am not quite sure about the transforms necessary for these effects. Any help would be appreciated. I have much of the framework running, live video playing and such, just not the transforms.

thanx

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

冷了相思 2024-11-24 15:55:31

我认为您需要使用“径向”变换和逆径向的“针垫”。
为了破坏变换的对称性,您可以在前后拉伸图像:

  1. 假设您的图像是 300x300
    像素。
  2. 将其拉伸至 300x600 或
    600x300 使用 cvResize()
  3. 应用变换:径向、枕形或
    正弦
  4. 拉伸回 300x300

我从未在 openCV 中使用过径向或正弦变换,所以我没有附加代码。但你可以使用 cvUn Distor2() 看看是否可以。
创建带有范围为 0..100 的轨迹栏的窗口。每个轨迹条控制失真参数:

static IplImage* srcImage;
static IplImage* dstImage;

static double _camera[9];
static double _dist4Coeff[4];        // This is the transformation matrix
static int _r = 50;   // Radial transform. 50 in range 0..100
static int _tX = 50;  // Tangetial coef in X directio
static int _tY = 50;  // Tangetial coef in Y directio
static int allRange = 50;

// Open windows
cvNamedWindow(winName, 1);

// Add track bars.
cvShowImage(winName, srcImage );
cvCreateTrackbar("Radial", winName, &_r         , 2*allRange, callBackFun);
cvCreateTrackbar("Tang X", winName, &_tX        , 2*allRange, callBackFun);
cvCreateTrackbar("Tang Y", winName, &_tY        , 2*allRange, callBackFun);
callBackFun(0);

// The distortion call back
void callBackFun(int arg){
 CvMat intrCamParamsMat = cvMat( 3, 3, CV_64F, _camera );
 CvMat dist4Coeff       = cvMat( 1, 4, CV_64F, _dist4Coeff );

 // Build distortion coefficients matrix.
 dist4Coeff.data.db[0] = (_r-allRange*1.0)/allRange*1.0;
 dist4Coeff.data.db[1] = (_r-allRange*1.0)/allRange*1.0;
 dist4Coeff.data.db[2] = (_tY-allRange*1.0)/allRange*1.0;
 dist4Coeff.data.db[3] = (_tX-allRange*1.0)/allRange*1.0;

 // Build intrinsic camera parameters matrix.
 intrCamParamsMat.data.db[0] = 587.1769751432448200/2.0;
 intrCamParamsMat.data.db[1] = 0.;
 intrCamParamsMat.data.db[2] = 319.5000000000000000/2.0+0;
 intrCamParamsMat.data.db[3] = 0.;
 intrCamParamsMat.data.db[4] = 591.3189722549362800/2.0;
 intrCamParamsMat.data.db[5] = 239.5000000000000000/2.0+0;
 intrCamParamsMat.data.db[6] = 0.;
 intrCamParamsMat.data.db[7] = 0.;
 intrCamParamsMat.data.db[8] = 1.;

 // Apply transformation
 cvUndistort2( srcImage, dstImage, &intrCamParamsMat, &dist4Coeff );
 cvShowImage( winName, dstImage );
}

I think that you need to use 'radial' transforms and 'pin cushion' which is inverse radial.
In order to braker the symmetry of the transforms you can strech the image before and after:

  1. Suppose your image is 300x300
    pixels.
  2. Strech it to 300x600 or
    600x300 using cvResize()
  3. Apply transform: radial, pincushion or
    sinusoidal
  4. Strech back to 300x300

I never used radial or sinusoidal transforms in openCV so I dont have a piece of code to attach. But you can use cvUndistort2() and see if it is OK.
Create window with trackbars with range 0..100. Each trackbar controls parameter of distortion:

static IplImage* srcImage;
static IplImage* dstImage;

static double _camera[9];
static double _dist4Coeff[4];        // This is the transformation matrix
static int _r = 50;   // Radial transform. 50 in range 0..100
static int _tX = 50;  // Tangetial coef in X directio
static int _tY = 50;  // Tangetial coef in Y directio
static int allRange = 50;

// Open windows
cvNamedWindow(winName, 1);

// Add track bars.
cvShowImage(winName, srcImage );
cvCreateTrackbar("Radial", winName, &_r         , 2*allRange, callBackFun);
cvCreateTrackbar("Tang X", winName, &_tX        , 2*allRange, callBackFun);
cvCreateTrackbar("Tang Y", winName, &_tY        , 2*allRange, callBackFun);
callBackFun(0);

// The distortion call back
void callBackFun(int arg){
 CvMat intrCamParamsMat = cvMat( 3, 3, CV_64F, _camera );
 CvMat dist4Coeff       = cvMat( 1, 4, CV_64F, _dist4Coeff );

 // Build distortion coefficients matrix.
 dist4Coeff.data.db[0] = (_r-allRange*1.0)/allRange*1.0;
 dist4Coeff.data.db[1] = (_r-allRange*1.0)/allRange*1.0;
 dist4Coeff.data.db[2] = (_tY-allRange*1.0)/allRange*1.0;
 dist4Coeff.data.db[3] = (_tX-allRange*1.0)/allRange*1.0;

 // Build intrinsic camera parameters matrix.
 intrCamParamsMat.data.db[0] = 587.1769751432448200/2.0;
 intrCamParamsMat.data.db[1] = 0.;
 intrCamParamsMat.data.db[2] = 319.5000000000000000/2.0+0;
 intrCamParamsMat.data.db[3] = 0.;
 intrCamParamsMat.data.db[4] = 591.3189722549362800/2.0;
 intrCamParamsMat.data.db[5] = 239.5000000000000000/2.0+0;
 intrCamParamsMat.data.db[6] = 0.;
 intrCamParamsMat.data.db[7] = 0.;
 intrCamParamsMat.data.db[8] = 1.;

 // Apply transformation
 cvUndistort2( srcImage, dstImage, &intrCamParamsMat, &dist4Coeff );
 cvShowImage( winName, dstImage );
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文