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;
}
相关推荐
2zcode3 小时前
项目文档:基于MATLAB图像处理的乳腺癌辅助检测系统设计与实现
图像处理·人工智能·matlab
城中南小5 小时前
3D-VLA 方法原理详解
人工智能·计算机视觉·3d
在世修行5 小时前
第17篇:晶粒尺寸统计算法 — 从像素到微米的转换
人工智能·计算机视觉·像素转换
m沐沐7 小时前
【深度学习】dlib 人脸关键点实时疲劳检测
人工智能·深度学习·计算机视觉·疲劳检测·关键点检测·人脸检测·dlib
研來如此8 小时前
8位图、24位图、32位图、48位图区别
图像处理·人工智能·计算机视觉
A hao10 小时前
HDR LED显示屏工作原理:高动态范围显示技术解析
大数据·图像处理·人工智能
硅谷秋水1 天前
World Engine:迈向自动驾驶的后训练时代
人工智能·深度学习·机器学习·计算机视觉·语言模型·自动驾驶
一个王同学1 天前
从零到一 | CV转多模态大模型 | week17 | LLM 推理优化 & vLLM 详解
人工智能·深度学习·算法·机器学习·计算机视觉·vllm
ShiMetaPi1 天前
事件相机商业化落地的 “最后一道关键门槛”
人工智能·计算机视觉·ai·自动驾驶·事件相机
日光明媚1 天前
LongLive-英伟达-数字人实时生成
人工智能·计算机视觉·aigc·音视频