栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

如何通过openCV模拟鱼眼镜头效果?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

如何通过openCV模拟鱼眼镜头效果?

我使用opencv创建了此应用。这是您所指的效果吗?我基本上编码了维基百科“ Distortion(optics)”上显示的公式,如果需要,我可以显示代码

更新:好的,因此以下是使用opencv用c ++编写的实际代码(未记录,因此随时要求解释):该程序将输入以下参数作为输入:输入图片| | 输出图像| | 控制失真量的K(通常尝试0.001附近的值) | | 变形中心的x坐标| | 变形中心的y坐标|

因此,程序的关键是double for循环,该循环在结果图像上逐个像素迭代,并使用径向失真公式在输入图像中寻找匹配的像素(这通常是图像变形的方法-可能是直观地对付从输出到输入的反投影)。有一些细微之处与输出图像的比例有关(在此程序中,生成的图像与输入的大小相同),除非您想了解更多细节,否则我不会涉及。

    #include <cv.h>    #include <highgui.h>    #include <math.h>    #include <unistd.h>    #include <getopt.h>    #include <iostream>    void sampleImage(const IplImage* arr, float idx0, float idx1, CvScalar& res)    {      if(idx0<0 || idx1<0 || idx0>(cvGetSize(arr).height-1) || idx1>(cvGetSize(arr).width-1)){        res.val[0]=0;        res.val[1]=0;        res.val[2]=0;        res.val[3]=0;        return;      }      float idx0_fl=floor(idx0);      float idx0_cl=ceil(idx0);      float idx1_fl=floor(idx1);      float idx1_cl=ceil(idx1);      CvScalar s1=cvGet2D(arr,(int)idx0_fl,(int)idx1_fl);      CvScalar s2=cvGet2D(arr,(int)idx0_fl,(int)idx1_cl);      CvScalar s3=cvGet2D(arr,(int)idx0_cl,(int)idx1_cl);      CvScalar s4=cvGet2D(arr,(int)idx0_cl,(int)idx1_fl);      float x = idx0 - idx0_fl;      float y = idx1 - idx1_fl;      res.val[0]= s1.val[0]*(1-x)*(1-y) + s2.val[0]*(1-x)*y + s3.val[0]*x*y + s4.val[0]*x*(1-y);      res.val[1]= s1.val[1]*(1-x)*(1-y) + s2.val[1]*(1-x)*y + s3.val[1]*x*y + s4.val[1]*x*(1-y);      res.val[2]= s1.val[2]*(1-x)*(1-y) + s2.val[2]*(1-x)*y + s3.val[2]*x*y + s4.val[2]*x*(1-y);      res.val[3]= s1.val[3]*(1-x)*(1-y) + s2.val[3]*(1-x)*y + s3.val[3]*x*y + s4.val[3]*x*(1-y);    }    float xscale;    float yscale;    float xshift;    float yshift;    float getRadialX(float x,float y,float cx,float cy,float k){      x = (x*xscale+xshift);      y = (y*yscale+yshift);      float res = x+((x-cx)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));      return res;    }    float getRadialY(float x,float y,float cx,float cy,float k){      x = (x*xscale+xshift);      y = (y*yscale+yshift);      float res = y+((y-cy)*k*((x-cx)*(x-cx)+(y-cy)*(y-cy)));      return res;    }    float thresh = 1;    float calc_shift(float x1,float x2,float cx,float k){      float x3 = x1+(x2-x1)*0.5;      float res1 = x1+((x1-cx)*k*((x1-cx)*(x1-cx)));      float res3 = x3+((x3-cx)*k*((x3-cx)*(x3-cx)));      //  std::cerr<<"x1: "<<x1<<" - "<<res1<<" x3: "<<x3<<" - "<<res3<<std::endl;      if(res1>-thresh and res1 < thresh)        return x1;      if(res3<0){        return calc_shift(x3,x2,cx,k);      }      else{        return calc_shift(x1,x3,cx,k);      }    }    int main(int argc, char** argv)    {      IplImage* src = cvLoadImage( argv[1], 1 );      IplImage* dst = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);      IplImage* dst2 = cvCreateImage(cvGetSize(src),src->depth,src->nChannels);      float K=atof(argv[3]);      float centerX=atoi(argv[4]);      float centerY=atoi(argv[5]);      int width = cvGetSize(src).width;      int height = cvGetSize(src).height;      xshift = calc_shift(0,centerX-1,centerX,K);      float newcenterX = width-centerX;      float xshift_2 = calc_shift(0,newcenterX-1,newcenterX,K);      yshift = calc_shift(0,centerY-1,centerY,K);      float newcenterY = height-centerY;      float yshift_2 = calc_shift(0,newcenterY-1,newcenterY,K);      //  scale = (centerX-xshift)/centerX;      xscale = (width-xshift-xshift_2)/width;      yscale = (height-yshift-yshift_2)/height;      std::cerr<<xshift<<" "<<yshift<<" "<<xscale<<" "<<yscale<<std::endl;      std::cerr<<cvGetSize(src).height<<std::endl;      std::cerr<<cvGetSize(src).width<<std::endl;      for(int j=0;j<cvGetSize(dst).height;j++){        for(int i=0;i<cvGetSize(dst).width;i++){          CvScalar s;          float x = getRadialX((float)i,(float)j,centerX,centerY,K);          float y = getRadialY((float)i,(float)j,centerX,centerY,K);          sampleImage(src,y,x,s);          cvSet2D(dst,j,i,s);        }      }    #if 0      cvNamedWindow( "Source1", 1 );      cvShowImage( "Source1", dst);      cvWaitKey(0);    #endif      cvSaveImage(argv[2],dst,0);    #if 0      for(int j=0;j<cvGetSize(src).height;j++){        for(int i=0;i<cvGetSize(src).width;i++){          CvScalar s;          sampleImage(src,j+0.25,i+0.25,s);          cvSet2D(dst,j,i,s);        }      }      cvNamedWindow( "Source1", 1 );      cvShowImage( "Source1", src);      cvWaitKey(0);    #endif  }


转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/508271.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号