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();
}
}
}