1. 程式人生 > 程式設計 >OpenCvSharp影象的修改和儲存以及掩膜操作

OpenCvSharp影象的修改和儲存以及掩膜操作

一 :影象的顏色空間轉換

在OpenCvSharp中顏色轉換函式為:Cv2.CvtColor()

引數:

引數 說明
src: 源影象,8位無符號,16位無符號或單精度浮點
dst: 輸出影象,具有與src相同的大小和深度
code: 顏色空間轉換程式碼:(ColorConversionCodes)列舉型別

程式碼:

static void Main(string[] args)
    {
      Mat src = new Mat(@"C:\Users\whx\Desktop\opcvImage\s1.jpg ",ImreadModes.Color);

      if (src == null) //上面的載入方式如果找不到指定的檔案也會報錯
      {
        Console.WriteLine("載入影象失敗");
        return;
      }

      Mat outImage = new Mat(); //宣告一個容器,裝載改變後的影象

      //引數:1 原圖矩陣容器 2:儲存影象的矩陣容器 3:顏色轉換通道(很多,查手冊)
      Cv2.CvtColor(src,outImage,ColorConversionCodes.RGB2GRAY); //轉為灰度空間影象,

      //引數:1 要儲存圖片的路徑 2:影象的矩陣容器 ,(圖片儲存格式個根據自定義的字尾名)
      Cv2.ImWrite(@"C:\Users\whx\Desktop\out.png",outImage);//儲存到桌面

      using (new Window("src",WindowMode.Normal,src))
      using (new Window("out",outImage))
      {
        Cv2.WaitKey();
      }
    }

OpenCvSharp影象的修改和儲存以及掩膜操作

左邊是源影象,右邊是轉為灰度空間的影象,儲存路徑在桌面。
轉為灰度空間的型別在 OpenCvSharp 中的 ColorConversionCodes.RGB2GRAY 與 ColorConversionCodes.BRR2GRAY 都能實現,OpenCvSharp 載入進來的影象是哪一種?

程式碼

static void Main(string[] args)
    {
      #region 
      //自定義一張全紅色的圖片
      Mat src = new Mat(100,100,MatType.CV_8UC3,new Scalar(0,255));
      Vec3b vec3B = new Vec3b();
      //獲取第一個畫素的三通道畫素值
      vec3B.Item0 = src.At<Vec3b>(0,0)[0];
      vec3B.Item1 = src.At<Vec3b>(0,0)[1];
      vec3B.Item2 = src.At<Vec3b>(0,0)[2];
      Console.WriteLine("0 :"+vec3B.Item0); //控制檯輸出
      Console.WriteLine("1 :"+vec3B.Item1);
      Console.WriteLine("2 :"+vec3B.Item2);

      using (new Window("src image",WindowMode.FreeRatio,src)) //建立一個新視窗顯示影象
      {
        Cv2.WaitKey();
      }
      #endregion

    }

在這裡插入圖片描述

根據輸出畫素值(0,0,255)可以看出 OpenCvSharp 三通道畫素值排列為:BGR

二: 掩膜操作,提高影象對比度

使用Cv2.Filter2D函式:

引數 說明
src: 輸入的源影象
dst: 輸出影象,一個Mat 物件,與原圖影象具有相同的大小和影象深度
ddepth: 目標影象的所需深度。如果它是負的,它就是與src.depth()相同,不確定時就填 -1
kernel: 卷積核
anchor: 核心的錨點,表示經過過濾的點的相對位置. (- 1,-1)表示錨位於核心中心
delta: 在卷積過程中,該值會加到每個畫素上。預設情況下,這個值為 0 。相當於一個增益值
borderType: 指定邊緣處理的方法,比較複雜,選擇預設值即可。是列舉型別

程式碼:

 static void Main(string[] args)
    {
      using (Mat src = new Mat(@"C:\Users\whx\Desktop\opcvImage\m4.jpg",ImreadModes.AnyColor | ImreadModes.AnyDepth))
      using (Mat dst = new Mat())
      {
        //定義一個掩膜矩陣
        InputArray kernel = InputArray.Create<int>(new int[3,3] { { 0,-1,0 },{ -1,5,-1 },{ 0,0 } });

        //進行掩膜操作,提高圖片亮度
        Cv2.Filter2D(src,dst,kernel,new Point(-1,1),BorderTypes.Default);

        using (new Window("OutputImage",dst))
        using (new Window("InputImage",src))
        {
          Cv2.WaitKey(0);
        }
      }
    }

在這裡插入圖片描述

從上圖可以看出,OutputImage 比 Inputimage 的亮度明顯增強。

三:利用指標修改影象畫素值,進行影象對比度處理

程式碼:

unsafe static void Main(string[] args)
    {
      Mat src,dst;
      src = Cv2.ImRead(@"C:\Users\whx\Desktop\opcvImage\m4.jpg"); //讀取圖片
      if (src.Data == null)
      {
        Console.WriteLine("載入影象失敗");
        return;
      }
      #region 
      /*
       * 兩種判斷方法都可以
       */

      //if(src.Empty()) //如果陣列沒有元素,則返回true。
      //{
      //  Console.WriteLine("載入影象失敗");
      //  return;
      //}

      //顯示方式2
      //new Window("Input Image",WindowMode.FreeRatio);
      //Cv2.ImShow("Input Image",src);
      //Cv2.WaitKey(0); 
      #endregion

      #region 指標操作增加飽和度
      int clos = (src.Cols - 1) * src.Channels(); //RGB有三個通道,(影象的列(長度) * 影象的通道數)
      int rows = src.Rows; //行(高度)
      int offsetx = src.Channels();

      dst = new Mat(src.Size(),src.Type()); //初始化

      for (int row = 1; row < rows - 1; row++)
      {
        IntPtr current = src.Ptr(row); //當前行
        byte* curr = (byte*)current.ToPointer();

        IntPtr upRow = src.Ptr(row - 1);//上一行
        byte* up = (byte*)upRow.ToPointer();

        IntPtr nextRow = src.Ptr(row + 1);//下一行
        byte* next = (byte*)nextRow.ToPointer();

        IntPtr outPut = dst.Ptr(row); //輸出
        byte* opt = (byte*)outPut.ToPointer();

        for (int col = offsetx; col < clos; col++)
        {
          opt[col] = (byte)Saturate.Saturate_cast((5 * curr[col] - (curr[col - offsetx] + curr[col + offsetx] + up[col] + next[col])));
        }
      }
      #endregion

      
      using (new Window("OutputImage",dst))
      using (new Window("InputImage",src))
      {
        Cv2.WaitKey(0);
      }
    }
unsafe static void Main(string[] args)
    {
      Mat src,src))
      {
        Cv2.WaitKey(0);
      }
    }

在這裡插入圖片描述

效果與上面使用API操作基本一致。這裡是由一個計算公式:

在這裡插入圖片描述

對應這行程式碼:

 opt[col] = (byte)Saturate.Saturate_cast((5 * curr[col] - (curr[col - offsetx] + curr[col + offsetx] + up[col] + next[col])));

四:減少影象亮度

程式碼:

static void Main(string[] args)
    {
      Mat src,dst;
      src = Cv2.ImRead(@"C:\Users\whx\Desktop\opcvImage\m4.jpg"); //讀取圖片
      dst = new Mat(src.Size(),src.Type()); //初始化
      src.CopyTo(dst); //把原影象拷貝到 dst 中
      for (int i = 0; i < src.Rows; i++)
      {
        for (int j = 0; j < src.Cols; j++)
        {
          Vec3b color = new Vec3b();//新建Vec3b物件(位元組的三元組(System.Byte))
          color.Item0 = (byte)Saturate.Saturate_cast((src.Get<Vec3b>(i,j).Item0 - 50));// B 讀取原來的通道值並減50
          color.Item1 = (byte)Saturate.Saturate_cast((src.Get<Vec3b>(i,j).Item1 - 50)); // G
          color.Item2 = (byte)Saturate.Saturate_cast((src.Get<Vec3b>(i,j).Item2 - 50)); // R
          src.Set(i,j,color);
        }
      }

      using (new Window("Input",dst))
      using (new Window("Output",src))
      {
        Cv2.WaitKey(0);
      }
    }

在這裡插入圖片描述

輸出影象明顯比輸入的亮度下降。

程式碼:

static void Main(string[] args)
    {
      Mat src,j).Item0 + 50));//讀取原來的通道值並加50
          color.Item1 = (byte)Saturate.Saturate_cast((src.Get<Vec3b>(i,j).Item1 + 50));
          color.Item2 = (byte)Saturate.Saturate_cast((src.Get<Vec3b>(i,j).Item2 + 50));
          src.Set(i,color);
        }
      }
      using (new Window("Input",src))
      {
        Cv2.WaitKey(0);
      }
    }

在這裡插入圖片描述

輸出影象明顯比輸入的亮度提高很多。

到此這篇關於OpenCvSharp影象的修改和儲存以及掩膜操作的文章就介紹到這了,更多相關OpenCvSharp影象掩膜內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!