ノンローカルミーン(Non-Local Means)フィルタは、画像内のノイズを除去する手法の一つで
画像全体の広い範囲から似たようなパターン(テクスチャ)を探し、それらを平均化してノイズを消します。
エッジや細かい模様を「画像内の別の場所にある似た構造」から復元するため、鮮明さを維持しやすいのが特徴です。
高品質な結果が得られる反面、画像全体を探索するため計算量が非常に多く、処理に時間がかかるという側面があります。
NonLocalMeansFilter.cs
using OpenCvSharp;
using Reactive.Bindings;
using Reactive.Bindings.Extensions;
using System.Reactive.Linq;
using Cv = OpenCvSharp;
namespace OpenCvFilterMaker2;
public class NonLocalMeansFilter : CvFilterBase
{
public ReactivePropertySlim<float> H{ get; set; }
= new ReactivePropertySlim<float>(10.0f);
public ReactivePropertySlim<int> TemplateWindowSize { get; set; }
= new ReactivePropertySlim<int>(7);
public ReactivePropertySlim<int> SearchWindowSize { get; set; }
= new ReactivePropertySlim<int>(21);
public NonLocalMeansFilter()
{
MenuHeader = "ノンローカルミーン";
IsEnabled.Value = true;
H.Subscribe(_ => UpdateName())
.AddTo(Disposable);
TemplateWindowSize
.Subscribe(value =>
{
TemplateWindowSize.Value = value < 3 ? 3 : value;
UpdateName();
})
.AddTo(Disposable);
SearchWindowSize
.Subscribe(value =>
{
SearchWindowSize.Value = value < 7 ? 7 : value;
UpdateName();
})
.AddTo(Disposable);
UpdateName();
}
private void UpdateName()
{
Name.Value = $"NonLocalMeansFilter(H={H.Value} Teamp={TemplateWindowSize.Value}) Search={SearchWindowSize.Value}";
}
protected override Cv.Mat Apply(Cv.Mat input)
{
if (input.Depth() != Cv.MatType.CV_8U)
throw new InvalidOperationException("NLMeans requires CV_8U image.");
Cv.Mat dst = new Cv.Mat();
if (input.Channels() == 1)
{
Cv2.FastNlMeansDenoising(
input,
dst,
H.Value,
TemplateWindowSize.Value,
SearchWindowSize.Value);
}
else
{
Cv2.FastNlMeansDenoisingColored(
input,
dst,
H.Value,
H.Value,
TemplateWindowSize.Value,
SearchWindowSize.Value);
}
return dst;
}
}
NonLocalMeansFilter.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:OpenCvFilterMaker2">
<!-- NonLocalMeansFilter用テンプレート -->
<DataTemplate DataType="{x:Type local:NonLocalMeansFilter}">
<StackPanel Margin="10">
<TextBlock Text="NonLocalMeansFilter Settings"
FontWeight="Bold"
Margin="0,0,0,10"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="H:"
VerticalAlignment="Center"
Margin="0,0,5,0"/>
<TextBox Width="60"
Text="{Binding H.Value}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="TemplateWindowSize:"
VerticalAlignment="Center"
Margin="0,0,5,0"/>
<TextBox Width="60"
Text="{Binding TemplateWindowSize.Value}"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="SearchWindowSize:"
VerticalAlignment="Center"
Margin="0,0,5,0"/>
<TextBox Width="60"
Text="{Binding SearchWindowSize.Value}"/>
</StackPanel>
</StackPanel>
</DataTemplate>
</ResourceDictionary>
MainWindow.xaml
<ResourceDictionary Source="/Resources/NonLocalMeansFilter.xaml"/>
追加


コメント