記事ディレクトリ
序文:
ヒストグラムはデジタル画像処理における強力かつ重要なツールであり、データの分布を視覚化することで画像の特性をより深く理解するのに役立ちます。この記事では、C++ と OpenCV ライブラリを使用してヒストグラムを作成するプロセスを詳しく説明し、いくつかのヒストグラム アプリケーション シナリオを紹介します。
ヒストグラムの概要:
ヒストグラムはデータの分布をグラフで表現したもので、画像内のピクセル強度の分布を分析するためによく使用されます。画像処理では、ヒストグラムは画像の明るさ、コントラスト、その他の情報を理解するのに役立ちます。 OpenCV は、画像のヒストグラムを計算するために使用される calcHist と呼ばれる関数を提供します。
関数プロトタイプ
calcHist 関数は、ヒストグラムを計算するために使用される OpenCV の関数です。関数のプロトタイプは次のとおりです。
void calcHist(const Mat* images, int nimages, const int* channels, InputArray mask, OutputArray hist, int dims, const int* histSize, const float** ranges, bool uniform = true, bool accumulate = false);
パラメータの説明:
画像: 入力画像配列。単一の画像または画像配列にすることができます。複数の画像がある場合、それらは全体として考慮され、累積ヒストグラムが形成されます。
nimages: 画像の数。入力画像配列に画像が 1 つだけ含まれている場合、値は 1 です。
チャネル: 考慮されるチャネルのインデックス。通常、グレースケール イメージの場合は [0]、カラー イメージのすべてのチャネルの場合は [0、1、2]。たとえば、グレースケール イメージを処理する場合、チャネルはグレースケール値に対応する 0 になります。カラー イメージを処理する場合、チャネルはそれぞれ青、緑、赤のチャネルに対応する [0]、[1]、[2] になります。
マスク: ヒストグラムの計算範囲を制限するために使用されるオプションのマスク画像。マスク画像内の対応する位置にある非ゼロ値を持つピクセル値のみがヒストグラムの計算に使用されます。
hist: 出力ヒストグラム。これは、計算されたヒストグラムを保持する出力配列です。
dims: ヒストグラムの次元、通常は 1。
histSize: 各次元のヒストグラム サイズ。配列として提供されます。たとえば、グレースケール イメージの場合、histSize は 256 になりますが、カラー イメージの場合、各チャネルに同じヒストグラム サイズを使用するのが一般的です。
ranges: 各次元のピクセル値の範囲。配列として提供されます。グレースケール イメージの場合、範囲は通常 [0, 256] ですが、カラー イメージの場合、各チャネルの範囲は [0, 256] になります。
uniform: ヒストグラムが均一かどうかを指定するブール値。 true の場合、ヒストグラムの各ビンは同じサイズになります。false の場合、各ビンのサイズは入力ピクセル値の範囲に従って調整されます。
累積: ヒストグラムを累積するかどうかを指定するために使用されるブール値。 true の場合、複数の画像に対してヒストグラムを計算するときにヒストグラムが累積され、false の場合、ヒストグラムはゼロにリセットされます。
コード例
#include <opencv2/opencv.hpp>
#include <opencv2/highgui/highgui.hpp>
using namespace cv;
int main() {
Mat image = imread("sample.jpg", IMREAD_GRAYSCALE); // 以灰度模式读取图像
if (image.empty()) {
std::cerr << "Error: Could not open or find the image!\n";
return -1;
}
// 定义直方图参数
int histSize = 256; // 灰度级别的数量
float range[] = {0, 256}; // 像素值范围
const float* histRange = {range};
// 计算直方图
Mat hist;
calcHist(&image, 1, 0, Mat(), hist, 1, &histSize, &histRange);
// 绘制直方图
int histWidth = 512;
int histHeight = 400;
int binWidth = cvRound((double) histWidth/histSize);
Mat histImage(histHeight, histWidth, CV_8UC3, Scalar(255, 255, 255));
// 归一化直方图数据
normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());
// 绘制直方图
for (int i = 1; i < histSize; i++) {
line(histImage, Point(binWidth * (i - 1), histHeight - cvRound(hist.at<float>(i - 1))),
Point(binWidth * (i), histHeight - cvRound(hist.at<float>(i))),
Scalar(0, 0, 255), 2, 8, 0);
}
// 显示原图和直方图
imshow("Image", image);
imshow("Histogram", histImage);
waitKey(0);
return 0;
}
アプリケーションシナリオ:
画像の強調: 画像のヒストグラムを分析することで、画像のコントラストと明るさを調整して、視覚的により魅力的なものにすることができます。
画像のセグメンテーション: ヒストグラム分析は、画像内のさまざまな領域の分割線を決定するのに役立ち、それによって画像のセグメンテーションの目的を達成できます。
色認識: カラー画像の場合、各チャネルのヒストグラムを分析して色の認識と分析を行うことができます。
コード分析:
まず、関数 imread でイメージを読み取り、IMREAD_GRAYSCALE を使用してグレースケール イメージに変換します。
calcHist 関数を使用して、グレー レベルの数、ピクセル値の範囲、その他のパラメーターを含む画像のヒストグラムを計算します。
ヒストグラムを描画するための画像を作成し、line 関数を使用してヒストグラムの線を描画します。
最後に、関数 imshow を使用して、元の画像と生成されたヒストグラムが表示されます。
結論:
ヒストグラムは画像処理における強力なツールであり、OpenCV が提供する calcHist 関数を使用すると、画像のピクセル分布を簡単に分析できます。ヒストグラムの応用シナリオを理解すると、画像処理における意思決定と操作をより適切に導くことができます。この記事を通じて、ヒストグラムの魅力をより深く理解し、さらに画像処理スキルを習得していただければ幸いです。