C# OpenCvSharp 直方图均衡化 图像去雾
  yqdtHKhvd9Ja 2023年11月02日 77 0


直方图

直方图均衡化

自适应的直方图均衡化

全局直方图均衡化

局部直方图均衡化

对比度调整

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using OpenCvSharp;

namespace OpenCvSharp_图像去雾
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
        string imgPath = "";

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() != DialogResult.OK) return;
            pictureBox1.Image = null;
            imgPath = ofd.FileName;
            pictureBox1.Image = new Bitmap(imgPath);
        }

        /// <summary>
        /// 直方图均衡化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button2_Click(object sender, EventArgs e)
        {
            if (imgPath == "") return;
            Mat mat = Cv2.ImRead(imgPath, ImreadModes.Grayscale);
            Cv2.EqualizeHist(mat, mat);
            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
        }

        /// <summary>
        /// 自适应的直方图均衡化
        /// 将整幅图像分成很多小块,然后再对每一个小块分别进行直方图均衡化,最后进行拼接
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button3_Click(object sender, EventArgs e)
        {
            if (imgPath == "") return;
            Mat mat = Cv2.ImRead(imgPath, ImreadModes.Grayscale);
            CLAHE clahe = Cv2.CreateCLAHE(10.0, new OpenCvSharp.Size(8, 8));
            clahe.Apply(mat, mat);
            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
        }

        /// <summary>
        /// 全局直方图处理
        /// 全局直方图处理通过对 RGB 图像的 R、G、B 三层通道分别进行直方图均衡化,再整合到新的图像的方式进行。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button4_Click(object sender, EventArgs e)
        {
            if (imgPath == "") return;
            Mat mat = Cv2.ImRead(imgPath);
            Mat[] mats = Cv2.Split(mat);//拆分
            //Mat mats0 =  mats[0];//B
            //Mat mats1 =  mats[1];//G
            //Mat mats2 =  mats[2];//R

            Cv2.EqualizeHist(mats[0], mats[0]);
            Cv2.EqualizeHist(mats[1], mats[1]);
            Cv2.EqualizeHist(mats[2], mats[2]);

            Cv2.Merge(new Mat[] { mats[0], mats[1], mats[2] }, mat);

            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
        }

        /// <summary>
        ///  局部直方图处理
        ///  即自适应直方图均衡化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button5_Click(object sender, EventArgs e)
        {
            if (imgPath == "") return;
            CLAHE clahe = Cv2.CreateCLAHE(6.0, new OpenCvSharp.Size(8, 8));
            Mat mat = Cv2.ImRead(imgPath);
            Mat[] mats = Cv2.Split(mat);//拆分
            clahe.Apply(mats[0], mats[0]);//B
            clahe.Apply(mats[1], mats[1]);//G
            clahe.Apply(mats[2], mats[2]);//R

            Cv2.Merge(new Mat[] { mats[0], mats[1], mats[2] }, mat);

            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(mat);
        }

        /// <summary>
        /// 直方图
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button6_Click(object sender, EventArgs e)
        {
            if (imgPath == "") return;
            Mat lena = Cv2.ImRead(imgPath);
            Mat[] mats = Cv2.Split(lena);//一张图片,将lena拆分成3个图片装进mat
            Mat[] mats0 = new Mat[] { mats[0] };//B
            Mat[] mats1 = new Mat[] { mats[1] };//G
            Mat[] mats2 = new Mat[] { mats[2] };//R
            Mat[] hist = new Mat[] { new Mat(), new Mat(), new Mat() };//一个矩阵数组,用来接收直方图,记得全部初始化
            int[] channels = new int[] { 0 };//一个通道,初始化为通道0
            int[] histsize = new int[] { 256 };//初始化为256箱子
            Rangef[] range = new Rangef[1];//一个通道,范围
            range[0] = new Rangef(0, 256);//从0开始(含),到256结束(不含)
            Mat mask = new Mat();//不做掩码
            Cv2.CalcHist(mats0, channels, mask, hist[0], 1, histsize, range);//对被拆分的图片单独进行计算
            Cv2.CalcHist(mats1, channels, mask, hist[1], 1, histsize, range);//对被拆分的图片单独进行计算
            Cv2.CalcHist(mats2, channels, mask, hist[2], 1, histsize, range);//对被拆分的图片单独进行计算
            Cv2.Normalize(hist[0], hist[0], 0, 256, NormTypes.MinMax);// 归一化
            Cv2.Normalize(hist[1], hist[1], 0, 256, NormTypes.MinMax);// 归一化
            Cv2.Normalize(hist[2], hist[2], 0, 256, NormTypes.MinMax);// 归一化

            double minVal0, maxVal0;
            Cv2.MinMaxLoc(hist[0], out minVal0, out maxVal0);
            double minVal1, maxVal1;
            Cv2.MinMaxLoc(hist[1], out minVal1, out maxVal1);
            double minVal2, maxVal2;
            Cv2.MinMaxLoc(hist[2], out minVal2, out maxVal2);

            double minVal = Math.Min(minVal0, Math.Min(minVal1, minVal2));
            double maxVal = Math.Max(maxVal0, Math.Max(maxVal1, maxVal2));

            int height = 512;
            int width = 512;

            hist[0] = hist[0] * (maxVal != 0 ? height / maxVal : 0.0);
            hist[1] = hist[1] * (maxVal != 0 ? height / maxVal : 0.0);
            hist[2] = hist[2] * (maxVal != 0 ? height / maxVal : 0.0);

            Mat histImage = new Mat(height, width, MatType.CV_8UC3, new Scalar(100, 100, 100));
            int binW = (int)((double)width / histsize[0]);
            for (int i = 0; i < histsize[0]; i++)
            {
                histImage.Rectangle(
                                    new OpenCvSharp.Point(i * binW, histImage.Rows - (int)hist[0].Get<float>(i)),
                                    new OpenCvSharp.Point((i + 1) * binW, histImage.Rows),
                                     new Scalar(255, 0, 0),
                                    -1);

                histImage.Rectangle(
                    new OpenCvSharp.Point(i * binW, histImage.Rows - (int)hist[1].Get<float>(i)),
                    new OpenCvSharp.Point((i + 1) * binW, histImage.Rows),
                     new Scalar(0, 255, 0),
                    -1);

                histImage.Rectangle(
                    new OpenCvSharp.Point(i * binW, histImage.Rows - (int)hist[2].Get<float>(i)),
                    new OpenCvSharp.Point((i + 1) * binW, histImage.Rows),
                     new Scalar(0, 0, 255),
                    -1);
            }
            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(histImage);
            //Cv2.ImShow("hist", histImage);
        }

        /// <summary>
        /// 画面对比度调整
        /// 此处需要注意的是采用了YCrCB格式,该格式的Y通道是亮度,对其调整,实际上调整的是对比度,不会导致图片本身的失真。
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button7_Click(object sender, EventArgs e)
        {
            if (imgPath == "") return;
            Mat lena = Cv2.ImRead(imgPath, ImreadModes.Color);
            Mat yCbCR = new Mat();
            Cv2.CvtColor(lena, yCbCR, ColorConversionCodes.BGR2YCrCb);
            Mat[] channels = Cv2.Split(yCbCR);//一张图片,将lena拆分成3个图片装进mat
            Cv2.EqualizeHist(channels[0], channels[0]);
            Cv2.Merge(channels, yCbCR);
            Mat result = new Mat();
            Cv2.CvtColor(yCbCR, result, ColorConversionCodes.YCrCb2BGR);
            pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(result);
            //Cv2.ImShow("origin", lena);
            //Cv2.ImShow("EqualizeHist", result);
        }
    }
}

Demo下载

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  jJVxqmfuiDRw   2023年11月02日   61   0   0 sqli++System
  I7LiCMSIjWYz   2023年11月02日   52   0   0 人工智能区块链
yqdtHKhvd9Ja