OpenCVSharp4のエッジ強調(一次微分、Prewitt、Sobel、Laplacian、canny etc...)

OpenCVSharp4の色々な輪郭抽出フィルタを試してみた
※2020/06/08追記 正規化の方法が間違っていました。

方法

  1. VisualStudioにNuGetでOpenCVSharp4とOpenCVSharp4.runtime.winをインストール
  2. 次のプログラムを実行
using System;  
using OpenCvSharp;  

namespace 輪郭抽出 {  
    class Program {  
        static void Main(string[] args) {  
            Mat src = new Mat(@"D:\picture.png");  
            Cv2.CvtColor(src, src, ColorConversionCodes.BGR2GRAY);  

            Mat bibun = new Mat(),  
                prewitt = new Mat(),   
                sobel = new Mat(),   
                laplacian = new Mat(),   
                emboss = new Mat(),   
                canny = new Mat(),  
                roberts = new Mat();  


            //一次微分フィルタ  
            Mat bibunX = new Mat();  
            Mat bibunKernelX = new Mat(3, 3, MatType.CV_32FC1,  
                new float[,] {  
                    {  0, 0, 0 },  
                    { -1, 0, 1 },  
                    {  0, 0, 0 }  
                });  

            Mat bibunY = new Mat();  
            Mat bibunKernelY = new Mat(3, 3, MatType.CV_32FC1,  
                new float[,] {  
                    { 0, -1, 0 },  
                    { 0,  0, 0 },  
                    { 0,  1, 0 }  
                });  


            Cv2.Filter2D(src, bibunX, MatType.CV_32FC1, bibunKernelX);  
            Cv2.Filter2D(src, bibunY, MatType.CV_32FC1, bibunKernelY);  
            Cv2.Sqrt(bibunX.Pow(2) + bibunY.Pow(2), bibun);  



            //Prewitt法  
            Mat prewittX = new Mat();  
            Mat prewittKernelX = new Mat(3, 3, MatType.CV_32FC1,  
                new float[,] {  
                    { -1, 0, 1 },  
                    { -1, 0, 1 },  
                    { -1, 0, 1 }  
                });  

            Mat prewittY = new Mat();  
            Mat prewittKernelY = new Mat(3, 3, MatType.CV_32FC1,  
                new float[,] {  
                    { -1, -1, -1 },  
                    {  0,  0,  0 },  
                    {  1,  1,  1 }  
                });  

            Cv2.Filter2D(src, prewittX, MatType.CV_32FC1, prewittKernelX);  
            Cv2.Filter2D(src, prewittY, MatType.CV_32FC1, prewittKernelY);  
            Cv2.Sqrt(prewittX.Pow(2) + prewittY.Pow(2), prewitt);  


            //Sobel法  
            Mat sobelX = new Mat();  
            Cv2.Sobel(src, sobelX, MatType.CV_32FC1, 1, 0);  
            Mat sobelY = new Mat();  
            Cv2.Sobel(src, sobelY, MatType.CV_32FC1, 0, 1);  
            Cv2.Sqrt(sobelX.Pow(2) + sobelY.Pow(2), sobel);  


            //Laplacian法  
            int ksize = 3;  
            Cv2.Laplacian(src, laplacian, MatType.CV_32FC1, ksize);  


            //Emboss法  
            Mat embossKernel = new Mat(3, 3, MatType.CV_32FC1,  
                new float[,] {  
                    {-2, -1, 0},  
                    {-1,  1, 1},  
                    { 0,  1, 2}  
                });  
            Cv2.Filter2D(src, emboss, MatType.CV_32FC1, embossKernel);  


            //canny法  
            double minThresh = 100;  
            double maxThresh = 200;  
            Cv2.Canny(src, canny, minThresh, maxThresh);  


            //表示  
            Cv2.ImShow("入力画像", src);  
            Cv2.ImShow("一次微分", bibun);  
            Cv2.ImShow("Prewitt", prewitt);  
            Cv2.ImShow("Sobel", sobel);  
            Cv2.ImShow("Laplacian", laplacian);  
            Cv2.ImShow("Emboss", emboss);  
            Cv2.ImShow("Canny", canny);  

            Cv2.WaitKey();  

        }  
    }  
}