参考
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();
}
Mat src;//源图
double alpha = 0;
double beta = 0;
double gamma = 0;
double maxVal = -1;//源图最多像素点个数
Mat new_Image1;
Mat new_Image2;
Mat dst;
Mat hist;
Mat histImg;
private void OnChange()
{
//初始化所有值都为0的矩阵
new_Image1 = Mat.Zeros(src.Size(), src.Type());
new_Image2 = Mat.Zeros(src.Size(), src.Type());
//m:转换类型后的输出的图像;rtype转换图像的数据类型;alpha:转换过程中的缩放因子;beta:转换过程中的偏置因子
//m(x,y)=saturate_cast(alpha*(*this)(x,y)+beta);
src.ConvertTo(new_Image2, src.Type(), alpha, beta);
GetHistResult(new_Image2, out hist, out histImg);
if (pictureBox2.Image != null)
{
pictureBox2.Image.Dispose();
}
pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(histImg);
if (pictureBox3.Image != null)
{
pictureBox3.Image.Dispose();
}
pictureBox3.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(new_Image2);
}
const int histW = 512;
const int histH = 400;
int histSize = 256;//直方图数组大小
Rangef range = new Rangef(0, 256);//统计0至255(=266-1)
///
/// 计算并生成绘制直方图
///
/// 待统计的图像
/// 直方图结果
/// 直方图的绘制结果
private void GetHistResult(Mat src, out Mat hist, out Mat histImage)
{
hist = new Mat();
histImage = new Mat(histH, histW, MatType.CV_8UC3, Scalar.All(0));
//将图像像素灰度[0,255]共分为histSize个等级统计,
for (int channel = 0; channel < src.Channels(); channel++)
{
Cv2.CalcHist(images: new[] { src },//待统计的图像
channels: new[] { channel },//待统计的通道
mask: null,//掩膜
hist: hist,//输出的统计结果
dims: 1,//直方图维度
histSize: new[] { histSize },//将range分为histSize梯度
ranges: new[] { range });//待统计通道像素的范围,不在这个范围内的不统计
DrawHist(histImage, hist, (channel == 0 ? Scalar.Blue : (channel == 1 ? Scalar.Green : Scalar.Red)));
}
}
///
/// 绘制直方图
///
/// 直方图绘制结果
/// 直方图数组大小
/// 线的颜色
private void DrawHist(Mat histImage, Mat hist, Scalar color)
{
var binW = Math.Round((double)histImage.Width / hist.Height);
if (maxVal > 0)
{
//截断超过源图最大值的像素大数(防止饱和像素过多)
Cv2.Threshold(hist, hist, maxVal, maxVal, ThresholdTypes.Trunc);
}
//归一化
Cv2.Normalize(hist, hist, 0, histImage.Rows, NormTypes.MinMax, -1);
for (int i = 1; i < hist.Height; i++)
{
var pt1 = new Point2d(binW * (i - 1), histImage.Height - Math.Round(hist.At(i - 1)));
var pt2 = new Point2d(binW * (i), histImage.Height - Math.Round(hist.At(i)));
Cv2.Line(histImage, (OpenCvSharp.Point)pt1, (OpenCvSharp.Point)pt2, color, 1, LineTypes.AntiAlias);
}
}
///
/// Gamma矫正
///
///
///
///
private Mat GammaCorrection(Mat src, double gamma)
{
var lookUpTable = new Mat(new OpenCvSharp.Size(1, 256), MatType.CV_8U);
for (int i = 0; i < 256; i++)
{
lookUpTable.Set(0, i, Convert.ToByte(Math.Pow(i / 255.0D, gamma) * 255.0D));
}
Mat dst = new Mat();
//查表法,性能优化
Cv2.LUT(src, lookUpTable, dst);
return dst;
}
private void gammaOnChange()
{
dst = GammaCorrection(src, gamma);
GetHistResult(dst, out hist, out histImg);
if (pictureBox2.Image != null)
{
pictureBox2.Image.Dispose();
}
pictureBox2.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(histImg);
if (pictureBox3.Image != null)
{
pictureBox3.Image.Dispose();
}
pictureBox3.Image = OpenCvSharp.Extensions.BitmapConverter.ToBitmap(dst);
}
private void PutText(Mat src, string text)
{
PutText(src, text, new OpenCvSharp.Point(10, 20));
}
private void PutText(Mat src, string text, OpenCvSharp.Point point)
{
Cv2.PutText(src, text, point, HersheyFonts.HersheySimplex, 2, Scalar.Red);
}
string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tiff;*.png";
string imgPath = "";
private void button2_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);
src = new Mat(imgPath);
}
///
/// alpha
///
///
///
private void trackBar1_Scroll(object sender, EventArgs e)
{
alpha = trackBar1.Value / 100.0D;
textBox1.Text = alpha.ToString("0.00");
if (pictureBox1.Image == null) return;
OnChange();
}
///
/// beta
///
///
///
private void trackBar2_Scroll(object sender, EventArgs e)
{
beta = trackBar2.Value - 255;
textBox2.Text = beta.ToString();
if (pictureBox1.Image == null) return;
OnChange();
}
///
/// gamma
///
///
///
private void trackBar3_Scroll(object sender, EventArgs e)
{
gamma = trackBar3.Value / 100.0D;
textBox3.Text = gamma.ToString("0.00");
if (pictureBox1.Image == null) return;
gammaOnChange();
}
}
}
Demo下载