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