Resize image
Peponi │ 2/12/2025 │ 7m
C#
NugetPackageOpenCvSharp4
Resize image
2/12/2025
7m
Peponi
C#
NugetPackageOpenCvSharp4
1. Introduction
OpenCvSharp4는 이미지 크기 조절 기능을 제공하는데, Cv2.Resize()
와 Cv2.PyrUp()
, Cv2.PyrDown()
을 제공한다. 여기서는 Cv2.Resize()
에 대해 알아본다.
Cv2.Resize()
는 사이즈 변경과 함께 다양한 픽셀 보간 방법을 제공한다. 사이즈 변경은 원하는 특정 크기 또는 스케일 팩터 적용이 가능하다. 픽셀 보간 방법은 기본적으로 InterpolationFlags
.Linear
가 적용되어 있으며 자세한 리스트는 아래 표를 참조한다.
InterpolationFlags | Description |
---|---|
Nearest | Nearest-neighbor interpolation |
Linear | Bilinear interpolation (used by default) |
Cubic | Bicubic interpolation. |
Area | Resampling using pixel area relation. It is the preferred method for image decimation that gives moire-free results. In case of zooming it is similar to CV_INTER_NN method. |
Lanczos4 | Lanczos interpolation over 8x8 neighborhood |
LinearExact | Bit exact bilinear interpolation |
Max | mask for interpolation codes |
WarpFillOutliers | Fill all the destination image pixels. If some of them correspond to outliers in the source image, they are set to fillval. |
WarpInverseMap | Indicates that matrix is inverse transform from destination image to source and, thus, can be used directly for pixel interpolation. Otherwise, the function finds the inverse transform from map_matrix. |
OpenCV docs에 의하면 이미지 축소를 할 때는 보통 InterpolationFlags
.Area
가 최상의 결과를 가져오며, 확대 시에는 InterpolationFlags
.Cubic
이 가장 결과가 좋다고 한다.
To shrink an image, it will generally look best with INTER_AREA interpolation, whereas to enlarge an image, it will generally look best with INTER_CUBIC (slow) or INTER_LINEAR (faster but still looks OK).
2. Sampling image

여기서는 이미지 로드 후 스케일을 변경하는 방법을 알아본다.
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace ResizeImage;
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.Controls.Add(AddComponents());
}
private void Load_Click(object? sender, EventArgs e)
{
OpenFileDialog dialog = new()
{
Filter = "All files|*.*",
InitialDirectory = $@"C:\",
CheckPathExists = true,
CheckFileExists = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
// Image load
using var original = Cv2.ImRead(dialog.FileName);
// Sampling
// Mat.Resize(targetSize, scaleFactorX, scaleFactorY, InterpolationFlags)
// targetSize가 0일 때는 호출자 (여기서는 original) 의 크기 사용
using var upsampled = original.Resize(new(), 4, 4);
using var downsampled = original.Resize(new(), 0.25, 0.25);
SetImage(nameof(original), original);
SetImage(nameof(upsampled), upsampled);
SetImage(nameof(downsampled), downsampled);
}
}
private TableLayoutPanel AddComponents()
{
PictureBox original = new()
{
Name = nameof(original),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox upsampled = new()
{
Name = nameof(upsampled),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox downsampled = new()
{
Name = nameof(downsampled),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
Button load = new()
{
Name = nameof(load),
Dock = DockStyle.Fill,
Text = nameof(load),
};
load.Click += Load_Click;
TableLayoutPanel panel = new()
{
ColumnCount = 3,
RowCount = 2,
Dock = DockStyle.Fill,
};
panel.ColumnStyles.Add(new(SizeType.Percent, 33.34F));
panel.ColumnStyles.Add(new(SizeType.Percent, 33.33F));
panel.ColumnStyles.Add(new(SizeType.Percent, 33.33F));
panel.RowStyles.Add(new(SizeType.Percent, 95));
panel.RowStyles.Add(new(SizeType.Percent, 5));
panel.Controls.Add(original, 0, 0);
panel.Controls.Add(upsampled, 1, 0);
panel.Controls.Add(downsampled, 2, 0);
panel.Controls.Add(load, 0, 1);
return panel;
}
private void SetImage(string controlName, Mat image)
{
if (this.Controls.Find(controlName, true).First() is PictureBox box)
{
box.Image = image.ToBitmap();
}
}
}
3. Upsampling

여기서는 몇몇 보간 방법을 적용하여 이미지의 크기를 키우고 결과를 확인한다.
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace ResizeImage;
public class Form2 : Form
{
public Form2()
{
this.Size = new System.Drawing.Size(1280, 768);
this.Controls.Add(AddComponents());
}
private void Load_Click(object? sender, EventArgs e)
{
OpenFileDialog dialog = new()
{
Filter = "All files|*.*",
InitialDirectory = $@"C:\",
CheckPathExists = true,
CheckFileExists = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
// Image load
using var original = Cv2.ImRead(dialog.FileName);
// Sampling
// Mat.Resize(targetSize, scaleFactorX, scaleFactorY, InterpolationFlags)
// targetSize가 0일 때는 호출자 (여기서는 original) 의 크기 사용
using var nearest = original.Resize(new(), 4, 4, InterpolationFlags.Nearest);
using var linear = original.Resize(new(), 4, 4, InterpolationFlags.Linear);
using var cubic = original.Resize(new(), 4, 4, InterpolationFlags.Cubic);
using var area = original.Resize(new(), 4, 4, InterpolationFlags.Area);
using var lanczos4 = original.Resize(new(), 4, 4, InterpolationFlags.Lanczos4);
SetImage(nameof(original), original);
SetImage(nameof(nearest), nearest);
SetImage(nameof(linear), linear);
SetImage(nameof(cubic), cubic);
SetImage(nameof(area), area);
SetImage(nameof(lanczos4), lanczos4);
}
}
private TableLayoutPanel AddComponents()
{
PictureBox original = new()
{
Name = nameof(original),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox nearest = new()
{
Name = nameof(nearest),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox linear = new()
{
Name = nameof(linear),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox cubic = new()
{
Name = nameof(cubic),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox area = new()
{
Name = nameof(area),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox lanczos4 = new()
{
Name = nameof(lanczos4),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
Button load = new()
{
Name = nameof(load),
Dock = DockStyle.Fill,
Text = nameof(load),
};
load.Click += Load_Click;
TableLayoutPanel panel = new()
{
ColumnCount = 5,
RowCount = 2,
Dock = DockStyle.Fill,
};
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.RowStyles.Add(new(SizeType.Percent, 50));
panel.RowStyles.Add(new(SizeType.Percent, 50));
panel.Controls.Add(original, 2, 0);
panel.Controls.Add(load, 4, 0);
panel.Controls.Add(nearest, 0, 1);
panel.Controls.Add(linear, 1, 1);
panel.Controls.Add(cubic, 2, 1);
panel.Controls.Add(area, 3, 1);
panel.Controls.Add(lanczos4, 4, 1);
return panel;
}
private void SetImage(string controlName, Mat image)
{
if (this.Controls.Find(controlName, true).First() is PictureBox box)
{
box.Image = image.ToBitmap();
}
}
}
4. Downsampling

여기서는 몇몇 보간 방법을 적용하여 이미지의 크기를 낮추고 결과를 확인한다.
using OpenCvSharp;
using OpenCvSharp.Extensions;
namespace ResizeImage;
public class Form3 : Form
{
public Form3()
{
this.Size = new System.Drawing.Size(1280, 768);
this.Controls.Add(AddComponents());
}
private void Load_Click(object? sender, EventArgs e)
{
OpenFileDialog dialog = new()
{
Filter = "All files|*.*",
InitialDirectory = $@"C:\",
CheckPathExists = true,
CheckFileExists = true
};
if (dialog.ShowDialog() == DialogResult.OK)
{
// Image load
using var original = Cv2.ImRead(dialog.FileName);
// Sampling
// Mat.Resize(targetSize, scaleFactorX, scaleFactorY, InterpolationFlags)
// targetSize가 0일 때는 호출자 (여기서는 original) 의 크기 사용
using var nearest = original.Resize(new(), 0.5, 0.5, InterpolationFlags.Nearest);
using var linear = original.Resize(new(), 0.5, 0.5, InterpolationFlags.Linear);
using var cubic = original.Resize(new(), 0.5, 0.5, InterpolationFlags.Cubic);
using var area = original.Resize(new(), 0.5, 0.5, InterpolationFlags.Area);
using var lanczos4 = original.Resize(new(), 0.5, 0.5, InterpolationFlags.Lanczos4);
SetImage(nameof(original), original);
SetImage(nameof(nearest), nearest);
SetImage(nameof(linear), linear);
SetImage(nameof(cubic), cubic);
SetImage(nameof(area), area);
SetImage(nameof(lanczos4), lanczos4);
}
}
private TableLayoutPanel AddComponents()
{
PictureBox original = new()
{
Name = nameof(original),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox nearest = new()
{
Name = nameof(nearest),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox linear = new()
{
Name = nameof(linear),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox cubic = new()
{
Name = nameof(cubic),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox area = new()
{
Name = nameof(area),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
PictureBox lanczos4 = new()
{
Name = nameof(lanczos4),
Dock = DockStyle.Fill,
SizeMode = PictureBoxSizeMode.StretchImage
};
Button load = new()
{
Name = nameof(load),
Dock = DockStyle.Fill,
Text = nameof(load),
};
load.Click += Load_Click;
TableLayoutPanel panel = new()
{
ColumnCount = 5,
RowCount = 2,
Dock = DockStyle.Fill,
};
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.ColumnStyles.Add(new(SizeType.Percent, 20));
panel.RowStyles.Add(new(SizeType.Percent, 50));
panel.RowStyles.Add(new(SizeType.Percent, 50));
panel.Controls.Add(original, 2, 0);
panel.Controls.Add(load, 4, 0);
panel.Controls.Add(nearest, 0, 1);
panel.Controls.Add(linear, 1, 1);
panel.Controls.Add(cubic, 2, 1);
panel.Controls.Add(area, 3, 1);
panel.Controls.Add(lanczos4, 4, 1);
return panel;
}
private void SetImage(string controlName, Mat image)
{
if (this.Controls.Find(controlName, true).First() is PictureBox box)
{
box.Image = image.ToBitmap();
}
}
}