C++ OpenCV Image Processing
Image Filtering
Image filtering is a basic operation in image processing, mainly used to remove noise from images or enhance certain features. Common filtering methods include mean filter, Gaussian filter, median filter, and custom filters.
Mean Filter
Mean filtering is a simple linear filtering method that replaces each pixel value in an image with the average of all pixel values in its neighborhood. This method can effectively remove noise, but it also blurs the image.
cv::Mat src = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE);
cv::Mat dst;
cv::blur(src, dst, cv::Size(3, 3)); // 3x3的均值滤波
Gaussian Filter
Gaussian filtering is a nonlinear filtering method that uses a Gaussian function to calculate the weights of pixels in the neighborhood, thereby smoothing the image. While removing noise, Gaussian filtering can better preserve edge information in the image.
cv::GaussianBlur(src, dst, cv::Size(5, 5), 0); // 5x5的高斯滤波
Median Filter
Median filtering is a nonlinear filtering method that replaces each pixel value in an image with the median of all pixel values in its neighborhood. This method is very effective at removing salt-and-pepper noise.
cv::medianBlur(src, dst, 5); // 5x5的中值滤波
Custom Filter
OpenCV allows users to customize the filter kernel. Throughcv::filter2Dthe function, custom filtering operations can be implemented.
cv::Mat kernel = (cv::Mat_<float>(3, 3) << 1, 0, -1, 0, 0, 0, -1, 0, 1); cv::filter2D(src, dst, -1, kernel);
Image Edge Detection
Edge detection is an important task in image processing, used to identify the boundaries of objects in an image. Common edge detection methods include the Sobel operator and Canny edge detection.
Sobel Operator
The Sobel operator is a gradient-based edge detection method that can detect horizontal and vertical edges in an 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); // 合并结果
Canny Edge Detection
Canny edge detection is a multi-stage edge detection algorithm that can effectively detect edges in images and is highly robust to noise.
cv::Canny(src, dst, 100, 200); // 阈值1=100,阈值2=200
Image Morphological Operations
Morphological operations are a series of operations based on image shape, often used for tasks such as foreground and background separation and noise removal. Common morphological operations include erosion, dilation, opening, closing, and morphological gradient.
Erosion
The erosion operation can eliminate small objects or details in an image, making foreground objects smaller.
cv::Mat kernel = cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3, 3)); cv::erode(src, dst, kernel);
Dilation
The dilation operation can enlarge foreground objects in an image, often used to fill holes in foreground objects.
cv::dilate(src, dst, kernel);
Opening Operation
Opening is an operation of erosion followed by dilation, often used to remove small objects or noise.
cv::morphologyEx(src, dst, cv::MORPH_OPEN, kernel);
Closing Operation
Closing is an operation of dilation followed by erosion, often used to fill small holes in foreground objects.
cv::morphologyEx(src, dst, cv::MORPH_CLOSE, kernel);
Morphological Gradient
The morphological gradient is the difference between dilation and erosion, and can be used to extract object edges.
cv::morphologyEx(src, dst, cv::MORPH_GRADIENT, kernel);
Image Thresholding
Image thresholding is the process of converting an image into a binary image, often used for image segmentation. Common thresholding methods include binarization, adaptive thresholding, and Otsu's method.
Binarization
Binarization divides pixel values in an image into two classes according to a set threshold, usually used for simple image segmentation.
cv::threshold(src, dst, 127, 255, cv::THRESH_BINARY);
Adaptive Threshold
Adaptive threshold dynamically calculates the threshold based on local regions of the image, suitable for images with uneven illumination.
cv::adaptiveThreshold(src, dst, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY, 11, 2);
Otsu's Thresholding Method
Otsu's method is an automatic threshold determination method, suitable for images with bimodal histograms.
cv::threshold(src, dst, 0, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
Image Histogram
A histogram is a tool used in image processing to analyze the brightness distribution of an image. Common histogram operations include calculating histograms, histogram equalization, and histogram comparison.
Calculating Histogram
A histogram can reflect the distribution of pixel values in an 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);
Histogram Equalization
Histogram equalization can enhance the contrast of an image, making the brightness distribution more uniform.
cv::equalizeHist(src, dst);
Histogram Comparison
Histogram comparison can be used to compare the similarity of two images.
double compare = cv::compareHist(hist1, hist2, cv::HISTCMP_CORREL);
Examples
Common image processing operations in OpenCV include filtering, edge detection, thresholding, morphological operations, and contour detection. With these techniques, you can implement more complex image processing tasks.
The following are common image processing operations in C++ OpenCV and their code examples:
1. Image Filtering
Image filtering is used to remove noise or enhance image features.
1.1 Mean Filter
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Mean filter
Mat blurredImage;
blur(image, blurredImage, Size(5, 5)); // 5x5 kernel
imshow("Original Image", image);
imshow("Blurred Image", blurredImage);
waitKey(0);
destroyAllWindows();
return 0;
}
1.2 Gaussian Filter
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Gaussian filter
Mat gaussianBlurredImage;
GaussianBlur(image, gaussianBlurredImage, Size(5, 5), 0); // 5x5 kernel
imshow("Original Image", image);
imshow("Gaussian Blurred Image", gaussianBlurredImage);
waitKey(0);
destroyAllWindows();
return 0;
}
1.3 Median Filter
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Median filter
Mat medianBlurredImage;
medianBlur(image, medianBlurredImage, 5); // Kernel size is 5
imshow("Original Image", image);
imshow("Median Blurred Image", medianBlurredImage);
waitKey(0);
destroyAllWindows();
return 0;
}
2. Edge Detection
Edge detection is used to extract edge information from images.
2.1 Canny Edge Detection
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Convert to grayscale image
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
// Canny edge detection
Mat edges;
Canny(grayImage, edges, 100, 200); // Threshold 1 and threshold 2
imshow("Original Image", image);
imshow("Canny Edges", edges);
waitKey(0);
destroyAllWindows();
return 0;
}
3. Image Thresholding
Thresholding is used to convert an image into a binary image.
3.1 Simple Thresholding
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Convert to grayscale image
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
// Simple thresholding
Mat binaryImage;
threshold(grayImage, binaryImage, 127, 255, THRESH_BINARY);
imshow("Original Image", image);
imshow("Binary Image", binaryImage);
waitKey(0);
destroyAllWindows();
return 0;
}
3.2 Adaptive Thresholding
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Convert to grayscale image
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
// Adaptive thresholding
Mat adaptiveBinaryImage;
adaptiveThreshold(grayImage, adaptiveBinaryImage, 255, ADAPTIVE_THRESH_MEAN_C, THRESH_BINARY, 11, 2);
imshow("Original Image", image);
imshow("Adaptive Binary Image", adaptiveBinaryImage);
waitKey(0);
destroyAllWindows();
return 0;
}
4. Morphological Operations
Morphological operations are used to process the shape and structure of images.
4.1 Erosion and Dilation
Example
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Convert to grayscale image
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
// Binarization
Mat binaryImage;
threshold(grayImage, binaryImage, 127, 255, THRESH_BINARY);
// Erosion operation
Mat erodedImage;
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
erode(binaryImage, erodedImage, kernel);
// Dilation operation
Mat dilatedImage;
dilate(binaryImage, dilatedImage, kernel);
imshow("Original Image", image);
imshow("Eroded Image", erodedImage);
imshow("Dilated Image", dilatedImage);
waitKey(0);
destroyAllWindows();
return 0;
}
5. Contour Detection
Contour detection is used to extract object contours in images.
Example
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main() {
Mat image = imread("test.jpg");
if (image.empty()) {
cout << "Error: Unable to load image, please check if the path is correct." << endl;
return -1;
}
// Convert to grayscale image
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
// Binarization
Mat binaryImage;
threshold(grayImage, binaryImage, 127, 255, THRESH_BINARY);
// Find contours
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;
findContours(binaryImage, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);
// Draw 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("Original Image", image);
imshow("Contours", contourImage);
waitKey(0);
destroyAllWindows();
return 0;
}