1. 程式人生 > >C# EMGU 3.4.1學習筆記(十二)示例程式:直方圖均衡化(彩色影象)

C# EMGU 3.4.1學習筆記(十二)示例程式:直方圖均衡化(彩色影象)

本示例是《OpenCV3程式設計入門》中7.5.3中的示例程式的C# + EMGU 3.4.1版,演示瞭如何用EqualizeHist()函式進行影象的直方圖均衡化。

原書程式碼僅演示了對灰度影象的直方圖均衡化,對此我做了一些改變,從而可對彩色影象進行直方圖均衡化。

彩色影象的直方圖均衡化說明

由於opencv自帶的函式是對灰度影象進行直方圖均衡化的,所以在需要對彩色影象進行直方圖均衡化時,不可直接呼叫函式。另外需要注意的是,對於彩色影象(RGB),直接對三個通道單獨進行直方圖均衡化,然後合成是不可取的,原因是直方圖均衡化並非線性操作,這樣會引起顏色失真。

可行的方式是將RGB轉換到HSV,HSI,YUV 或者YCrCb顏色空間,然後對亮度(即前面的V,I,Y)通道進行均衡化,這樣不會對彩色的色調產生影響,最後再轉換回RGB空間即可。特別推薦YCrCb顏色空間,因為它就是專門為數字影象所設計的。

彩色影象的直方圖均衡化程式程式碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Util;

namespace EqualizeHist
{
    class Program
    {
        static void Main(string[] args)
        {
            //【1】載入並顯示源影象
            Mat srcImage = CvInvoke.Imread("star.jpg");
            CvInvoke.Imshow("Source Image", srcImage); //顯示源影象

            //【2】將srcImage轉換到YCrCb顏色空間
            Mat yccImage = new Mat(); //定義yccImage變數,儲存轉化後的圖
            CvInvoke.CvtColor(srcImage, yccImage, ColorConversion.Bgr2YCrCb); //顏色空間轉化

            //【3】分離yccImage,以便對其亮度通道(Y通道)應用直方圖均衡化
            VectorOfMat channels = new VectorOfMat(); //定義channels儲存split後的各通道影象
            CvInvoke.Split(yccImage, channels); //呼叫Split函式,分離yccImage顏色通道
            CvInvoke.EqualizeHist(channels[0], channels[0]); //對Y通道進行直方圖均衡化

            //【4】轉換回Bgr顏色空間,並顯示結果圖
            CvInvoke.Merge(channels, yccImage); //合併所有通道,重新生成yccImage
            Mat dstImage = new Mat(); //定義儲存結果的Mat變數
            CvInvoke.CvtColor(yccImage, dstImage, ColorConversion.YCrCb2Bgr); //從YCrCb轉回Bgr顏色空間

            //【5】顯示結果圖
            CvInvoke.Imshow("Destination Image", dstImage);

            //等待使用者按鍵退出程式
            CvInvoke.WaitKey(0);
        }
    }
}

程式執行截圖如下: