ChatGPTでプログラム生成⑤

ChatGPTでプログラム生成④に追加でChatGPTへ質問し、もう少し整理されたソースリストを入手します。

ChatGPTへ追加質問

以下の質問をChatGPTでプログラム生成④に追加で行います。

画像の保存機能が欲しい
フィルター処理を増やし、メニューも追加して
フィルターはクラスに分離して
フィルタークラスは一つにまとめて
全部のソースリストを示して

arques.hatenablog.com
なお、ChatGPTの回答は毎回異なりますので、その都度、自身で質問を調整する必要があります。ChatGPTが生成したソースコードコンパイル時にエラーになる場合や、実行時に例外が発生したり、画像表示がうまく行かない場合もあります。このため、万能ではなくC#OpenCVの基礎知識がないと難しいと感じます。代わりに、C#OpenCVの初級者が画像処理を行いたいときにchatGPTは強力な助っ人なるでしょう。現在のChatGPTで、これだけの完成度ですので、しばらくしたら簡単なコードを記述するようにエンジニアの出番は無さそうに感じますし、中級以上のエンジニアであっても生産性の低いエンジニアは淘汰されてしまうのではないかと思います。

プロジェクトの生成とOpenCVsharpのインストール

ChatGPTでプログラム生成④と同じです。NuGetで導入するのは、

OpenCvSharp4.WpfExtensions
OpenCvSharp4.Windows

の2つです。

ChatGPTが生成したソースコード

以降に、ChatGPTが生成したソースコードを示します。Visual Studio が生成したMainWindow.xamlとMainWindow.xaml.csへ上書きします。

MainWindow.xaml

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Menu>
            <MenuItem Header="_File">
                <MenuItem Header="_Open" Click="OpenMenuItem_Click"/>
                <MenuItem Header="_Save" Click="SaveMenuItem_Click"/>
                <MenuItem Header="_Exit" Click="ExitMenuItem_Click"/>
            </MenuItem>
            <MenuItem Header="_Filter">
                <MenuItem Header="_Gaussian Blur" Click="GaussianBlurMenuItem_Click"/>
                <MenuItem Header="_Canny Edge Detection" Click="CannyEdgeMenuItem_Click"/>
            </MenuItem>
        </Menu>
        <Image x:Name="imageView" Stretch="Uniform" Grid.Row="1"/>
    </Grid>
</Window>

MainWindow.xaml.cs

using Microsoft.Win32;
using System.Windows;
using OpenCvSharp;
using OpenCvSharp.WpfExtensions;

namespace WpfApp
{
    public partial class MainWindow : System.Windows.Window
    {
        private Mat originalImage;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void OpenMenuItem_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "Image Files (*.jpg;*.jpeg;*.png;*.bmp)|*.jpg;*.jpeg;*.png;*.bmp|All files (*.*)|*.*";
            if (openFileDialog.ShowDialog() == true)
            {
                originalImage = Cv2.ImRead(openFileDialog.FileName, ImreadModes.Color);
                imageView.Source = originalImage.ToBitmapSource();
            }
        }

        private void SaveMenuItem_Click(object sender, RoutedEventArgs e)
        {
            if (originalImage != null)
            {
                SaveFileDialog saveFileDialog = new SaveFileDialog();
                saveFileDialog.Filter = "PNG (*.png)|*.png|JPEG (*.jpg;*.jpeg)|*.jpg;*.jpeg|Bitmap (*.bmp)|*.bmp";
                if (saveFileDialog.ShowDialog() == true)
                {
                    string filePath = saveFileDialog.FileName;
                    originalImage.SaveImage(filePath);
                }
            }
            else
            {
                MessageBox.Show("Please open an image first.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void ExitMenuItem_Click(object sender, RoutedEventArgs e)
        {
            Application.Current.Shutdown();
        }

        private void ApplyFilter(ImageFilter.FilterType filterType)
        {
            if (originalImage != null)
            {
                Mat filteredImage = ImageFilter.ApplyFilter(originalImage, filterType);
                imageView.Source = filteredImage.ToBitmapSource();
            }
            else
            {
                MessageBox.Show("Please open an image first.", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void GaussianBlurMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ApplyFilter(ImageFilter.FilterType.GaussianBlur);
        }

        private void CannyEdgeMenuItem_Click(object sender, RoutedEventArgs e)
        {
            ApplyFilter(ImageFilter.FilterType.CannyEdgeDetection);
        }
    }
}

MainWindow.xaml.csは1行を修正します。ChatGPTが生成した以下の行はnamespaceが曖昧です。

public partial class MainWindow : Window

このコードに対し、Visual Studio がエラーメッセージを出力します。カーソルをWindowの位置へ移動すると、修正の案内が表示されますので、以下のように修正します。

public partial class MainWindow : System.Windows.Window

この修正はChatGPTへnamespaceが曖昧だよと指摘すると、ChatGPTがnamespaceを明示したソースコードを示す場合もあります。


たった1箇所を変更しただけで、OpenCVSharpを使いフィルター処理を行う本格的なプログラムが完成します。

ビルド&実行

このプログラムをビルド&実行し、メニューから対象画像を選びます。

メニューからフィルター処理を選びます。

処理結果を保存する機能も追加されました。

このプログラムは、保存機能やフィルター処理をひとつのクラスにまとめましたので、新規の機能を追加するのは簡単になりました。ほんの数分で、このようなプログラムをChatGPTを利用すると開発できます。

このあとで、画像表示のBindingやMVVMへの変更も行ってみましたが、比較的簡単に変更できました。ただ、ある程度、言語、ライブラリ、画像処理の知識がないと難しい部分も感じます。

ChatGPT 3.5を利用しました。