[Computer Vision 1] ----- Bildverbesserungsalgorithmus (Kontrastverbesserung, Histogrammausgleich)

Bildverbesserungsalgorithmus

Bildverbesserungsalgorithmen müssen Faktoren wie Beleuchtung, Rauschen, Bildinhalt usw. berücksichtigen, wenn sie Probleme wie Umweltauswirkungen behandeln. Geeignete Korrektur-, adaptive und mehrskalige Verarbeitungsmethoden müssen übernommen werden. Darüber hinaus müssen die Bewertung und Die Optimierung des Algorithmus selbst wirkt sich auch auf den endgültigen Verarbeitungseffekt aus.
Spezifische Korrekturmethoden finden Sie unter [Mehrere Korrekturmethoden für Bildverbesserungsalgorithmen, die von der Umgebung beeinflusst werden]

· Histogramm berechnen

Zählen Sie zunächst die Anzahl der Pixel bei jeder Graustufe im Bild, um ein Histogramm zu erstellen. Das Histogramm stellt die Verteilung der Pixel in verschiedenen Graustufen im Bild dar.

// 计算输入图像的最小灰度值和最大灰度值
    double minValue, maxValue;
    cv::minMaxLoc(image, &minValue, &maxValue);

    // 将图像的灰度值范围映射到更广泛的范围(例如,0-255)
    cv::Mat mappedImage;
    cv::convertScaleAbs(image, mappedImage, 255.0 / (maxValue - minValue), -minValue * 255.0 / (maxValue - minValue));

    // 显示原始图像和映射后的图像
    cv::imshow("原始图像", image);
    cv::imshow("映射后的图像", mappedImage);

    cv::waitKey(0);
    cv::destroyAllWindows();

minMaxLoc()-Funktion ermittelt die minimalen und maximalen Graustufenwerte des Eingabebildes. Verwenden Sie dann convertScaleAbsdie Funktion (), um den Grauwertbereich des Bildes zur Histogrammkorrektur einem größeren Bereich (z. B. 0-255) zuzuordnen.

imshowAbschließend werden das Originalbild und das Bild nach der Grauwertbereichszuordnung über die Funktion () angezeigt.

Beachten Sie, dass diese Methode den Grauwertbereich des Bildes lediglich linear auf einen größeren Bereich abbildet. Für komplexere Histogrammkorrekturmethoden sind möglicherweise andere Algorithmen und Techniken erforderlich.
Gehen Sie davon aus, dass das Eingabebild ein Graustufenbild ist. Wenn Sie das Histogramm eines Farbbildes berechnen möchten, müssen Sie das Bild zunächst in Graustufen konvertieren.

· Berechnen Sie das kumulative Histogramm

Durch die Durchführung einer Akkumulationsoperation am Histogramm wird die Gesamtzahl der Pixel vor jeder Graustufe berechnet. Und das kumulative Histogramm wird normalisiert, um den Anteil der Pixel im Bild darzustellen, die kleiner oder gleich einer bestimmten Graustufe sind.

// 计算直方图
    cv::Mat hist;
    int histSize = 256;
    float range[] = {
    
    0, 256};
    const float* histRange = {
    
    range};
    cv::calcHist(&image, 1, nullptr, cv::Mat(), hist, 1, &histSize, &histRange);

    // 计算累积直方图
    cv::Mat cumulativeHist(histSize, 1, CV_32F);
    cumulativeHist.at<float>(0) = hist.at<float>(0);
    for (int i = 1; i < histSize; ++i)
    {
    
    
        cumulativeHist.at<float>(i) = cumulativeHist.at<float>(i - 1) + hist.at<float>(i);
    }

    // 归一化累积直方图
    cv::normalize(cumulativeHist, cumulativeHist, 0, 1, cv::NORM_MINMAX);

calcHistDie Funktion () berechnet das Histogramm des Eingabebilds und berechnet durch eine Akkumulationsoperation die Gesamtzahl der Pixel vor jeder Graustufe. Verwenden Sie dann normalizedie Funktion (), um das kumulative Histogramm zu normalisieren, um den Anteil der Pixel im Bild darzustellen, die kleiner oder gleich einer bestimmten Graustufe sind. Die imshowFunktion () zeigt das Originalbild und das kumulative Histogramm an.

Hierbei ist zu beachten, dass Sie, wenn Sie das Histogramm oder kumulative Histogramm eines Farbbilds berechnen möchten, unter der Annahme, dass das Eingabebild ein Graustufenbild ist, das Bild in ein Graustufenbild konvertieren oder jeden Kanal separat verarbeiten müssen.

·Normalisiertes kumulatives Histogramm

Das Prinzip des normalisierten kumulativen Histogramms besteht darin, den Wertebereich des kumulativen Histogramms auf [0, 1] abzubilden, sodass es eine einheitliche Skala aufweist. Der Zweck besteht darin, Unterschiede in der Gesamtzahl der Pixel zwischen verschiedenen Bildern zu beseitigen, damit deren kumulative Histogramme besser verglichen und analysiert werden können.

// 计算累积直方图
std::vector<int> computeCumulativeHistogram(const std::vector<int>& histogram) 
{
    
    
    std::vector<int> cumulativeHistogram(histogram.size(), 0);
    cumulativeHistogram[0] = histogram[0];

    for (int i = 1; i < histogram.size(); ++i) {
    
    
        cumulativeHistogram[i] = cumulativeHistogram[i - 1] + histogram[i];
    }

    return cumulativeHistogram;
}

// 归一化累积直方图
std::vector<double> normalizeCumulativeHistogram(const std::vector<int>& cumulativeHistogram, int totalPixels)
{
    
    
    std::vector<double> normalizedHistogram(cumulativeHistogram.size());

    for (int i = 0; i < cumulativeHistogram.size(); ++i) {
    
    
        normalizedHistogram[i] = static_cast<double>(cumulativeHistogram[i]) / totalPixels;
    }

    return normalizedHistogram;
}
void CalculatehistogramModel
{
    
    
  // 示例直方图
    std::vector<int> histogram = {
    
    10, 20, 30, 40, 50};

    // 计算累积直方图
    std::vector<int> cumulativeHistogram = computeCumulativeHistogram(histogram);

    // 总像素数
    int totalPixels = cumulativeHistogram.back();

    // 归一化累积直方图
    std::vector<double> normalizedHistogram = normalizeCumulativeHistogram(cumulativeHistogram, totalPixels);
}

1. Definition computeCumulativeHistogramund normalizeCumulativeHistogramFunktion zur Berechnung des kumulativen Histogramms und des normalisierten kumulativen Histogramms. computeCumulativeHistogramDie Funktion empfängt ein Histogramm als Eingabe und gibt das berechnete kumulative Histogramm zurück. Wir verwenden eine Schleife, um jede Graustufe des Histogramms zu durchlaufen und den Pixelwert der aktuellen Graustufe mit dem kumulativen Wert der vorherigen Graustufe zu addieren, um den kumulativen Histogrammwert der aktuellen Graustufe zu erhalten.

2. normalizeCumulativeHistogramDie Funktion empfängt das kumulative Histogramm und die Gesamtzahl der Pixel als Eingabe und gibt das normalisierte kumulative Histogramm zurück. In dieser Funktion verwenden wir eine Schleife, um jeden Wert des kumulativen Histogramms zu durchlaufen und ihn durch die Gesamtzahl der Pixel zu dividieren, um den Anteil jeder Graustufe im Bild zu erhalten. In der CalculatehistogramModelFunktion wird ein Histogramm definiert histogram, das die enthält Um die Anzahl der Pixel bei einer bestimmten Graustufe zu ermitteln, rufen Sie computeCumulativeHistogramdie Funktion auf und übergeben ihr das Beispielhistogramm als Parameter, um das kumulative Histogramm zu erhalten.

3... Rufen Sie den letzten Wert im kumulativen Histogramm ab, der die Gesamtzahl der Pixel darstellt, rufen Sie die normalizeCumulativeHistogramFunktion auf und übergeben Sie das kumulative Histogramm und die Gesamtzahl der Pixel als Parameter an normalizeCumulativeHistogramdie Funktion, um das normalisierte kumulative Histogramm zu erhalten.
Auf diese Weise wird ein normalisiertes kumulatives Histogramm erhalten, in dem der Anteil jeder Graustufe im Bild auf den Bereich [0, 1] begrenzt ist.

· Berechnen Sie das Zielhistogramm

Die Berechnung des Zielhistogramms bezieht sich normalerweise auf die Berechnung der Graustufenverteilung eines bestimmten Ziels in einem Bild oder einem Bildbereich.

// 计算目标直方图
std::vector<int> computeTargetHistogram(const std::vector<std::vector<int>>& image, int targetValue) {
    
    
    std::vector<int> histogram(256, 0);

    for (const auto& row : image) {
    
    
        for (int pixelValue : row) {
    
    
            if (pixelValue == targetValue) {
    
    
                histogram[pixelValue]++;
            }
        }
    }

    return histogram;
    
// 归一化直方图
std::vector<double> normalizeHistogram(const std::vector<int>& histogram, int totalPixels) {
    
    
    std::vector<double> normalizedHistogram(histogram.size());

    for (int i = 0; i < histogram.size(); ++i) {
    
    
        normalizedHistogram[i] = static_cast<double>(histogram[i]) / totalPixels;
    }

    return normalizedHistogram;
}

     // 示例图像
    std::vector<std::vector<int>> image = {
    
    
        {
    
    0, 1, 2, 2, 1},
        {
    
    1, 3, 2, 0, 2},
        {
    
    2, 1, 2, 3, 0},
        {
    
    2, 2, 1, 0, 1}
       };
    // 目标灰度级
    int targetValue = 2;

    // 计算目标直方图
    std::vector<int> targetHistogram = computeTargetHistogram(image, targetValue);
}

1. Definieren computeTargetHistogramund normalizeHistogramfunktionieren. Wird zur Berechnung von Zielhistogrammen und normalisierten Histogrammen verwendet.

2. computeTargetHistogramDie Funktion empfängt ein Bild und eine Zielgraustufe als Eingabe und gibt das berechnete Zielhistogramm zurück. Verwenden Sie zwei verschachtelte Schleifen, um jeden Pixelwert im Bild zu durchlaufen, zu zählen, wie oft die Zielgraustufe erscheint, und sie an der entsprechenden Histogrammposition aufzuzeichnen.

3. normalizeHistogramDie Funktion empfängt das Histogramm und die Gesamtzahl der Pixel als Eingabe und gibt das normalisierte Histogramm zurück. Verwenden Sie in dieser Funktion eine Schleife, um jeden Wert des Histogramms zu durchlaufen und ihn durch die Gesamtzahl der Pixel zu dividieren, um den Anteil jeder Graustufe im Bild zu erhalten. In mainder Funktion definieren wir ein Beispielbild image, das einige Pixelwerte enthält.

4. Geben Sie die Zielgraustufe targetValuefür die Berechnung des Zielhistogramms an, rufen Sie computeTargetHistogramdie Funktion auf und übergeben Sie ihr das Beispielbild und die Zielgraustufe als Parameter, um das Zielhistogramm zu erhalten. Um die Gesamtzahl der Pixel zu berechnen, durchlaufen Sie jede Zeile des Bildes und akkumulieren die Anzahl der Pixel in jeder Zeile.

5. Rufen Sie normalizeHistogramdie Funktion auf und übergeben Sie ihr das Zielhistogramm und die Gesamtzahl der Pixel als Parameter, um das normalisierte Histogramm zu erhalten. Verwenden Sie eine Schleife, um jeden Wert des normalisierten Histogramms zu durchlaufen.

Auf diese Weise werden das Zielhistogramm und das normalisierte Zielhistogramm erhalten, die zur Darstellung der Graustufenverteilung eines bestimmten Ziels im Bild oder Bildbereich verwendet werden.

·Histogrammausgleich

Histogramm-Mapping ist eine häufig verwendete Bildverbesserungstechnik, die den Kontrast des Bildes durch Anpassen des Histogramms des Bildes erhöht.


// 直方图映射
std::vector<int> histogramMapping(const std::vector<std::vector<int>>& image, const std::vector<int>& histogram) {
    
    
    std::vector<int> mappedImage;

    // 计算映射函数
    std::vector<int> mappingFunction(256, 0);
    int totalPixels = 0;
    for (int i = 0; i < histogram.size(); ++i) {
    
    
        totalPixels += histogram[i];
        mappingFunction[i] = static_cast<int>(round(255.0 * totalPixels / (image.size() * image[0].size())));
    }

    // 进行直方图映射
    for (const auto& row : image) {
    
    
        for (int pixelValue : row) {
    
    
            mappedImage.push_back(mappingFunction[pixelValue]);
        }
    }

    return mappedImage;
int main() {
    
    
    // 示例图像
    std::vector<std::vector<int>> image = {
    
    
        {
    
    100, 150, 200},
        {
    
    50, 75, 100},
        {
    
    200, 175, 125}
    };

    // 计算原始图像的直方图
    std::vector<int> histogram = computeHistogram(image);

    // 进行直方图映射
    std::vector<int> mappedImage = histogramMapping(image, histogram);
}

Definieren Sie histogramMappingeine Funktion zum Berechnen des Histogramms des Originalbilds und zum Durchführen einer Histogrammzuordnung. Die Funktion empfängt das Histogramm des Bilds und des Originalbilds als Eingabe und gibt das Bild nach der Histogrammzuordnung zurück. In dieser Funktion berechnen wir zunächst die Zuordnungsfunktion, die die Graustufe des Originalbildes der neuen Graustufe zuordnet. Wir verwenden eine Schleife, um jede Graustufe des ursprünglichen Bildhistogramms zu durchlaufen und die Anzahl der Pixel zu berechnen, die jede Graustufe im neuen Bild einnimmt. Definieren Sie eine verschachtelte Schleife, die jeden Pixelwert im Originalbild durchläuft, ihn gemäß der Zuordnungsfunktion einer neuen Graustufe zuordnet und den zugeordneten Pixelwert im neuen Bild speichert.

Übergeben Sie die Histogramme des Beispielbilds und des Originalbilds als Argumente an histogramMappingdie Funktion, um das Histogramm-zugeordnete Bild zu erhalten. Durch das Histogramm-zugeordnete Bild können wir den Kontrast des Bildes verbessern und die Details in den Bildpixeln deutlicher machen.

·Histogrammausgleich

Transformieren Sie das Histogramm des Bildes, um die Graustufenverteilung des Originalbilds einem größeren Bereich zuzuordnen und so den visuellen Effekt des Bildes zu verbessern.

// 计算直方图
    cv::Mat hist;
    int histSize = 256;
    float range[] = {
    
    0, 256};
    const float* histRange = {
    
    range};
    cv::calcHist(&image, 1, nullptr, cv::Mat(), hist, 1, &histSize, &histRange);

    // 计算累积直方图
    cv::Mat cumulativeHist(histSize, 1, CV_32F);
    cumulativeHist.at<float>(0) = hist.at<float>(0);
    for (int i = 1; i < histSize; ++i)
    {
    
    
        cumulativeHist.at<float>(i) = cumulativeHist.at<float>(i - 1) + hist.at<float>(i);
    }

    // 归一化累积直方图
    cv::normalize(cumulativeHist, cumulativeHist, 0, histSize - 1, cv::NORM_MINMAX);

    // 映射灰度值
    cv::Mat equalizedImage = image.clone();
    for (int i = 0; i < image.rows; ++i)
    {
    
    
        for (int j = 0; j < image.cols; ++j)
        {
    
    
            int pixel = image.at<uchar>(i, j);
            equalizedImage.at<uchar>(i, j) = cv::saturate_cast<uchar>(cumulativeHist.at<float>(pixel));
        }
    }

    // 显示原始图像、直方图和均衡化后的图像
    cv::imshow("原始图像", image);
    cv::imshow("直方图", hist);
    cv::imshow("均衡化后的图像", equalizedImage);

    cv::waitKey(0);
    cv::destroyAllWindows();

Dieses Codebeispiel implementiert einen grundlegenden Algorithmus zur Histogrammkorrektur. Beachten Sie jedoch, dass es sich dabei um eine globale Bildverbesserungsmethode handelt, die die Sichtbarkeit von Rauschen im Bild erhöhen kann. In praktischen Anwendungen kann es notwendig sein, andere Technologien zu kombinieren, um die Qualität und visuelle Wirkung des Bildes weiter zu verbessern.

Guess you like

Origin blog.csdn.net/weixin_43504942/article/details/130790245