最近邻插值算法的实现
using namespace std; using namespace cv;
Mat NearInter(Mat &srcImage, double kx, double ky)
{
int rows = cvRound(srcImage.rows*kx);
int cols = cvRound(srcImage.cols*ky);
Mat resultImg(rows, cols, srcImage.type());
int i, j, x, y;
for (i = 0; i < rows; i++)
{
x = static_cast<int>((i + 1) / kx + 0.5) - 1;
for (j = 0; j < cols; j++)
{
y = static_cast<int>((j + 1) / ky+ 0.5) - 1; resultImg.at<Vec3b>(i, j) = srcImage.at<Vec3b>(x, y);
}
}
return resultImg;
}
int main()
{
Mat srcImg = imread("D:\\Visual Studio 2015\\lena.bmp");
Mat resultImg = NearInter(srcImg, 0.6, 1.2);
imshow("src", srcImg);
imshow("0.6,1.2", resultImg);
waitKey(0);
return 0;
}
双线性插值代码的实现
uchar* dataDst = matDst1.data;
int stepDst = matDst1.step;
uchar* dataSrc = matSrc.data;
int stepSrc = matSrc.step;
int iWidthSrc = matSrc.cols;
int iHiehgtSrc = matSrc.rows;
for (int j = 0; j < matDst1.rows; ++j)
{
float fy = (float)((j + 0.5) * scale_y - 0.5);
int sy = cvFloor(fy);
fy -= sy;
sy = std::min(sy, iHiehgtSrc - 2);
sy = std::max(0, sy);
short cbufy[2];
cbufy[0] = cv::saturate_cast<short>((1.f - fy) * 2048);
cbufy[1] = 2048 - cbufy[0];
for (int i = 0; i < matDst1.cols; ++i)
{
float fx = (float)((i + 0.5) * scale_x - 0.5);
int sx = cvFloor(fx);
fx -= sx;
if (sx < 0) {
fx = 0, sx = 0;
}
if (sx >= iWidthSrc - 1) {
fx = 0, sx = iWidthSrc - 2;
}
short cbufx[2];
cbufx[0] = cv::saturate_cast<short>((1.f - fx) * 2048);
cbufx[1] = 2048 - cbufx[0];
for (int k = 0; k < matSrc.channels(); ++k)
{
*(dataDst+ j*stepDst + 3*i + k) = (*(dataSrc + sy*stepSrc + 3*sx + k) * cbufx[0] * cbufy[0] +
*(dataSrc + (sy+1)*stepSrc + 3*sx + k) * cbufx[0] * cbufy[1] +
*(dataSrc + sy*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[0] +
*(dataSrc + (sy+1)*stepSrc + 3*(sx+1) + k) * cbufx[1] * cbufy[1]) >> 22;
}
}
}
cv::imwrite("linear_1.jpg", matDst1);
cv::resize(matSrc, matDst2, matDst1.size(), 0, 0, 1);
cv::imwrite("linear_2.jpg", matDst2);
双线性插值原理
学习手册Task01-06