Erkunden Sie die Magie von Histogrammen in OpenCV: Anwendung und Implementierung

Vorwort:

Das Histogramm ist ein leistungsstarkes und wichtiges Werkzeug in der digitalen Bildverarbeitung. Es hilft uns, die Eigenschaften des Bildes besser zu verstehen, indem es die Datenverteilung visualisiert. In diesem Artikel werden wir uns mit dem Prozess der Erstellung von Histogrammen mithilfe von C++ und der OpenCV-Bibliothek befassen und einige Anwendungsszenarien für Histogramme vorstellen.

Histogrammübersicht:

Ein Histogramm ist eine grafische Darstellung der Datenverteilung und wird häufig zur Analyse der Verteilung der Pixelintensität in einem Bild verwendet. Bei der Bildverarbeitung können uns Histogramme helfen, die Helligkeit, den Kontrast und andere Informationen des Bildes zu verstehen. OpenCV bietet eine Funktion namens calcHist, mit der das Histogramm eines Bildes berechnet wird.

Funktionsprototyp

Die calcHist-Funktion ist eine Funktion in OpenCV, die zum Berechnen von Histogrammen verwendet wird. Hier ist der Prototyp der Funktion:


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);

Parameterbeschreibung:

Bilder: Eingabebildarray, das ein einzelnes Bild oder ein Bildarray sein kann. Wenn mehrere Bilder vorhanden sind, werden sie als Ganzes betrachtet und bilden ein kumulatives Histogramm.

nimages: Die Anzahl der Bilder. Wenn das Eingabebild-Array nur ein Bild enthält, ist der Wert 1.

Kanäle: Index des zu berücksichtigenden Kanals, normalerweise [0] für Graustufenbilder und [0, 1, 2] für alle Kanäle von Farbbildern. Bei der Verarbeitung von Graustufenbildern sind die Kanäle beispielsweise 0, was den Graustufenwerten entspricht; bei der Verarbeitung von Farbbildern können die Kanäle [0], [1], [2] sein, was jeweils den blauen, grünen und roten Kanälen entspricht.

Maske: Optionales Maskenbild, das verwendet wird, um den Berechnungsbereich des Histogramms einzuschränken. Zur Berechnung des Histogramms werden nur Pixelwerte mit Werten ungleich Null an entsprechenden Positionen im Maskenbild verwendet.

hist: Histogramm ausgeben. Dies ist ein Ausgabearray, das das berechnete Histogramm enthält.

dims: Abmessungen des Histogramms, normalerweise 1.

histSize: Histogrammgröße für jede Dimension, bereitgestellt als Array. Bei Graustufenbildern könnte histSize beispielsweise 256 sein; bei Farbbildern ist es üblich, für jeden Kanal dieselbe Histogrammgröße zu verwenden.

Bereiche: Bereich von Pixelwerten für jede Dimension, bereitgestellt als Array. Bei Graustufenbildern liegt der Bereich normalerweise bei [0, 256]; bei Farbbildern kann der Bereich jedes Kanals bei [0, 256] liegen.

uniform: Ein boolescher Wert, der angibt, ob das Histogramm einheitlich ist. Bei „true“ hat jedes Bin des Histogramms die gleiche Größe; bei „false“ wird die Größe jedes Bins entsprechend dem Bereich der Eingabepixelwerte angepasst.

akkumulieren: Ein boolescher Wert, der angibt, ob das Histogramm akkumuliert werden soll. Bei „true“ werden die Histogramme bei der Berechnung über mehrere Bilder akkumuliert; bei „false“ werden die Histogramme auf Null zurückgesetzt.

Codebeispiel


#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;
}

Anwendungsszenarien:

Bildverbesserung: Durch die Analyse des Histogramms eines Bildes können wir den Kontrast und die Helligkeit des Bildes anpassen, um es optisch ansprechender zu machen.
Bildsegmentierung: Die Histogrammanalyse hilft dabei, die Trennlinien verschiedener Bereiche im Bild zu bestimmen und so den Zweck der Bildsegmentierung zu erreichen.
Farberkennung: Bei Farbbildern kann das Histogramm jedes Kanals analysiert werden, um eine Farberkennung und -analyse zu erreichen.
Code-Analyse:

Lesen Sie zunächst das Bild über die Funktion imread und konvertieren Sie es mit IMREAD_GRAYSCALE in ein Graustufenbild.
Verwenden Sie die Funktion calcHist, um das Histogramm des Bildes zu berechnen, das die Anzahl der Graustufen, den Pixelwertbereich und andere Parameter umfasst.
Erstellen Sie ein Bild zum Zeichnen eines Histogramms und zeichnen Sie dann die Linien des Histogramms mit der Linienfunktion.
Abschließend werden das Originalbild und das generierte Histogramm über die Funktion imshow angezeigt.

Abschluss:

Das Histogramm ist ein leistungsstarkes Werkzeug in der Bildverarbeitung. Mit der von OpenCV bereitgestellten calcHist-Funktion können wir die Pixelverteilung des Bildes einfach analysieren. Das Verständnis der Anwendungsszenarien von Histogrammen kann unsere Entscheidungsfindung und Abläufe in der Bildverarbeitung besser steuern. Ich hoffe, dass die Leser durch diesen Artikel ein tieferes Verständnis für den Charme von Histogrammen erlangen und ihre Fähigkeiten in der Bildverarbeitung weiter ausbauen können.

Acho que você gosta

Origin blog.csdn.net/qq_46017342/article/details/134340248
Recomendado
Clasificación