C#

【C#】Chartを使ったヒストグラム表示

Chartコントロールを使いたかった理由の一つに画像処理ではおなじみのヒストグラムをChartコントロールで表示したかったのですが、その簡単なプログラムです。

 

フォームにはChartコントロールを配置し、Chartの名前がchart1とした事を前提として、

// /////////////////////////////////////////////////////
// Chartコントロール内のグラフ、凡例、目盛り領域を削除
chart1.Series.Clear();
chart1.Legends.Clear();
chart1.ChartAreas.Clear();

// /////////////////////////////////////////////////////
// 目盛り領域の設定
var ca = chart1.ChartAreas.Add("Histogram");

// X軸
ca.AxisX.Title = "Brightness";  // タイトル
ca.AxisX.Minimum = 0;           // 最小値
ca.AxisX.Maximum = 256;         // 最大値
ca.AxisX.Interval = 64;         // 目盛りの間隔
// Y軸
ca.AxisY.Title = "Count";
ca.AxisY.Minimum = 0;

// /////////////////////////////////////////////////////
// データの追加
var hist = new Point[] {
    new Point(32, 10),
    new Point(96, 30),
    new Point(160, 50),
    new Point(224, 20)
};

// グラフの系列を追加
var s = chart1.Series.Add("Histogram");
// 棒グラフの隙間を無くす
s.SetCustomProperty("PointWidth", "1.0");
// データ設定
for (int i = 0; i < hist.Length; i++) {
    s.Points.AddXY(hist[i].X, hist[i].Y);
}

と書くだけで、モノクロ画像用のヒストグラムが簡単に作成できます。

 

(実行結果)

C# Chart Histogram

 

ここでのポイントとしては、棒グラフ(ChartTypeColumn)の時に、棒グラフの間隔を無くすにはPointWidthプロパティを1.0にすればよい(デフォルトは0.8)のですが、各グラフ特有のプロパティ設定は以下のように設定する必要があります。

(直接プロパティの設定ができません。)

// 棒グラフの隙間を無くす
s.SetCustomProperty("PointWidth", "1.0");

モノクロ画像の時はこれでもよいのですが、カラーだと、R,G,Bの3つのグラフを書かないといけないので、折れ線では表現しにくいので、折れ線(ChartTypeLine)を使ってみたいと思います。

 

要領は同じで、SeriesにR,G,B用の3つを追加することぐらいです。

// /////////////////////////////////////////////////////
// Chartコントロール内のグラフ、凡例、目盛り領域を削除
chart1.Series.Clear();
chart1.Legends.Clear();
chart1.ChartAreas.Clear();

// /////////////////////////////////////////////////////
// 目盛り領域の設定
var ca = chart1.ChartAreas.Add("Histogram");

// X軸
ca.AxisX.Title = "Brightness";  // タイトル
ca.AxisX.Minimum = 0;           // 最小値
ca.AxisX.Maximum = 256;         // 最大値
ca.AxisX.Interval = 64;         // 目盛りの間隔
// Y軸
ca.AxisY.Title = "Count";
ca.AxisY.Minimum = 0;

// /////////////////////////////////////////////////////
// データの追加
var histR = new Point[] {
    new Point(0, 10),
    new Point(63, 30),
    new Point(127, 80),
    new Point(191, 30),
    new Point(255, 15)
};
var histG = new Point[] {
    new Point(0, 70),
    new Point(63, 60),
    new Point(127, 40),
    new Point(191, 20),
    new Point(255, 10)
};
var histB = new Point[] {
    new Point(0, 10),
    new Point(63, 20),
    new Point(127, 30),
    new Point(191, 70),
    new Point(255, 90)
};

// グラフの系列を追加
var sR = chart1.Series.Add("HistogramR");
var sG = chart1.Series.Add("HistogramG");
var sB = chart1.Series.Add("HistogramB");

// グラフの種類を折れ線に設定する
sR.ChartType = sG.ChartType = sB.ChartType 
    = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.Line;

// データ設定
for (int i = 0; i < histR.Length; i++)
{
    sR.Points.AddXY(histR[i].X, histR[i].Y);
    sG.Points.AddXY(histG[i].X, histG[i].Y);
    sB.Points.AddXY(histB[i].X, histB[i].Y);
}

(実行結果)

C# Chart Histogram

 

これでカラーのヒストグラムも表示できる事ができます!

とか言っても、見た目があまりにもショボイので、もう少し手を入れます。

 

今度はグラフの種類にスプライン面グラフ(SeriesChartType.SplineArea)を使ってみます。

// /////////////////////////////////////////////////////
// Chartコントロール内のグラフ、凡例、目盛り領域を削除
chart1.Series.Clear();
chart1.Legends.Clear();
chart1.ChartAreas.Clear();

// /////////////////////////////////////////////////////
// 目盛り領域の設定
var ca = chart1.ChartAreas.Add("Histogram");

// X軸
ca.AxisX.Title = "Brightness";  // タイトル
ca.AxisX.Minimum = 0;           // 最小値
ca.AxisX.Maximum = 256;         // 最大値
ca.AxisX.Interval = 64;         // 目盛りの間隔
// Y軸
ca.AxisY.Title = "Count";
ca.AxisY.Minimum = 0;

// /////////////////////////////////////////////////////
// データの追加
var histR = new Point[] {
    new Point(0, 10),
    new Point(63, 30),
    new Point(127, 80),
    new Point(191, 30),
    new Point(255, 15)
};
var histG = new Point[] {
    new Point(0, 70),
    new Point(63, 60),
    new Point(127, 40),
    new Point(191, 20),
    new Point(255, 10)
};
var histB = new Point[] {
    new Point(0, 10),
    new Point(63, 20),
    new Point(127, 30),
    new Point(191, 70),
    new Point(255, 90)
};

// グラフの系列を追加
var sR = chart1.Series.Add("HistogramR");
var sG = chart1.Series.Add("HistogramG");
var sB = chart1.Series.Add("HistogramB");

// グラフの種類をスプライン面グラフに設定する
sR.ChartType = sG.ChartType = sB.ChartType
    = System.Windows.Forms.DataVisualization.Charting.SeriesChartType.SplineArea;

// 輪郭線の太さ
sR.BorderWidth = sG.BorderWidth = sB.BorderWidth = 2;

// 輪郭線の色
sR.BorderColor = Color.Red;
sG.BorderColor = Color.Green;
sB.BorderColor = Color.Blue;

// 塗りつぶしの色の設定(半透明)
sR.Color = Color.FromArgb(150, Color.Red);
sG.Color = Color.FromArgb(150, Color.Green);
sB.Color = Color.FromArgb(150, Color.Blue);

// データ設定
for (int i = 0; i < histR.Length; i++)
{
    sR.Points.AddXY(histR[i].X, histR[i].Y);
    sG.Points.AddXY(histG[i].X, histG[i].Y);
    sB.Points.AddXY(histB[i].X, histB[i].Y);
}

(実行結果)

C# Chart Histogram

 

これで、かなりそれっぽくないですか?

プログラム的に書くと、塗りつぶしの色に半透明の色を設定できるところがポイントでしょうかね。

 

Chartコントロールの使用方法へ戻る

コメント

タイトルとURLをコピーしました