热门标签 | 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;
}



推荐阅读
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社区 版权所有