我有四个2d点,p0 =(x0,y0),p1 =(x1,y1)等,形成一个四边形.在我的例子中,四边形不是矩形,但至少应该是凸面.
p2 --- p3
| |
t | p |
| |
p0 --- p1
s
Run Code Online (Sandbox Code Playgroud)
我正在使用双线性插值.S和T在[0..1]范围内,插值点由下式给出:
bilerp(s,t) = t*(s*p3+(1-s)*p2) + (1-t)*(s*p1+(1-s)*p0)
Run Code Online (Sandbox Code Playgroud)
这是问题..我有一个2d点p,我知道它在四边形内.我想在使用双线性插值时找到能给我这一点的s,t.
是否有一个简单的公式来反转双线性插值?
谢谢你的解决方案.我将我的Naaff解决方案的实现发布为维基.
结果tf.image.resize_bilinear与之完全不同cv2.resize.
我发现这有点麻烦.设置align_corners=True并不总是合理的,因为四个角并不总是固定在角落里.那么无论如何要让它更"对称"吗?
代码重现:
import tensorflow as tf
import numpy as np
import cv2
np.set_printoptions(precision=3)
resize_shape = (10, 10)
a = np.ones((1, 2, 2, 1), dtype=np.float32)
a[0, 0, 0, 0] = 5.0
a[0, 1, 1, 0] = 5.0
b = tf.constant(a, dtype=tf.float32)
c = tf.image.resize_bilinear(b, resize_shape)
with tf.Session() as sess:
np_c = sess.run(c)
print np_c[0, :, :, 0]
print cv2.resize(a[0], resize_shape, interpolation=cv2.INTER_LINEAR)
Run Code Online (Sandbox Code Playgroud)
获得的结果:
# tf.image.resize_bilinear
[[ 5. 4.2 3.4 2.6 1.8 1. 1. 1. 1. …Run Code Online (Sandbox Code Playgroud) OpenCV remap()使用实值索引网格使用双线性插值从图像中采样值网格,并将样本网格作为新图像返回.
确切地说,让:
A = an image
X = a grid of real-valued X coords into the image.
Y = a grid of real-valued Y coords into the image.
B = remap(A, X, Y)
Run Code Online (Sandbox Code Playgroud)
那么对于所有像素坐标i,j,
B[i, j] = A(X[i, j], Y[i, j])
Run Code Online (Sandbox Code Playgroud)
其中圆括号A(x, y)表示使用双线性插值来求解使用浮点数x和和的图像A的像素值y.
我的问题是:给定索引网格X,Y我如何生成"逆网格" X^-1,Y^-1这样:
X(X^-1[i, j], Y^-1[i, j]) = i
Y(X^-1[i, j], Y^-1[i, j]) = j
Run Code Online (Sandbox Code Playgroud)
和
X^-1(X[i, j], Y[i, j]) = i
Y^-1(X[i, …Run Code Online (Sandbox Code Playgroud) 使用双线性插值将2x2矩阵升级到5x5的示例程序.对于这种简单的情况,OpenCV产生的结果在边界处具有伪像.
gy, gx = np.mgrid[0:2, 0:2]
gx = np.float32(gx)
print(gx)
res = cv2.resize(gx,(5,5), fx=0, fy=0, interpolation=cv2.INTER_LINEAR)
print(res)
Run Code Online (Sandbox Code Playgroud)
输出:
[[ 0. 1.]
[ 0. 1.]]
[[ 0. 0.1 0.5 0.89999998 1. ]
[ 0. 0.1 0.5 0.89999998 1. ]
[ 0. 0.1 0.5 0.89999998 1. ]
[ 0. 0.1 0.5 0.89999998 1. ]
[ 0. 0.1 0.5 0.89999998 1. ]]
Run Code Online (Sandbox Code Playgroud)
预期产量:
[[0 0.25 0.5 0.75 1
0 0.25 0.5 0.75 1
0 0.25 0.5 0.75 1
0 0.25 0.5 0.75 1 …Run Code Online (Sandbox Code Playgroud) 函数imagecopyresampled可用于生成缩略图或调整图像大小,同时保持纵横比:
$fn = $_FILES['data']['tmp_name'];
$size = getimagesize($fn);
$width = $size[0];
$height = $size[1];
$ratio = $width / $height;
if ($ratio > 1 && $size[0] > 500) { $width = 500; $height = 500 / $ratio; }
else { if ($ratio <= 1 && $size[1] > 500) { $width = 500 * $ratio; $height = 500; }}
$src = imagecreatefromstring(file_get_contents($fn));
$dst = imagecreatetruecolor($width, $height);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $size[0], $size[1]);
imagedestroy($src);
imagejpeg($dst, 'test.jpg');
imagedestroy($dst);
Run Code Online (Sandbox Code Playgroud)
如何选择PHP使用的大小调整算法? …
考虑以下MATLAB代码:
C = [ 0 0 0 0 0
0 1 2 1 0
0 2 4 2 0
0 1 2 1 0
0 0 0 0 0 ];
pcolor( C );
shading interp;
axis square
Run Code Online (Sandbox Code Playgroud)
注意,C在90度旋转下是不变的.另请注意以下句子中的帮助pcolor:
使用着色interp,使用C的所有元素,通过四个顶点处的颜色的双线性插值对每个单元进行着色.
但是,绘制的图像如下:
请注意,图像在90度旋转下不是不变的(例如考虑四个角).现在,除非我可怕地误解双线性插值,否则这一定是错的.MATLAB似乎是在三角形上插值,这与双线性插值不同.
有没有办法解决这个MATLAB错误,并获得正确的双线性插值?(除了我自己手动插入额外的点,如果放大到足够远,这仍然无法解决问题.)
*注意:尽管这篇文章是关于双线性插值的,但我还是保持标题的一般性,并提供了更多信息,以防有人对如何更好地做到这一点有所了解
为了创建单词搜索解决程序,我一直难以实现从图像中识别字母的方法。出于主要出于教育目的,也出于便携性的目的,我一直在尝试使用不使用库的方法。可以假设,将要拾取字符的图像除了拼图之外没有任何其他内容。尽管此页面只能识别少量字符,但我一直在用它来指导我的工作,这一个也一样 正如文章所建议的,我将每个字母的图像缩小为5x5,以将每个未知字母与之进行比较。通过使用双线性重采样将未知数缩小到5x5,并对已知和未知图像中每个相应像素的强度差的平方求和,我获得了最大的成功。为了尝试获得更准确的结果,我还添加了每个图像的上半部分和下半部分的宽度:高度比率和白色:黑色像素比率之差的平方。然后,将具有与未知图像最接近的“差异分数”的已知图像视为未知字母。问题在于,这似乎只有大约50%的准确性。为了改善这一点,我尝试使用较大的样本(而不是5x5,我尝试使用15x15),但是事实证明效果不佳。我还尝试浏览已知和未知的图像,寻找特征和形状,然后基于具有相同数量的相同特征的两个图像确定匹配项。例如,识别并计数了以下形状:?代表黑色像素)。事实证明,这种方法不如原始方法有效。
? ? ? ?
? ?
Run Code Online (Sandbox Code Playgroud)
因此,这里是一个示例:加载以下图像:
然后,该程序通过使用面积总和表确定每个像素的强度是否高于或低于11x11平方的平均强度,将其转换为单色,修复倾斜并通过识别相对相等间距的区域来挑选字母。然后,我使用相交的水平和垂直空间来大致了解每个字符的位置。接下来,我要确保在每个方块中都包含整个字母,方法是在原始方块的上方,下方,左侧和右侧逐行查找,直到该方块的边界未检测到深色像素为止。
然后,我将每个字母都重新采样,然后将其与已知图像进行比较。
*注意:已知样本使用的字体大小为12,使用双线性插值法在photoshop中重新缩放为5x5。
这是一个成功匹配的示例:选出以下字母:
缩小为:
看起来像
远道而来。这已成功匹配已知的N个样本:
这是失败的比赛:
被挑选出来并缩小为:
毫不奇怪,它与已知的R样本不匹配
我更改了图像的拾取方式,以致如上图所示,该字母不会被截断,因此我认为问题出在缩小图像上。目前,我正在使用双线性插值对图像进行重新采样。要了解究竟是如何工作原理与采样我提到的第二个答案的这个职位,并用下面的代码上来。以前,我已经测试过此代码可以正常工作(至少达到“看起来不错”的程度),因此它可能是引起问题的多种因素的组合。
void Image::scaleTo(int width, int height)
{
int originalWidth = this->width;
int originalHeight = this->height;
Image * originalData = new Image(this->width, this->height, 0, 0);
for (int i = 0; i < this->width * this->height; i++) {
int x = i % this->width;
int y = i / this->width;
originalData->setPixel(x, y, …Run Code Online (Sandbox Code Playgroud) 我正在使用 Tensorflow 1.4.0
Tensorflow tf.image.resize_bilinear() 有一个名为“align_corners”的参数,当我们将其设置为 False 时,我对行为感到困惑。在官方文档中,它说:
align_corners:一个可选的布尔值。默认为假。如果为 true,则输入和输出张量的 4 个角像素的中心对齐,保留角像素处的值。默认为假。
当我在以下程序中使用 tf.image.resize_bilinear() 和 align_corners=True 时:
import tensorflow as tf
sess = tf.Session()
x = tf.Variable(tf.Variable([[[[1],[2]],[[3],[4]]]]))
pooling_output_size = [4, 4]
pool_output = tf.image.resize_bilinear(x, pooling_output_size,align_corners=True)
sess.run(tf.global_variables_initializer())
print pool_output.eval(session=sess)
Run Code Online (Sandbox Code Playgroud)
它输出
[[[[1. ]
[1.3333334]
[1.6666667]
[2. ]]
[[1.6666667]
[2. ]
[2.3333335]
[2.6666667]]
[[2.3333335]
[2.6666665]
[3. ]
[3.3333335]]
[[3. ]
[3.3333333]
[3.6666667]
[4. ]]]]
Run Code Online (Sandbox Code Playgroud)
哪些角正确对齐。
但是,当我设置 align_corners=False 时,我得到了以下奇怪的输出
[[[[1. ]
[1.5]
[2. ]
[2. ]]
[[2. ]
[2.5]
[3. ]
[3. …Run Code Online (Sandbox Code Playgroud) My exmaple in JavaScript and <canvas>. https://codepen.io/KonradLinkowski/pen/QWbjaPr
const canvas = document.querySelector('#box')
const ctx = canvas.getContext('2d')
const interpolate = (value, start, end) => (end - start) * value + start
const interpolateRGB = (value, start, end) => {
return {
r: interpolate(value, start.r, end.r),
g: interpolate(value, start.g, end.g),
b: interpolate(value, start.b, end.b)
}
}
const calcColor = (point, topLeft, topRight, bottomLeft, bottomRight) => {
const top = interpolateRGB(point.x, topLeft, topRight)
const bottom = interpolateRGB(point.x, bottomLeft, bottomRight)
const result = interpolateRGB(point.y, …Run Code Online (Sandbox Code Playgroud)css linear-gradients background-color css-gradients bilinear-interpolation
使用interp函数(Akima软件包),可以绘制与数据集的双变量插值相对应的表面,请参见下面的示例(来自interp文档):
library(rgl)
data(akima)
# data visualisation
rgl.spheres(akima$x,akima$z , akima$y,0.5,color="red")
rgl.bbox()
# bivariate linear interpolation
# interp:
akima.li <- interp(akima$x, akima$y, akima$z,
xo=seq(min(akima$x), max(akima$x), length = 100),
yo=seq(min(akima$y), max(akima$y), length = 100))
# interp surface:
rgl.surface(akima.li$x,akima.li$y,akima.li$z,color="green",alpha=c(0.5))
Run Code Online (Sandbox Code Playgroud)
但是,输出仅是描述一组点的列表,而不是常规函数。
问题:是否有任何方法来获得与先前获得的曲面匹配的函数z = f(x,y)?我知道它可以使用interp(akima $ x,akima $ y,akima $ z,xo = A,yo = B),但是它非常慢。
在二维中,roximfun()函数可以完成此工作,但我找不到多参数插值的等效项。
我尝试使用 openCv 功能在 c++ 中旋转后进行双线性插值,但不使用在 openCv 中实现的双线性插值。
在我的输出图像中,总会有一些伪影(像素的颜色完全不同)。
我使用这个公式:
双线性插值公式

我没有使用 math.h 中的 ceil,而是使用 openCV 中的 cvRound()。
所以我的输入是: lena

我的工件输出是:
旋转和插值后的莉娜

我对所有 RGB 值使用该公式,因此对于 B,它看起来:
int l = cvRound(xn);
int k = cvRound(yn);
float a = xn-l;
float b = yn-k;
uchar B = (1-a)*(1-b)*src.at<cv::Vec3b>(l,k).val[0]+a*(1-b)*src.at<cv::Vec3b>(l+1,k).val[0]+b*(1-a)*src.at<cv::Vec3b>(l,k+1).val[0]+a*b*src.at<cv::Vec3b>(l+1,k+1).val[0];
Run Code Online (Sandbox Code Playgroud)
xn 和 yn 是变换 MAT 中的坐标,它们是浮点数。
正如您所看到的,大部分输出图片都是按应有的方式计算的,但不知何故,它们很少是人工制品,这让我没有任何意义。我需要摆脱它们。
感谢您的任何建议。
c++ interpolation opencv image-processing bilinear-interpolation