2020-09-20 OpenCVSharp4で画像に等高線を描く OpenCVSharp 画像処理 ゲームをやっていたら等高線を書きたくなったので。。。 方法 画像の正規化 画像の階調を粗くする 階調を荒くした画像でエッジ検出 階調を荒くした画像にエッジを上描き 等高線画像の表示 プログラム using System; using OpenCvSharp; namespace 等高線 { class Program { static void Main(string[] args) { //ガウス関数を作成 float[,] wave = new float[500, 500]; for(int i = 0; i < 500; i++) { for(int j =0; j < 500; j++) { double r = Math.Sqrt(i * i + 2 * j * j); wave[i, j] = (float)Math.Pow(Math.E, -r * r / 150000); } } Mat src = new Mat(500, 500, MatType.CV_32FC1, wave); //①0~255に正規化して、MatTypeをCV_8UC1に変更 Cv2.Normalize(src, src, 0, 255, NormTypes.MinMax); src.ConvertTo(src, MatType.CV_8UC1); Cv2.ImShow("src", src); src.ImWrite(@"D:\src1.png"); //⑤画像の表示 Mat dst = drawContourLine(src, 20, Scalar.Brown, ColormapTypes.Pink); Cv2.ImShow("dst", dst); dst.ImWrite(@"D:\dst1.png"); Cv2.WaitKey(); } static Mat drawContourLine(Mat src, int contourNum,Scalar contourColor, ColormapTypes? colormapTypes = ColormapTypes.Hot) { //②等高線の数から、等高線の高さを計算 int step = 256 / contourNum; //②階調変換用のヒストグラムを作成 byte[] lut = new byte[256]; for(int i = 0; i < lut.Length; i++) { lut[i] = (byte)(Math.Floor((double)i / step) * step); } Console.WriteLine(Scalar.White); //②階調を粗くする Mat roughGrad = new Mat(); Cv2.LUT(src, lut, roughGrad); //③階調を荒くした画像のエッジ検出 Mat contour = new Mat(); Cv2.Canny(roughGrad, contour, 1, step - 1); //④カラーマップに変更 if(colormapTypes == null) { return contour; } else { Cv2.ApplyColorMap(roughGrad, roughGrad, (ColormapTypes)colormapTypes); for(int j = 0; j < contour.Rows; j++) { for(int i = 0; i < contour.Cols; i++) { if(contour.At<char>(j, i) > 0) roughGrad.Set<Vec3b>(j, i, new Vec3b((byte)contourColor[0], (byte)contourColor[1], (byte)contourColor[2])); } } } return roughGrad; } } } C# 結果 入力画像 出力画像