热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

给一张图片做鱼眼(fisheye)特效,求算法,求算法!!!

如题,哪位大大指点一下。。。这个没算法怎么写程序啊!!!急!!!在线等!!!
如题,哪位大大指点一下。。。
    这个没算法怎么写程序啊 !!!
            急!!!   在线等!!!

18 个解决方案

#1


帖子怎么沉了。。。高手们伸伸手。。拉小弟一把吧。。。

#2


该回复于2011-03-29 09:34:10被版主删除

#3


╮(╯▽╰)╭。。。。悲剧中。。。就没有高手不吝赐教么???

#4


http://www.pudn.com/downloads128/sourcecode/graph/detail547468.html
现成 鱼眼特效类 

#5


补充一下
http://www.quietlyscheming.com/blog/components/fisheye-component/
有Fisheye.zip下载

#6


to icerainfc522
非常感谢,
    不过第一个网址进去我下载不了。
               第二个网址进去下载的代码应该是用脚本写的吧。。我是新手。不是很懂
                           我想学习一下语言实现的算法。或者C/C++写的代码!

#7


http://www.colorhook.com/blog/?tag=fisheye

在一个圆形的“鱼眼”区域内,越靠近圆心,让像素偏移得越厉害。使用DisplacementMapFilter实现鱼眼特效很重要的一点就是创建一个辅助圆,这个圆的区域就是鱼眼区域,而圆的像素的颜色值将会起到重要作用。在滤镜渲染的时候,这些颜色值参与计算,并根据计算结果改变原有位图的像素位置,算法公式如下:


dstPixel[x, y] = srcPixel[x + ((componentX(x, y) - 128) * scaleX) / 256,
              y + ((componentY(x, y) - 128) *scaleY) / 256)];

#8


package {
    import flash.events.*;
    import flash.display.*;
    import flash.filters.DisplacementMapFilter;
    import flash.filters.DisplacementMapFilterMode;
    import flash.geom.Point;
 
    [SWF(backgroundColor='0xFFFFFF', width = '576', height = '384', frameRate = '60')]
    public class FishEye2 extends Sprite {
 
          [Embed(source = "../library/bg.png")]
          private var ImageClass:Class;
 
          private var dmFilter:DisplacementMapFilter;
          private var canvas:Bitmap;
          private var origin:BitmapData;
          private var circle:BitmapData;
          private var circleBitmap:Bitmap;
 
          private const RADIUS:int=100;
          private const INTENSITY:Number = 1;
 
          public function FishEye2() {
              init();
              addEventListener(Event.ENTER_FRAME, paint);
          }
 
          private function init():void {
              stage.scaleMode = 'noScale';
              canvas = new ImageClass();
              origin = new BitmapData( this.canvas.width, this.canvas.height);
              circle = createCircle(RADIUS);
              circleBitmap = new Bitmap(circle);
              addChild(new Bitmap(origin));
              paint();
          }
 
          private function createCircle(radius:Number):BitmapData
          {
              var diameter:Number = radius * 2;
              var circle:BitmapData = new BitmapData(diameter, diameter, false, 0xFF008080);
              for (var cy:int = 0; cy < diameter; cy++) 
              {
                  var newY:int = cy - radius;
                  for (var cx:int = 0; cx < diameter; cx++) 
                  {
                      var newX:int=cx - radius;
                      var distance:Number = Math.sqrt(newX * newX + newY * newY);
                      if (distance < radius)
                      {
                          var base:Number = Math.sin(Math.PI / 2 * distance / radius);
                          var t:Number = Math.pow(base, INTENSITY);
                          var dx:Number = newX * (t - 1) / diameter;
                          var dy:Number = newY * (t - 1) / diameter;
                          var blue:uint = 0x80 + dx * 0xFF;
                          var green:uint = 0x80 + dy * 0xFF;
                          circle.setPixel(cx, cy, green << 8 |  blue);
                      }
                  }  
              }
              return circle;
          }
          private function paint( event:Event = null):void {
              origin.lock();
              origin.draw(this.canvas);
              dmFilter = new DisplacementMapFilter(circle, 
                      new Point(stage.mouseX - RADIUS, stage.mouseY - RADIUS),
                      BitmapDataChannel.BLUE, BitmapDataChannel.GREEN, RADIUS * 2, RADIUS * 2,
                      DisplacementMapFilterMode.CLAMP);
                  origin.applyFilter(origin, origin.rect, new Point, dmFilter );
                  origin.unlock();
              }
          }
}

#9


to icerainfc522

  算法我还是不很清楚。。因为我现在要用纯C来写。。你给的代码很多地方都调用了库的函数。。感觉不是很懂!!!
    关于圆的概念多少理解了一些。。但是这里用到了滤镜。我用C怎么写呢?
            现在我会的就是创建一个圆。也可以获取图片每一点像素的RGB值,但是如何把两者结合起来。做出图片效果还是不会。。
      我是菜鸟。还希望你可以讲解讲解!!!
            不胜感激!

#10


1.通过UI或其它方式确定畸变程度。最简单的情况下,应该是一段弧线 arcA。
2.在结果空间中遍历所有点,计算当前点距离图像中心点的距离,计算这个距离上的 arcA 的对应点的弦弧比 dubA。
3.用 dubA 来乘以当前点座标,得到一个浮点数坐标。
4.使用这个浮点数坐标来对源图进行插值运算。得到的结果放到结果空间

#11


to zhoujk,
非常感谢你的帮助。我有几点疑问。希望你可以解答。
           1.arcA的角度应该设置成多少。
           2.在第四步中。对原图进行插值运算是如何操作的。
                                  求指导!

#12


该回复于2011-03-30 15:33:21被版主删除

#13


 
icerainfc522
给的公式就可以作为调整参考依据,至于背后的数学,就要zhoujk说的那些了。

你的问题可能是在编程经验上,先读出所有点的数组,再去修改,覆盖回去,这些具体落地步骤上。

#14


插值运算,这些数学的玩意儿,我还是建议用Matlab来做。

#15


引用 11 楼 ezhourenwd 的回复:
to zhoujk,
非常感谢你的帮助。我有几点疑问。希望你可以解答。
  1.arcA的角度应该设置成多少。
  2.在第四步中。对原图进行插值运算是如何操作的。
  求指导!

1.这个角度可以由用户来确定,角度越大,则需要畸变的程度越大,参数范围为0-180,如果设置成0,则原图不需要变化,直接输出即可。
2.自己去看一下插值运算的代码,如果找不到,到我的资源去下载一个图像旋转的算法。原理都是相通的

#16


引用 15 楼 zhoujk 的回复:
引用 11 楼 ezhourenwd 的回复:
to zhoujk,
非常感谢你的帮助。我有几点疑问。希望你可以解答。
1.arcA的角度应该设置成多少。
2.在第四步中。对原图进行插值运算是如何操作的。
求指导!

1.这个角度可以由用户来确定,角度越大,则需要畸变的程度越大,参数范围为0-180,如果设置成0,则原图不需要变化,直接输出即可。
2.自己去看一下插值运算的代码,如……

我很纠结。还是不懂。。可以说的详细点么???操作起来感觉难度好大!

#17


不急,这个东东要静下心来慢慢学,你要想办法自己去掌握,如果你有具体的问题,可以提出来大家帮你想办法,如果连问题都问不到点子上,没有几个人能够帮你的。代码里开始就有大致的伪代码和思路,你先慢慢看吧

#18


C#原链接:http://www.codeproject.com/Articles/19712/Mapping-Images-on-Spherical-Surfaces-Using-C
//java代码:不知道为什么改成java的精度降低了,水平有限啊
double phi0 = 0.0;
double phi1 = Math.PI;
double theta0 = 0.0;
double theta1 = 2.0*Math.PI;
double x0,y0,z0;

//计算经纬度
public static double MapCoordinate(double i1, double i2, double w1,double w2, double p){
return ((p - i1) / (i2 - i1)) * (w2 - w1) + w1;
}

public void draw(int radius,Graphics g){ //半径和Graphics上下文
for (int i = 0; i < w; i++) //图像宽度
{
for (int j = 0; j < h; j++) //图像高度
{
// map the angles from image coordinates
double theta = MapCoordinate(0.0, w - 1,theta1, theta0, i);//经度
double phi = MapCoordinate( 0.0, h - 1,phi0, phi1, j);//纬度

// find the cartesian coordinates //经纬度映射到大圆平面的座标
x0 = radius * Math.sin(phi) * Math.cos(theta);
y0 = radius * Math.sin(phi) * Math.sin(theta);
z0 = radius * Math.cos(phi);

// apply rotation around X and Y axis to reposition the sphere
RotX(1.5, y0, z0);
RotY(-2.5, x0, z0);
// plot only positive points
if (z0 > 0){
g.setColor(new Color(pix[i+j*w]));//pix[w*h]为图像的像素数组
int ix = (int)x0 + 150; //java可以用BufferedImage 对象的
int iy = (int)y0 + 150; //getRGB(0, 0,w , h, pix, 0, w)方法获得
g.fillOval(ix,iy,5,5);//没有找到setPoint函数用画圆代替了.
}
}
}
}

public void RotX(double angle, double y, double z)//旋转
{
double y1 = y * Math.cos(angle) - z * Math.sin(angle);
double z1 = y * Math.sin(angle) + z * Math.cos(angle);
y0 = y1;
z0 = z1;
}
public void RotY(double angle, double x, double z)
{
double x1 = x * Math.cos(angle) - z * Math.sin(angle);
double z1 = x * Math.sin(angle) + z * Math.cos(angle);
x0 = x1;
z0 = z1;
}
public void RotZ(double angle, double x, double y)
{
double x1 = x * Math.cos(angle) - y * Math.sin(angle);
double y1 = x * Math.sin(angle) + y * Math.cos(angle);
x0 = x1;
y0 = y1;
}



推荐阅读
  • 本文探讨了C语言中指针的应用与价值,指针在C语言中具有灵活性和可变性,通过指针可以操作系统内存和控制外部I/O端口。文章介绍了指针变量和指针的指向变量的含义和用法,以及判断变量数据类型和指向变量或成员变量的类型的方法。还讨论了指针访问数组元素和下标法数组元素的等价关系,以及指针作为函数参数可以改变主调函数变量的值的特点。此外,文章还提到了指针在动态存储分配、链表创建和相关操作中的应用,以及类成员指针与外部变量的区分方法。通过本文的阐述,读者可以更好地理解和应用C语言中的指针。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 本文介绍了如何将CIM_DateTime解析为.Net DateTime,并分享了解析过程中可能遇到的问题和解决方法。通过使用DateTime.ParseExact方法和适当的格式字符串,可以成功解析CIM_DateTime字符串。同时还提供了关于WMI和字符串格式的相关信息。 ... [详细]
  • 本文介绍了C#中数据集DataSet对象的使用及相关方法详解,包括DataSet对象的概述、与数据关系对象的互联、Rows集合和Columns集合的组成,以及DataSet对象常用的方法之一——Merge方法的使用。通过本文的阅读,读者可以了解到DataSet对象在C#中的重要性和使用方法。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • 本文介绍了P1651题目的描述和要求,以及计算能搭建的塔的最大高度的方法。通过动态规划和状压技术,将问题转化为求解差值的问题,并定义了相应的状态。最终得出了计算最大高度的解法。 ... [详细]
  • C++字符字符串处理及字符集编码方案
    本文介绍了C++中字符字符串处理的问题,并详细解释了字符集编码方案,包括UNICODE、Windows apps采用的UTF-16编码、ASCII、SBCS和DBCS编码方案。同时说明了ANSI C标准和Windows中的字符/字符串数据类型实现。文章还提到了在编译时需要定义UNICODE宏以支持unicode编码,否则将使用windows code page编译。最后,给出了相关的头文件和数据类型定义。 ... [详细]
  • C# WPF自定义按钮的方法
    本文介绍了在C# WPF中实现自定义按钮的方法,包括使用图片作为按钮背景、自定义鼠标进入效果、自定义按压效果和自定义禁用效果。通过创建CustomButton.cs类和ButtonStyles.xaml资源文件,设计按钮的Style并添加所需的依赖属性,可以实现自定义按钮的效果。示例代码在ButtonStyles.xaml中给出。 ... [详细]
  • 本文总结了在开发中使用gulp时的一些技巧,包括如何使用gulp.dest自动创建目录、如何使用gulp.src复制具名路径的文件以及保留文件夹路径的方法等。同时介绍了使用base选项和通配符来保留文件夹路径的技巧,并提到了解决带文件夹的复制问题的方法,即使用gulp-flatten插件。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
author-avatar
博仔Mmi
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有