修订后的问题
我想将笛卡尔像素的栅格转换为极性像素。有这样做的明智算法吗?例如,在给定重叠的三个(笛卡尔)像素值的情况下,如何计算下图中阴影(极性)像素的值?
原始问题
是否有合理的方法来计算正方形和环形截面的交点面积,如下面的橙色部分所示?
动机:我有一个正方形像素的栅格,并将其转换为“极性像素”-我想找出每个笛卡尔像素对每个极性像素的贡献。
#1 楼
我已经实现了笛卡尔到极点的转换,并使用了不同的插值方法:1)最近邻
2)二次采样方法,平均81个子像素位置
3)双线性插值
下图中的第二行显示了三种方法的输出的详细放大倍数:
这是方法1和方法3的GLSL着色器代码:
precision mediump float;
varying vec2 tc; // texture coordinate of current output pixel
uniform sampler2D inputImg; // input image
const float PI = 3.141592653589793238462643383;
void main() {
float phi = tc.x; // phi is x-direction in output
float r = tc.y; // radius is y-direction in output
float xx = r * cos(2.0 * PI * phi); // unit circle in range [-1.0, 1.0]
float yy = r * sin(2.0 * PI * phi);
float x = xx * 0.5 + 0.5; // input texture coordinate in range [0.0, 1.0];
float y = yy * 0.5 + 0.5;
gl_FragColor = texture2D(inputImg, vec2(x,y));
}
这是方法2的GLSL着色器代码:
precision mediump float;
varying vec2 tc; // texture coordinate of current output pixel
uniform sampler2D inputImg; // input image
uniform int outputWidth; // width of output image
uniform int outputHeight; // height of output image
const float PI = 3.141592653589793238462643383;
const int samplesPerSide = 4;
void main() {
int samplesPerDirection = samplesPerSide * 2 + 1;
// compute size of subsample step in texture coordinates
float sampleStepX = 1.0 / float(outputWidth * samplesPerDirection);
float sampleStepY = 1.0 / float(outputHeight * samplesPerDirection);
vec4 sampleSum = vec4(0); // init sum to zero
for(int i = -samplesPerSide; i <= samplesPerSide; i++) {
for(int j = -samplesPerSide; j <= samplesPerSide; j++) {
float phi = tc.x + float(i) * sampleStepX; // phi is x-direction in output
float r = tc.y + float(j) * sampleStepY; // radius is y-direction in output
float xx = r * cos(2.0 * PI * phi); // unit circle in range [-1.0, 1.0]
float yy = r * sin(2.0 * PI * phi);
float x = xx * 0.5 + 0.5; // input texture coordinate in range [0.0, 1.0];
float y = yy * 0.5 + 0.5;
sampleSum += texture2D(inputImg, vec2(x,y));
}
}
gl_FragColor += sampleSum / float(samplesPerDirection * samplesPerDirection);
}
方法2,约为因子81比1和3慢,可能是您正在寻找的因子,但我也喜欢双线性插值结果。
使用具有WebGL功能的浏览器,您可以在此处尝试以下实现:
https://www.gsn-lib.org/index.html#projectName=CartesianToPolar&graphName=CartesianToPolar
评论
$ \ begingroup $
漂亮回答。并渲染。谢谢。
$ \ endgroup $
–fearless_fool
16年7月1日在23:24
$ \ begingroup $
请以后使用缩进的代码块。好答案
$ \ endgroup $
– joojaa
16年7月2日在7:14
#2 楼
我打电话给一位老同事和CG专家,问了几个问题后,他提供了一个简单的解决方案。我可能已经整理了一些细节,但是基本思想如下:以所需的精确度对极坐标进行二次采样,将每个二次采样视为一个点。然后找到包含每个点的笛卡尔像素很简单。总结每个极点像素的子采样点以获得最终值。
正确设置权重有一些微妙之处-指导见解是,如果整个笛卡尔栅格为纯灰色,则每个极性像素应具有相同的灰度值。您还可以添加许多其他细微差别,但是基本技术是直观且计算简单的。
评论
环形切片的左边界与矩形轴的对齐完全是巧合吗?这是承保范围计算吗?您为什么选择实施效率非常低的盒式过滤器?
@joojaa同意,但如果使它更容易,则可以从一些覆盖率计算中构建出一个近似的高斯函数。
@trichoplax:点好!我将讨论Maths.SE的问题-谢谢您的指导。
这样的事情。一般而言,箱式过滤是您可以选择的最差的过滤器。像素不是真正的正方形,而是点样本(读取的像素不是正方形x 3)。通过使用标准函数重建,您可以对有限采样进行相同的处理,这比框式过滤器可以产生更好的图像,因为您的工作量较少盒过滤算法是如此令人费解且昂贵。