OpenCV imgproc图像处理模块常用算子及示例

imgproc模块是 OpenCV 中最核心的图像处理模块,包含从基础色彩转换到高级形态学操作等丰富功能。

这个模块非常强大,建议从基础功能开始逐步实践,结合具体应用场景选择合适的算法组合。

常用函数速查

功能 主要函数
色彩转换(支持多种色彩空间) cvtColor()
滤波(去噪和平滑) GaussianBlur(), medianBlur(), bilateralFilter()
几何变换(缩放、旋转、透视) resize(), warpAffine(), warpPerspective()
阈值(二值化处理) threshold(), adaptiveThreshold()
形态学(形状操作) erode(), dilate(), morphologyEx()
边缘检测(提取边缘) Sobel(), Laplacian(), Canny()
直方图(统计分析) calcHist(), equalizeHist()
霍夫变换(检测几何形状) HoughLines(), HoughCircles()
轮廓(形状分析) findContours(), drawContours()

1. 色彩空间转换 (Color Conversions)

常用转换类型:

  • COLOR_BGR2GRAY:彩色转灰度
  • COLOR_BGR2HSV:彩色转 HSV(色调、饱和度、亮度)
  • COLOR_BGR2YCrCb:彩色转 YCrCb(亮度、色度)
  • COLOR_HSV2BGR:HSV 转彩色
cpp 复制代码
#include <opencv2/opencv.hpp>

using namespace cv;

int main() {
    Mat src = imread("test.jpg");
    if (src.empty()) return -1;

    Mat gray, hsv, ycrcb;
    
    // 转换为灰度图
    cvtColor(src, gray, COLOR_BGR2GRAY);
    
    // 转换为 HSV 空间(常用于颜色分割)
    cvtColor(src, hsv, COLOR_BGR2HSV);
    
    // 转换为 YCrCb 空间
    cvtColor(src, ycrcb, COLOR_BGR2YCrCb);

    imshow("原图", src);
    imshow("灰度图", gray);
    imshow("HSV", hsv);
    imshow("YCrCb", ycrcb);
    
    waitKey(0);
    return 0;
}

2. 图像滤波 (Image Filtering)
高斯模糊 (Gaussian Blur)

cpp 复制代码
Mat blurred;
// 参数:输入、输出、核大小(必须为正奇数)、标准差
GaussianBlur(src, blurred, Size(5, 5), 0);
imshow("高斯模糊", blurred);

中值滤波 (Median Blur) - 去除椒盐噪声

cpp 复制代码
Mat median;
// 核大小必须为大于1的奇数
medianBlur(src, median, 5);
imshow("中值滤波", median);

双边滤波 (Bilateral Filter) - 保边去噪

cpp 复制代码
Mat bilateral;
// 参数:直径、颜色空间标准差、坐标空间标准差
bilateralFilter(src, bilateral, 9, 75, 75);
imshow("双边滤波", bilateral);

3. 几何变换 (Geometric Transformations)
缩放 (Resize)

cpp 复制代码
Mat resized;
// 参数:目标大小、插值方法
resize(src, resized, Size(300, 300), 0, 0, INTER_LINEAR);
imshow("缩放", resized);

旋转 (Rotation)

cpp 复制代码
Mat rotated;
// 获取旋转矩阵
Point2f center(src.cols/2.0, src.rows/2.0);
Mat rot_mat = getRotationMatrix2D(center, 45.0, 1.0); // 旋转45度,缩放1倍
// 应用仿射变换
warpAffine(src, rotated, rot_mat, src.size());
imshow("旋转", rotated);

透视变换 (Perspective Transform)

cpp 复制代码
Mat perspective;
// 定义原图四个点和目标点
Point2f src_pts[4] = { {0,0}, {src.cols-1,0}, {0,src.rows-1}, {src.cols-1,src.rows-1} };
Point2f dst_pts[4] = { {50,50}, {src.cols-100,50}, {0,src.rows-1}, {src.cols-1,src.rows-1} };

Mat persp_mat = getPerspectiveTransform(src_pts, dst_pts);
warpPerspective(src, perspective, persp_mat, src.size());
imshow("透视变换", perspective);

4. 阈值处理 (Thresholding)
简单阈值

cpp 复制代码
Mat thresh;
// 参数:阈值、最大值、类型
threshold(gray, thresh, 127, 255, THRESH_BINARY);
imshow("二值化", thresh);

自适应阈值 (Adaptive Threshold)

cpp 复制代码
Mat adaptive_thresh;
// 参数:邻域大小、常数C
adaptiveThreshold(gray, adaptive_thresh, 255, ADAPTIVE_THRESH_GAUSSIAN_C, 
                  THRESH_BINARY, 11, 2);
imshow("自适应阈值", adaptive_thresh);

Otsu 阈值 (自动确定最佳阈值)

cpp 复制代码
Mat otsu;
// 必须与 THRESH_OTSU 组合使用
threshold(gray, otsu, 0, 255, THRESH_BINARY | THRESH_OTSU);
cout << "Otsu 计算的阈值: " << threshold(gray, otsu, 0, 255, THRESH_BINARY | THRESH_OTSU) << endl;
imshow("Otsu阈值", otsu);

5. 形态学操作 (Morphological Operations)

用于去除噪声、连接断开的区域等

cpp 复制代码
// 创建结构元素
Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));
Mat eroded, dilated, opened, closed;
// 腐蚀 (缩小白色区域)
erode(thresh, eroded, kernel);
// 膨胀 (扩大白色区域)
dilate(thresh, dilated, kernel);
// 开运算 (先腐蚀后膨胀,去噪)
morphologyEx(thresh, opened, MORPH_OPEN, kernel);
// 闭运算 (先膨胀后腐蚀,填充空洞)
morphologyEx(thresh, closed, MORPH_CLOSE, kernel);
imshow("腐蚀", eroded);
imshow("膨胀", dilated);
imshow("开运算", opened);
imshow("闭运算", closed);

6. 边缘检测 (Edge Detection)
Sobel 算子

cpp 复制代码
Mat sobel_x, sobel_y, sobel;
// x方向梯度
Sobel(gray, sobel_x, CV_16S, 1, 0);
// y方向梯度
Sobel(gray, sobel_y, CV_16S, 0, 1);
// 转换为8位无符号
convertScaleAbs(sobel_x, sobel_x);
convertScaleAbs(sobel_y, sobel_y);
// 合并梯度
addWeighted(sobel_x, 0.5, sobel_y, 0.5, 0, sobel);
imshow("Sobel边缘", sobel);

Laplacian 算子

cpp 复制代码
Mat laplacian;
Laplacian(gray, laplacian, CV_16S);
convertScaleAbs(laplacian, laplacian);
imshow("Laplacian边缘", laplacian);

Canny 边缘检测 (推荐)

cpp 复制代码
Mat canny_edges;
// 参数:低阈值、高阈值(推荐比例 1:2 或 1:3)
Canny(gray, canny_edges, 50, 150);
imshow("Canny边缘", canny_edges);

7. 直方图处理 (Histogram Processing)
计算和显示直方图

cpp 复制代码
// 计算灰度直方图
Mat hist;
int histSize = 256;
float range[] = {0, 256};
const float* histRange = {range};
calcHist(&gray, 1, 0, Mat(), hist, 1, &histSize, &histRange);

// 绘制直方图
int hist_w = 512, hist_h = 400;
int bin_w = cvRound((double)hist_w / histSize);
Mat histImage(hist_h, hist_w, CV_8UC3, Scalar(0,0,0));

// 归一化直方图
normalize(hist, hist, 0, histImage.rows, NORM_MINMAX, -1, Mat());

// 绘制折线
for(int i = 1; i < histSize; i++) {
    line(histImage, 
         Point(bin_w*(i-1), hist_h - cvRound(hist.at<float>(i-1))),
         Point(bin_w*(i), hist_h - cvRound(hist.at<float>(i))),
         Scalar(255,0,0), 2, 8, 0);
}

imshow("直方图", histImage);

直方图均衡化

cpp 复制代码
Mat equalized;
equalizeHist(gray, equalized);
imshow("均衡化后", equalized);

8. 图像金字塔 (Image Pyramids)

cpp 复制代码
Mat pyramid;
// 高斯金字塔向下采样
pyrDown(src, pyramid);
imshow("下采样", pyramid);

// 高斯金字塔向上采样
pyrUp(pyramid, pyramid);
imshow("上采样", pyramid);

9. 霍夫变换 (Hough Transform)
霍夫直线检测

cpp 复制代码
Mat edges, lines_img;
Canny(gray, edges, 50, 150);
cvtColor(edges, lines_img, COLOR_GRAY2BGR);

vector<Vec2f> lines;
// 参数:距离精度、角度精度、阈值
HoughLines(edges, lines, 1, CV_PI/180, 150);

// 绘制检测到的直线
for(size_t i = 0; i < lines.size(); i++) {
    float rho = lines[i][0], theta = lines[i][1];
    Point pt1, pt2;
    double a = cos(theta), b = sin(theta);
    double x0 = a*rho, y0 = b*rho;
    pt1.x = cvRound(x0 + 1000*(-b));
    pt1.y = cvRound(y0 + 1000*(a));
    pt2.x = cvRound(x0 - 1000*(-b));
    pt2.y = cvRound(y0 - 1000*(a));
    line(lines_img, pt1, pt2, Scalar(0,0,255), 2);
}

imshow("霍夫直线", lines_img);

霍夫圆检测

cpp 复制代码
Mat circles_img = src.clone();
vector<Vec3f> circles;
// 参数:方法、累加器分辨率、最小圆心距、高阈值、低阈值、最小半径、最大半径
HoughCircles(gray, circles, HOUGH_GRADIENT, 1, gray.rows/8, 200, 100, 0, 0);

for(size_t i = 0; i < circles.size(); i++) {
    Point center(cvRound(circles[i][0]), cvRound(circles[i][1]));
    int radius = cvRound(circles[i][2]);
    circle(circles_img, center, radius, Scalar(0,255,0), 2);
}

imshow("霍夫圆", circles_img);

10. 轮廓检测 (Contour Detection)

cpp 复制代码
Mat contours_img = Mat::zeros(thresh.size(), CV_8UC3);
vector<vector<Point>> contours;
vector<Vec4i> hierarchy;

// 查找轮廓
findContours(thresh, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

// 绘制轮廓
for(size_t i = 0; i < contours.size(); i++) {
    drawContours(contours_img, contours, (int)i, Scalar(0,255,0), 2);
}

imshow("轮廓", contours_img);

11. 模板匹配 (Template Matching)

cpp 复制代码
Mat result;
Mat template_img = imread("template.jpg", IMREAD_GRAYSCALE); // 小模板

// 匹配方法
matchTemplate(gray, template_img, result, TM_CCOEFF_NORMED);

// 找到最佳匹配位置
double minVal, maxVal;
Point minLoc, maxLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);

// 在源图上绘制矩形框
rectangle(src, maxLoc, Point(maxLoc.x + template_img.cols, maxLoc.y + template_img.rows), 
          Scalar(0,0,255), 2);

imshow("模板匹配", src);

12. 综合示例:车牌区域检测

cpp 复制代码
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

int main() {
    Mat src = imread("car.jpg");
    if (src.empty()) return -1;

    Mat gray, blur, edges, morph;
    
    // 预处理
    cvtColor(src, gray, COLOR_BGR2GRAY);
    GaussianBlur(gray, blur, Size(5,5), 0);
    Canny(blur, edges, 50, 150);
    
    // 形态学闭运算连接边缘
    Mat kernel = getStructuringElement(MORPH_RECT, Size(15, 3));
    morphologyEx(edges, morph, MORPH_CLOSE, kernel);
    
    // 查找轮廓
    vector<vector<Point>> contours;
    findContours(morph, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    
    // 筛选可能的车牌区域
    for(size_t i = 0; i < contours.size(); i++) {
        Rect rect = boundingRect(contours[i]);
        float aspect_ratio = (float)rect.width / rect.height;
        
        // 根据长宽比和面积筛选
        if(aspect_ratio > 2.0 && aspect_ratio < 5.0 && rect.area() > 1000) {
            rectangle(src, rect, Scalar(0,255,0), 2);
        }
    }
    
    imshow("车牌检测", src);
    waitKey(0);
    return 0;
}
相关推荐
kyle~2 小时前
Opencv---霍夫直线变换(HoughLines)
人工智能·opencv·计算机视觉
WAI_f2 小时前
【BEV】“Simple-BEV: What Really Matters for Multi-Sensor BEV Perception?“ -- 文章解读
计算机视觉·自动驾驶
咚咚王者3 小时前
人工智能之视觉领域 计算机视觉 第五章 图像阈值处理
人工智能·计算机视觉
sali-tec16 小时前
C# 基于OpenCv的视觉工作流-章25-ORB特征点
图像处理·人工智能·opencv·算法·计算机视觉
十铭忘18 小时前
个人思考3——世界动作模型
人工智能·深度学习·计算机视觉
小小张说故事20 小时前
OpenCV Python技术文档
python·opencv
saoys20 小时前
Opencv 学习笔记:图像卷积操作(锐化核实战 + 数据类型避坑)
笔记·opencv·学习
如若1231 天前
SoftGroup训练FORinstance森林点云数据集——从零到AP=0.506完整复现
人工智能·python·深度学习·神经网络·计算机视觉
rit84324991 天前
matlab实现自适应稀疏表示同时完成图像融合与去噪
人工智能·计算机视觉·matlab