Traitement d'images C++ OpenCV

Filtrage d'image

Le filtrage d'image est une opération de base en traitement d'image, principalement utilisée pour éliminer le bruit des images ou renforcer certaines caractéristiques. Les méthodes de filtrage courantes incluent le filtre moyenneur, le filtre gaussien, le filtre médian et les filtres personnalisés.

Filtre moyenneur

Le filtrage moyenneur est une méthode de filtrage linéaire simple qui remplace chaque valeur de pixel d'une image par la moyenne de toutes les valeurs de pixel de son voisinage. Cette méthode peut efficacement supprimer le bruit, mais elle floute aussi l'image.

cv::Mat src = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat dst;
cv::blur(src, dst, cv::Size(3, 3));  // 3x3的均值滤波

Filtre gaussien

Le filtrage gaussien est une méthode de filtrage non linéaire qui utilise une fonction gaussienne pour calculer les poids des pixels du voisinage, lissant ainsi l'image. Tout en supprimant le bruit, le filtrage gaussien peut mieux préserver les informations de contour dans l'image.

cv::GaussianBlur(src, dst, cv::Size(5, 5), 0);  // 5x5的高斯滤波

Filtre médian

Le filtrage médian est une méthode de filtrage non linéaire qui remplace chaque valeur de pixel d'une image par la médiane de toutes les valeurs de pixel de son voisinage. Cette méthode est très efficace pour supprimer le bruit poivre et sel.

cv::medianBlur(src, dst, 5);  // 5x5的中值滤波

Filtre personnalisé

OpenCV permet aux utilisateurs de personnaliser le noyau de filtre. Grâce àcv::filter2Dla fonction, des opérations de filtrage personnalisées peuvent être implémentées.

cv::Mat kernel = (cv::Mat_<float>(3, 3) << 1, 0, -1, 0, 0, 0, -1, 0, 1);
cv::filter2D(src, dst, -1, kernel);

Détection des contours d'image

La détection de contours est une tâche importante en traitement d'image, utilisée pour identifier les limites des objets dans une image. Les méthodes courantes de détection de contours incluent l'opérateur Sobel et la détection de contours Canny.

Opérateur Sobel

L'opérateur de Sobel est une méthode de détection de contours basée sur le gradient qui peut détecter les contours horizontaux et verticaux dans une image.

cv::Mat grad_x, grad_y;
cv::Sobel(src, grad_x, CV_16S, 1, 0);  // 水平方向
cv::Sobel(src, grad_y, CV_16S, 0, 1);  // 垂直方向
cv::convertScaleAbs(grad_x, grad_x);
cv::convertScaleAbs(grad_y, grad_y);
cv::addWeighted(grad_x, 0.5, grad_y, 0.5, 0, dst);  // 合并结果

Détection de contours de Canny

La détection de contours de Canny est un algorithme de détection de contours multi-étapes qui peut détecter efficacement les contours dans les images et est très robuste au bruit.

cv::Canny(src, dst, 100, 200);  // 阈值1=100,阈值2=200

Opérations morphologiques d'image

Les opérations morphologiques sont une série d'opérations basées sur la forme de l'image, souvent utilisées pour des tâches telles que la séparation du premier plan et de l'arrière-plan et l'élimination du bruit. Les opérations morphologiques courantes comprennent l'érosion, la dilatation, l'ouverture, la fermeture et le gradient morphologique.

Érosion

L'opération d'érosion peut éliminer les petits objets ou détails d'une image, ce qui rend les objets du premier plan plus petits.

cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3));
cv::erode(src, dst, kernel);

Dilatation

L'opération de dilatation peut agrandir les objets du premier plan d'une image, souvent utilisée pour remplir les trous dans les objets du premier plan.

cv::dilate(src, dst, kernel);

Opération d'ouverture

L'ouverture est une opération d'érosion suivie de dilatation, souvent utilisée pour supprimer les petits objets ou le bruit.

cv::morphologyEx(src, dst, cv::MORPH_OPEN, kernel);

Opération de fermeture

La fermeture est une opération de dilatation suivie d'érosion, souvent utilisée pour remplir les petits trous dans les objets du premier plan.

cv::morphologyEx(src, dst, cv::MORPH_CLOSE, kernel);

Gradient morphologique

Le gradient morphologique est la différence entre la dilatation et l'érosion, et peut être utilisé pour extraire les contours des objets.

cv::morphologyEx(src, dst, cv::MORPH_GRADIENT, kernel);

Seuillage d'image

Le seuillage d'image est le processus de conversion d'une image en une image binaire, souvent utilisé pour la segmentation d'image. Les méthodes de seuillage courantes incluent la binarisation, le seuillage adaptatif et la méthode d'Otsu.

Binarisation

La binarisation divise les valeurs de pixels d'une image en deux classes selon un seuil défini, généralement utilisée pour une segmentation d'image simple.

cv::threshold(src, dst, 127, 255, cv::THRESH_BINARY);

Seuillage adaptatif

Le seuillage adaptatif calcule dynamiquement le seuil en fonction des régions locales de l'image, adapté aux images présentant un éclairage inégal.

cv::adaptiveThreshold(src, dst, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 11, 2);

Méthode de seuillage d'Otsu

La méthode d'Otsu est une méthode de détermination automatique du seuil, adaptée aux images dont les histogrammes sont bimodaux.

cv::threshold(src, dst, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);

Histogramme d'image

Un histogramme est un outil utilisé en traitement d'image pour analyser la distribution de luminosité d'une image. Les opérations courantes sur les histogrammes incluent le calcul d'histogrammes, l'égalisation d'histogramme et la comparaison d'histogrammes.

Calcul de l'histogramme

Un histogramme peut refléter la distribution des valeurs de pixel dans une image.

cv::Mat hist;
int histSize = 256;
float range[] = {0, 256};
const float* histRange = {range};
cv::calcHist(&src, 1, 0, cv::Mat(), hist, 1, &histSize, &histRange);

Égalisation d'histogramme

L'égalisation d'histogramme peut améliorer le contraste d'une image, rendant la distribution de luminosité plus uniforme.

cv::equalizeHist(src, dst);

Comparaison d'histogrammes

La comparaison d'histogrammes peut être utilisée pour comparer la similarité de deux images.

double compare = cv::compareHist(hist1, hist2, cv::HISTCMP_CORREL);

Exemples

Les opérations courantes de traitement d'image dans OpenCV incluent le filtrage, la détection de bords, le seuillage, les opérations morphologiques et la détection de contours. Avec ces techniques, vous pouvez mettre en œuvre des tâches de traitement d'image plus complexes.

Voici des opérations courantes de traitement d'image avec OpenCV en C++ et leurs exemples de code :

1. Filtrage d'image

Le filtrage d'image est utilisé pour supprimer le bruit ou améliorer les caractéristiques de l'image.

1.1 Filtre moyen

Exemple

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Filtre moyenneur
    Mat blurredImage;
    blur(image, blurredImage, Size(5, 5)); // Noyau 5x5

    imshow("Image originale", image);
    imshow("Image floue", blurredImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

1.2 Filtre gaussien

Exemple

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Filtre gaussien
    Mat gaussianBlurredImage;
    GaussianBlur(image, gaussianBlurredImage, Size(5, 5), 0); // Noyau 5x5

    imshow("Image originale", image);
    imshow("Image floutée gaussienne", gaussianBlurredImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

1.3 Filtre médian

Exemple

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Filtre médian
    Mat medianBlurredImage;
    medianBlur(image, medianBlurredImage, 5); // La taille du noyau est de 5

    imshow("Image originale", image);
    imshow("Image floutée médiane", medianBlurredImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

2. Détection de contours

La détection de contours est utilisée pour extraire des informations de contour à partir d'images.

2.1 Détection de contours Canny

Exemple

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Convertir en image en niveaux de gris
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // Détection de contours Canny
    Mat edges;
    Canny(grayImage, edges, 100, 200); // Seuil 1 et seuil 2

    imshow("Image originale", image);
    imshow("Contours Canny", edges);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

3. Seuillage d'image

Le seuillage est utilisé pour convertir une image en image binaire.

3.1 Seuillage simple

Exemple

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Convertir en image en niveaux de gris
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // Seuillage simple
    Mat binaryImage;
    threshold(grayImage, binaryImage, 127, 255, THRESH_BINARY);

    imshow("Image originale", image);
    imshow("Image binaire", binaryImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

3.2 Seuillage adaptatif

Exemple

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Convertir en image en niveaux de gris
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // Seuillage adaptatif
    Mat adaptiveBinaryImage;
    adaptiveThreshold(grayImage, adaptiveBinaryImage, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, 2);

    imshow("Image originale", image);
    imshow("Image binaire adaptative", adaptiveBinaryImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

4. Opérations morphologiques

Les opérations morphologiques sont utilisées pour traiter la forme et la structure des images.

4.1 Érosion et dilatation

Exemple

#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Convertir en image en niveaux de gris
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // Binarisation
    Mat binaryImage;
    threshold(grayImage, binaryImage, 127, 255, THRESH_BINARY);

    // Opération d'érosion
    Mat erodedImage;
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
    erode(binaryImage, erodedImage, kernel);

    // Opération de dilatation
    Mat dilatedImage;
    dilate(binaryImage, dilatedImage, kernel);

    imshow("Image originale", image);
    imshow("Image érodée", erodedImage);
    imshow("Image dilatée", dilatedImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

5. Détection de contours

La détection de contours est utilisée pour extraire les contours des objets dans les images.

Exemple


#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main() {
    Mat image = imread("test.jpg");
    if (image.empty()) {
        cout << "Erreur : Impossible de charger l'image, veuillez vérifier si le chemin est correct." << endl;
        return -1;
    }

    // Convertir en image en niveaux de gris
    Mat grayImage;
    cvtColor(image, grayImage, COLOR_BGR2GRAY);

    // Binarisation
    Mat binaryImage;
    threshold(grayImage, binaryImage, 127, 255, THRESH_BINARY);

    // Trouver les contours
    vector<vector<Point>> contours;
    vector<Vec4i> hierarchy;
    findContours(binaryImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

    // Dessiner les contours
    Mat contourImage = Mat::zeros(image.size(), CV_8UC3);
    for (size_t i = 0; i < contours.size(); i++) {
        drawContours(contourImage, contours, i, Scalar(0, 255, 0), 2);
    }

    imshow("Image originale", image);
    imshow("Contours", contourImage);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
Autres extensions