Opencvに基づく二重線形補間の実現(二)
1946 ワード
前編のブログでは,二重線形補間アルゴリズムに基づく画像スケーリングを実現し,主な関数zoomではポインタが大量に用いられている.ポインタで画像画素を読み取る利点は、実行速度が速く、コードが読みにくいことです.本編ではopencvライブラリに付属するcvGet 2 D()とcvSet 2 D()関数を用いて画像画素を読み書きし,実行速度は遅いがコード読解性が強く,簡単明瞭である.
次は主な関数zoomの実装で、他の部分は私の前のブログを参考にします.
次は主な関数zoomの実装で、他の部分は私の前のブログを参考にします.
void zoom(IplImage* src, IplImage* dst)
{
int srcWidth = src->width;
int srcHeight = src->height;
int dstWidth = dst->width;
int dstHeight = dst->height;
// , 1 , , 。
const float tx = (srcWidth-1.0f)/(dstWidth-1.0f);
const float ty = (srcHeight-1.0f)/(dstHeight-1.0f);
CvPoint2D32f uv;//
CvPoint3D32f f1;
CvPoint3D32f f2;
for (int j=0; j<dstHeight-1; j++)
{
for (int i=0; i<dstWidth-1; i++)
{
uv.x = i*tx;
uv.y = j*ty;
int iu = (int)uv.x;
int iv = (int)uv.y;
CvScalar p1, p2, p3, p4, s;
p1=cvGet2D(src, iv, iu);
p2=cvGet2D(src, iv, iu+1);
p3=cvGet2D(src, iv+1, iu);
p4=cvGet2D(src, iv+1, iu+1);
f1.x = p1.val[0]*(1-Abs(uv.x-iu))+p2.val[0]*(uv.x-iu);
f1.y = p1.val[1]*(1-Abs(uv.x-iu))+p2.val[1]*(uv.x-iu);
f1.z = p1.val[2]*(1-Abs(uv.x-iu))+p2.val[2]*(uv.x-iu);
f2.x = p3.val[0]*(1-Abs(uv.x-iu))+p4.val[0]*(uv.x-iu);
f2.y = p3.val[1]*(1-Abs(uv.x-iu))+p4.val[1]*(uv.x-iu);
f2.z = p3.val[2]*(1-Abs(uv.x-iu))+p4.val[2]*(uv.x-iu);
s.val[0] = f1.x*(1-Abs(uv.y-iv))+f2.x*(Abs(uv.y-iv));
s.val[1] = f1.y*(1-Abs(uv.y-iv))+f2.y*(Abs(uv.y-iv));
s.val[2] = f1.z*(1-Abs(uv.y-iv))+f2.z*(Abs(uv.y-iv));
cvSet2D(dst, j, i, s);
}
//
cvSet2D(dst, j, dstWidth-1, cvGet2D(dst, j, dstWidth-2));
}
//
for(int i=0; i<dstWidth; i++)
{
cvSet2D(dst, dstHeight-1, i, cvGet2D(dst, dstHeight-2, i));
}
}