RGB三通道图像直方图
一、程序
private void uiButton5_Click(object sender, EventArgs e)
{
//1: 计算直方图
Mat[] mats = Cv2.Split(src_img); //分割图像(把三通道分割为3个单通道)
Mat hist_B = new Mat();
Mat hist_G = new Mat();
Mat hist_R = new Mat();
int[] channels0 = { 0 };
int[] channels1 = { 1 };
int[] channels2 = { 2 };
int[] histSize = { 256 };
Rangef[] rangefs = new Rangef[]
{
new Rangef(0, 256),
};
Cv2.CalcHist(mats, channels0, new Mat(), hist_B, 1, histSize, rangefs, true, false);
Cv2.CalcHist(mats, channels1, new Mat(), hist_G, 1, histSize, rangefs, true, false);
Cv2.CalcHist(mats, channels2, new Mat(), hist_R, 1, histSize, rangefs, true, false);
int high = 400;
int width = 512;
int bin_w = width / 256;//每个bins的宽度 画布的宽度除以bins的个数
Mat histImage = new Mat(width, high, MatType.CV_8UC3, new Scalar(0, 0, 0)); //定义一个Mat对象,相当于一个画布
//归一化,像素值有可能数据量很大,压缩一下。是范围在定义画布的范围内。
Cv2.Normalize(hist_B, hist_B, 0, histImage.Rows, NormTypes.MinMax, -1, null);
Cv2.Normalize(hist_G, hist_G, 0, histImage.Rows, NormTypes.MinMax, -1, null);
Cv2.Normalize(hist_R, hist_R, 0, histImage.Rows, NormTypes.MinMax, -1, null);
//绘制直方图
for (int i = 1; i < 256; i++)//遍历直方图的级数
{
//B 画线,一条线有两个点组成。首先确定每个点的坐标(x,y) .遍历从1开始。0 ~ 1 两个点组成一条线,依次类推。
Cv2.Line(histImage, new OpenCvSharp.Point(bin_w * (i - 1), high - Math.Round(hist_B.At<float>(i - 1))), new OpenCvSharp.Point(bin_w * (i - 1), high - Math.Round(hist_B.At<float>(i))), new Scalar(255, 0, 0), 1, LineTypes.AntiAlias);
//G
Cv2.Line(histImage, new OpenCvSharp.Point(bin_w * (i - 1), high - Math.Round(hist_G.At<float>(i - 1))), new OpenCvSharp.Point(bin_w * (i - 1), high - Math.Round(hist_G.At<float>(i))), new Scalar(0, 255, 0), 1, LineTypes.AntiAlias);
//R
Cv2.Line(histImage, new OpenCvSharp.Point(bin_w * (i - 1), high - Math.Round(hist_R.At<float>(i - 1))), new OpenCvSharp.Point(bin_w * (i - 1), high - Math.Round(hist_R.At<float>(i))), new Scalar(0, 0, 255), 1, LineTypes.AntiAlias);
}
pictureBox1.Image = histImage.ToBitmap();
}
二、资料
「haixin-561」博客:
https://blog.csdn.net/weixin_41049188/article/details/93401792
网友评论