# 圖片處理程式的一些問題

http://stackoverflow.com/questions/5055625/image-w...

http://stackoverflow.com/questions/5542942/looking...

width = 圖片寬度

height = 圖片長度

r = Sqrt( (x - width/2)^2 + (height/2)^2 )

n = Bulge factor (default = 0)

Set

x' = r^n * ( x - width/2 ) + width/2

y' = r^n * (y - height/2) + height/2

int color;

for(int x = 0; x < width; x++) {

for(int y = 0; y < height; y++) {

double r = Math.pow(x-width/2, 2) + Math.pow(y-height/2, 2);

double x2 = Math.pow(r, n) * (x - width/2) + (width/2);

double y2 = Math.pow(r, n) * (y - height/2) + (height/2);

if(x2 >= 0 && y2 >= 0 && x2 <= width && y2 <= height){

color = bmp.getPixel((int)x2, (int)y2);//將原圖(x2, y2)的像素取出

pBitmap.setPixel(x, y, color);//將color放入pBitmap(x,y)

}

}

}

Update:

Tai大大：

Update 2:

r = (x - 0.5)^2 + (y - 0.5)^2

n = Bulge factor (default = 0)

Set

x' = r^n * (x - 0.5) + 0.5

y' = r^n * (y - 0.5) + 0.5

(x and y span from 0 to 1. If your dimensions span 0 to w, replace 0.5 with w/2)

Update 3:

if(x2 >= 0 && y2 >= 0 && x2 <= width && y2 <= height)

Update 4:

Update 5:

red = Math.min(255, red+(red*red2)/(255 - red2));

green = Math.min(255, green+(green*green2)/(255 - green2));

blue = Math.min(255, blue+(blue*blue2)/(255 - blue2));

out[x] = Color.rgb(red, green, blue);

(red、green、blue 對應到黑白圖 ；red2、green2 、blue2 對應到反色+高斯模糊圖 )

Update 6:

int avg=(red+green+blue)/3;

out[x] = Color.rgb(avg, avg, avg);

Update 7:

Rating
• Tai
Lv 5
7 years ago

要反過來求解

假設

center = (w/2, h/2) = (x0, y0) = p0

given p' = (x,y)

solve the unknown p

|p'-p0| = R = r^n

|p-p0| = r = R^ (1/n)

p = p0 + (p'-p0) R^(-1+1/n) <= ans

code:

double x0 = width/2.0, y0 = height/2.0;

double R = Math.pow( (x-x0)*(x-x0)+(y-y0)*(y-y0), 0.5); // |p'-p0|

double x2 = Math.pow(r, -1.0 + 1.0/n) + x0;

double y2 = Math.pow(r, -1.0 + 1.0/n) + y0;

if(x2 >= 0 && y2 >= 0 && x2 <= width && y2 <= height){

color = bmp.getPixel((int)x2, (int)y2);//將原圖(x2, y2)的像素取出

pBitmap.setPixel(x, y, color);//將color放入pBitmap(x,y)

2013-11-08 20:53:42 補充：

code 打錯了, 更正為

double x0 = width/2.0, y0 = height/2.0;

double R = Math.pow( (x-x0)*(x-x0)+(y-y0)*(y-y0), 0.5); // |p'-p0|

double x2 = (x-x0) * Math.pow(R, -1.0 + 1.0/n) + x0;

double y2 = (y-y0) * Math.pow(R, -1.0 + 1.0/n) + y0;

沒環境驗證, 祝你順利

2013-11-09 04:01:17 補充：

更正為 p'=(x,y), p is unknown

let

|p'-p0| = R

|p-p0| = r

p'-p0 = r^n (p-p0)

=> R=|p'-p0| = |r^n (p-p0)| = r^n * r = r^(n+1)

=> r = R^(1/(n+1))

=> p = (p'-p0) * R^(-n/(n+1)) + p0

code:

double x2 = (x-x0) * Math.pow(R, -n/(n+1.)) + x0;

double y2 = (y-y0) * Math.pow(R, -n/(n+1.)) + y0;

2013-11-09 04:07:04 補充：

版大的公式是將 image 長寬正規化為 1 後,

原本網格 (x,y) 會以中心 (.5, 0.5) 向外膨脹.

膨脹的是 "網格"

如果上色系統是根據新網格, 和網格上的顏色重新上色,

那會看到圖片隆起的效果

但原式中 (x2,y2) 是 (x,y) 膨脹的新位置.

將膨脹後的位置的顏色放到 (x,y), 反而給人陷下去的感覺.

所以是反過來, (x,y) 是膨脹後的網點,

找某個 (x2,y2) 能膨脹到 (x,y), 在取 (x2,y2) 的顏色給 (x,y)

2013-11-10 11:35:21 補充：

是說 (x2,y2) 在原圖範圍越來越小吧?

與這無關 f(x2 >= 0 && y2 >= 0 && x2 <= width && y2 <= height)

你說的 source code, 我也覺得很奇怪, 就是向外膨脹, 沒有越到邊界膨脹越少的特行.

但為什有這種效果 ....

2013-11-10 19:58:24 補充：

http://stackoverflow.com/questions/5055625/image-w...

中提供兩式, 第一個我仍覺得是膨脹網格

就算逆算, 也只是你說的在原圖範圍越來越小

第二個用 p = p' - nlog( d ) v.

n = 0, 沒有變形.

n 逐漸變大時,

同張圖內, d 落在 sqrt(2) >1>d>0 範圍內.

越靠近圖心扭曲越大, 到 d=1 扭曲最小 log(d)=0.

而 d>1 後是反向, 但變動不大.

用第二式符合你需求

2013-11-11 15:26:55 補充：

程式 2 是 GLSL, 算是跟 OpenGL 搭配用的 shader code.

看似 fragment shader, 也就是寫每個 pixel 的處理程式.

所以比較短 ..

2013-11-11 15:27:50 補充：

版大, 我昨晚應該有寄到你信箱喔.

意見區和輔助回答區字數限制太誇張, 根本寫不下去

2013-11-12 05:00:20 補充：

適合版大的第二式, 以 opencv

http://stackoverflow.com/questions/5055625/image-w...

Mat warp(im.size(), im.type());

imshow("warp", warp); waitKey(0);

int width = im.cols, height = im.rows;

double x0, y0, w2, h2;

2013-11-12 05:02:47 補充：

x0 = width/2., y0 = height/2.;

w2 = width/1.4, h2 = height/1.4;

for-loop, 則外部用 n = 0:0.2:0.01

內部就是跑 y,x

每次新 n 值, warp.setTo(Scalar(255,255,255));

2013-11-12 05:04:15 補充：

Point2d cen((x-x0)/w2,(y-y0)/h2);

double len=sqrt(cen.ddot(cen));

double nlog=n*log(len);

Point2d mcen = nlog*cen;

int x2=x-mcen.x*w2;

int y2=y-mcen.y*h2;

if(x2 >= 0 && y2 >= 0 && x2 < width && y2 < height){

Vec3b color = im.at (y2, x2);

warp.at (y, x) = color;

}