效果
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/3f65df4812cc4ec69c0f7f9c66060e74~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp)
项目
![](https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/5919a3bfacdc4b55951f412e832fb078~tplv-k3u1fbpfcp-jj-mark:3024:0:0:0:q75.awebp)
参考
代码
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<rType>(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)
/// <summary>
/// 计算并生成绘制直方图
/// </summary>
/// <param name="src">待统计的图像</param>
/// <param name="hist">直方图结果</param>
/// <param name="histImage">直方图的绘制结果</param>
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
{
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)))
}
}
/// <summary>
/// 绘制直方图
/// </summary>
/// <param name="histImage">直方图绘制结果</param>
/// <param name="histSize">直方图数组大小</param>
/// <param name="color">线的颜色</param>
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
{
var pt1 = new Point2d(binW * (i - 1), histImage.Height - Math.Round(hist.At<float>(i - 1)))
var pt2 = new Point2d(binW * (i), histImage.Height - Math.Round(hist.At<float>(i)))
Cv2.Line(histImage, (OpenCvSharp.Point)pt1, (OpenCvSharp.Point)pt2, color, 1, LineTypes.AntiAlias)
}
}
/// <summary>
/// Gamma矫正
/// </summary>
/// <param name="src"></param>
/// <param name="gamma"></param>
/// <returns></returns>
private Mat GammaCorrection(Mat src, double gamma)
{
var lookUpTable = new Mat(new OpenCvSharp.Size(1, 256), MatType.CV_8U)
for (int i = 0
{
lookUpTable.Set<byte>(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)
}
/// <summary>
/// alpha
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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()
}
/// <summary>
/// beta
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void trackBar2_Scroll(object sender, EventArgs e)
{
beta = trackBar2.Value - 255
textBox2.Text = beta.ToString()
if (pictureBox1.Image == null) return
OnChange()
}
/// <summary>
/// gamma
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
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下载