直方图
直方图均衡化
自适应的直方图均衡化
全局直方图均衡化
局部直方图均衡化
对比度调整
代码
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]
//Mat mats1 = mats[1]
//Mat mats2 = mats[2]
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])
clahe.Apply(mats[1], mats[1])
clahe.Apply(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 button6_Click(object sender, EventArgs e)
{
if (imgPath == "") return
Mat lena = Cv2.ImRead(imgPath)
Mat[] mats = Cv2.Split(lena)
Mat[] mats0 = new Mat[] { mats[0] }
Mat[] mats1 = new Mat[] { mats[1] }
Mat[] mats2 = new Mat[] { mats[2] }
Mat[] hist = new Mat[] { new Mat(), new Mat(), new Mat() }
int[] channels = new int[] { 0 }
int[] histsize = new int[] { 256 }
Rangef[] range = new Rangef[1]
range[0] = new Rangef(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
{
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)
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下载