OpenCV从入门到精通:安装、配置、依赖、基本语法与常用方法详解

摘要

本文旨在为计算机视觉初学者提供一份详尽的OpenCV入门指南。从OpenCV的安装配置、依赖项安装,到基本语法和常用方法的解析,我们力求以通俗易懂的方式,配合丰富的代码示例,帮助读者快速掌握OpenCV的核心概念和技术,并为后续深入学习打下坚实的基础。无论您是Python爱好者还是C++开发者,都能从中受益。最后,欢迎大家加我的微信一起交流学习!

引言

大家好!作为一名默语博主,我深知初学者在接触新技术时常常会感到迷茫。计算机视觉领域更是如此,涉及众多的概念和工具。今天,我就为大家带来一篇保姆级的OpenCV入门教程。OpenCV(Open Source Computer Vision Library)作为一个功能强大的开源计算机视觉库,是进行图像处理、视频分析、物体识别等任务的利器。别看它名字听起来很“高大上”,其实只要跟着我的步骤一步步来,你会发现它并没有想象中那么难。让我们一起开启OpenCV的奇妙之旅吧!

博主 默语带您 Go to New World.
个人主页—— 默语 的博客👦🏻 优秀内容
《java 面试题大全》
《java 专栏》
《idea技术专区》
《spring boot 技术专区》
《MyBatis从入门到精通》
《23种设计模式》
《经典算法学习》
《spring 学习》
《MYSQL从入门到精通》数据库是开发者必会基础之一~
🍩惟余辈才疏学浅,临摹之作或有不妥之处,还请读者海涵指正。☕🍭
🪁 吾期望此文有资助于尔,即使粗浅难及深广,亦备添少许微薄之助。苟未尽善尽美,敬请批评指正,以资改进。!💻⌨


默语是谁?

大家好,我是 默语,别名默语博主,擅长的技术领域包括Java、运维和人工智能。我的技术背景扎实,涵盖了从后端开发到前端框架的各个方面,特别是在Java 性能优化、多线程编程、算法优化等领域有深厚造诣。

目前,我活跃在CSDN、掘金、阿里云和 51CTO等平台,全网拥有超过15万的粉丝,总阅读量超过1400 万。统一 IP 名称为 默语 或者 默语博主。我是 CSDN 博客专家、阿里云专家博主和掘金博客专家,曾获博客专家、优秀社区主理人等多项荣誉,并在 2023 年度博客之星评选中名列前 50。我还是 Java 高级工程师、自媒体博主,北京城市开发者社区的主理人,拥有丰富的项目开发经验和产品设计能力。希望通过我的分享,帮助大家更好地了解和使用各类技术产品,在不断的学习过程中,可以帮助到更多的人,结交更多的朋友.


我的博客内容涵盖广泛,主要分享技术教程、Bug解决方案、开发工具使用、前沿科技资讯、产品评测与使用体验。我特别关注云服务产品评测、AI 产品对比、开发板性能测试以及技术报告,同时也会提供产品优缺点分析、横向对比,并分享技术沙龙与行业大会的参会体验。我的目标是为读者提供有深度、有实用价值的技术洞察与分析。

默语:您的前沿技术领航员

👋 大家好,我是默语
📱 全网搜索“默语”,即可纵览我在各大平台的知识足迹。

📣 公众号“默语摸鱼”,每周定时推送干货满满的技术长文,从新兴框架的剖析到运维实战的复盘,助您技术进阶之路畅通无阻。

💬 微信端添加好友“Solitudemind”,与我直接交流,不管是项目瓶颈的求助,还是行业趋势的探讨,随时畅所欲言。

📅 最新动态:2025 年 5 月 11 日

快来加入技术社区,一起挖掘技术的无限潜能,携手迈向数字化新征程!


好的,请看下面这篇关于OpenCV的入门到精通的技术博客文章,希望对您有所帮助!

OpenCV从入门到精通:安装、配置、依赖、基本语法与常用方法详解

在这里插入图片描述

目录

  1. 引言
  2. 环境准备
    • 2.1 系统需求
    • 2.2 安装依赖
  3. OpenCV安装
    • 3.1 Python 环境安装
    • 3.2 C++ 环境安装(源码编译)
  4. OpenCV 配置
    • 4.1 Python 配置
    • 4.2 C++ 配置(CMake、IDE)
  5. 基本语法
    • 5.1 包含头文件与命名空间
    • 5.2 Mat 类详解
    • 5.3 读取与显示图像
    • 5.4 视频读写
  6. 常用方法详解
    • 6.1 色彩空间转换
    • 6.2 图像阈值处理
    • 6.3 滤波与平滑
    • 6.4 边缘检测
    • 6.5 形态学操作
    • 6.6 轮廓检测
    • 6.7 几何变换
    • 6.8 绘制函数
  7. 进阶技巧
    • 7.1 ROI 与模板匹配
    • 7.2 特征检测(ORB/SIFT/SURF)
    • 7.3 摄像头标定与透视变换
  8. 常见问题与解决方案
  9. 总结与建议
  10. 参考资料

2. 环境准备

在开始安装OpenCV之前,我们需要确保你的计算机满足一些基本条件,并安装必要的依赖项。

2.1 系统需求

OpenCV支持多种操作系统,包括Windows、Linux、macOS等。你需要一台能够运行这些操作系统的计算机。对于初学者来说,Windows或Linux都是不错的选择。

2.2 安装依赖

根据你选择的编程语言(Python或C++),需要安装相应的依赖库。

2.2.1 Python 环境

如果你选择使用Python进行OpenCV开发,你需要确保已经安装了Python环境。建议安装Python 3.7或更高版本。

可以通过以下方式检查Python是否已安装以及版本:

Bash

python --version

或者Bash

python3 --version

如果尚未安装,请前往Python官方网站下载并安装。

接下来,我们需要安装一些Python的常用库,这些库能够帮助我们更好地使用OpenCV:

  • NumPy: OpenCV中的图像数据是以NumPy数组的形式存储的,因此NumPy是OpenCV的基础。
  • Matplotlib: 用于绘制图像和图表。

可以使用pip(Python的包管理器)来安装这些库:

Bash

pip install numpy matplotlib

如果你的Python环境配置了多个版本,可能需要使用pip3命令:

Bash

pip3 install numpy matplotlib
2.2.2 C++ 环境

如果你选择使用C++进行OpenCV开发,你需要一个C++编译器。常用的编译器有:

  • Windows: MinGW-w64(通常与CMake结合使用)、Visual Studio
  • Linux: GCC、Clang
  • macOS: Xcode

此外,我们还需要安装CMake,它是一个跨平台的构建系统,用于管理OpenCV的编译过程。

  • Windows: 可以从CMake官方网站下载安装程序。

  • Linux (Debian/Ubuntu): 可以使用apt命令安装:

    Bash

    sudo apt update
    sudo apt install cmake cmake-curses-gui
    
  • Linux (Fedora/CentOS): 可以使用yum或dnf命令安装:

    Bash

    sudo yum install cmake cmake-gui
    

    或者

    Bash

    sudo dnf install cmake cmake-gui
    
  • macOS: 可以使用Homebrew安装:

    Bash

    brew install cmake
    

3. OpenCV安装

接下来,我们将分别介绍Python和C++环境下OpenCV的安装方法。

3.1 Python 环境安装

在Python环境下安装OpenCV非常简单,可以直接使用pip命令:

Bash

pip install opencv-python

或者,如果你需要包含contrib模块(包含一些额外的、可能不太稳定的功能),可以使用以下命令:

Bash

pip install opencv-contrib-python

同样地,如果你的Python环境配置了多个版本,可能需要使用pip3命令:

Bash

pip3 install opencv-python

安装完成后,你可以在Python交互式环境中导入cv2模块来验证是否安装成功:

Python

import cv2

print(cv2.__version__)

如果能够成功打印出OpenCV的版本号,则说明安装成功。

3.2 C++ 环境安装(源码编译)

在C++环境下安装OpenCV通常需要从源码进行编译,这可能稍微复杂一些,但能够提供更大的灵活性。

3.2.1 下载OpenCV源码

你可以从OpenCV官方GitHub仓库下载最新或指定版本的源码。通常会下载一个zip或tar.gz压缩包。

3.2.2 下载OpenCV Contrib模块(可选)

如果你需要使用contrib模块中的额外功能,也需要从OpenCV Contrib GitHub仓库下载源码。

3.2.3 创建构建目录

在OpenCV源码目录下创建一个名为build的文件夹,用于存放编译生成的文件。

Bash

mkdir build
cd build
3.2.4 使用CMake配置

build目录下运行CMake,配置编译选项。你需要指定OpenCV源码的路径以及contrib模块的路径(如果下载了的话)。

Bash

cmake -D CMAKE_BUILD_TYPE=Release \
      -D CMAKE_INSTALL_PREFIX=/usr/local \
      -D INSTALL_C_EXAMPLES=OFF \
      -D INSTALL_PYTHON_EXAMPLES=OFF \
      -D BUILD_EXAMPLES=OFF \
      -D WITH_QT=OFF \
      -D WITH_OPENGL=OFF \
      -D OPENCV_EXTRA_MODULES_PATH=../../opencv_contrib/modules ../../opencv

-D CMAKE_BUILD_TYPE=Release: 设置编译类型为Release,生成优化过的可执行文件。

-D CMAKE_INSTALL_PREFIX=/usr/local: 设置OpenCV的安装路径。你可以根据自己的需求修改。

-D INSTALL_C_EXAMPLES=OFF、
-D INSTALL_PYTHON_EXAMPLES=OFF、
-D BUILD_EXAMPLES=OFF 、 -D WITH_QT=OFF、
-D WITH_OPENGL=OFF
: 关闭一些不需要的选项,加快编译速度。

  • -D OPENCV_EXTRA_MODULES_PATH=…/…/opencv_contrib/modules
    指定contrib模块的路径(相对于build目录)。你需要将其替换为你的实际路径。
  • …/…/opencv: 指定OpenCV源码的路径(相对于build目录)。同样需要根据你的实际路径进行调整。

如果你没有下载contrib模块,可以省略-D OPENCV_EXTRA_MODULES_PATH=...这一行。

3.2.5 编译与安装

配置完成后,使用make命令进行编译:

Bash


make -j4

-j4表示使用4个线程进行编译,可以根据你的CPU核心数进行调整,加快编译速度。

编译完成后,使用以下命令进行安装:

Bash

sudo make install
sudo ldconfig

sudo make install会将编译生成的文件安装到之前通过CMAKE_INSTALL_PREFIX指定的路径。sudo ldconfig会更新系统的动态链接库缓存,使得程序能够找到OpenCV的库文件。

4. OpenCV 配置

安装完成后,我们还需要进行一些配置,以便在Python或C++项目中使用OpenCV。

4.1 Python 配置

如果你是通过pip安装的OpenCV,通常情况下不需要进行额外的配置。Python会自动找到安装的cv2模块。

4.2 C++ 配置(CMake、IDE)

如果你是通过源码编译安装的OpenCV,你需要告诉你的C++项目如何找到OpenCV的头文件和库文件。这通常通过CMake来实现。

4.2.1 使用CMakeLists.txt

在你的C++项目的CMakeLists.txt文件中,你需要添加以下代码来查找OpenCV:

CMake

cmake_minimum_required(VERSION 3.10)
project(YourProjectName)

find_package(OpenCV REQUIRED)

include_directories(${OpenCV_INCLUDE_DIRS})
link_directories(${OpenCV_LIBS})

add_executable(YourExecutableName main.cpp)
target_link_libraries(YourExecutableName ${OpenCV_LIBS})
  • ind_package(OpenCV REQUIRED): 告诉CMake查找OpenCV。如果找不到,会报错。

  • include_directories(${OpenCV_INCLUDE_DIRS}) : 将OpenCV的头文件目录添加到包含路径中。

  • link_directories(${OpenCV_LIBS}) : 将OpenCV的库文件目录添加到链接路径中(通常不需要显式指定, target_link_libraries会自动处理)。

  • target_link_libraries(YourExecutableName ${OpenCV_LIBS}): 将OpenCV的库文件链接到你的可执行文件。

4.2.2 在IDE中配置

如果你使用集成开发环境(IDE)如Visual Studio或CLion,你需要配置项目的构建设置,告诉IDE OpenCV的头文件和库文件在哪里。

  • Visual Studio:

    你需要在项目属性中的“VC++目录”->“包含目录”中添加OpenCV的头文件路径,并在“VC++目录”->“库目录”中添加OpenCV的库文件路径。然后在“链接器”->“输入”->“附加依赖项”中添加你需要链接的OpenCV库文件(例如opencv_world4xxx.lib,具体名称取决于你的OpenCV版本)。

  • CLion: CLion通常会使用你的CMakeLists.txt文件进行配置,所以只需要确保你的CMakeLists.txt文件配置正确即可。

5. 基本语法

现在我们已经安装并配置好了OpenCV,接下来让我们学习一些基本的语法。

5.1 包含头文件与命名空间

5.1.1 C++

在使用OpenCV的C++代码中,你需要包含相应的头文件。通常会包含opencv2/opencv.hpp这个头文件,它包含了OpenCV的大部分常用模块。

C++

#include <opencv2/opencv.hpp>

int main() {
    // OpenCV 代码
    return 0;
}

为了方便使用OpenCV的函数和类,可以添加命名空间:

C++

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    // 使用 cv::Mat 等
    Mat image;
    return 0;
}
5.1.2 Python

在使用OpenCV的Python代码中,你需要导入cv2模块:

Python

import cv2

# OpenCV 代码

5.2 Mat 类详解

cv::Mat(C++)或 numpy.ndarray(Python)是OpenCV中用于表示图像的核心数据结构。它可以表示单通道或多通道的图像,每个通道可以存储不同数据类型的像素值。

  • C++: cv::Mat是一个类,提供了丰富的方法来操作图像数据。你可以指定图像的尺寸、数据类型和通道数来创建Mat对象。

    C++

    // 创建一个3通道(BGR)、8位无符号整数类型的300x400的图像
    Mat image(300, 400, CV_8UC3);
    
    • CV_8U : 8位无符号整数(通常用于像素值,范围0-255)

    • C3 : 3通道(例如,BGR颜色图像)

  • Python: 在Python中,图像数据存储为NumPy数组。你可以使用NumPy的函数来创建和操作图像数组。

    Python

    import numpy as np
    
    # 创建一个3通道的300x400的图像,像素值初始化为0
    image = np.zeros((300, 400, 3), dtype=np.uint8)
    
    • (300, 400, 3): 表示图像的形状(高度、宽度、通道数)

    • dtype=np.uint8: 表示数据类型为8位无符号整数

5.3 读取与显示图像

5.3.1 C++

可以使用cv::imread()函数读取图像,使用cv::imshow()函数显示图像,使用cv::waitKey()函数等待按键,使用cv::destroyAllWindows()函数关闭所有窗口。

C++

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    // 读取图像
    Mat image = imread("path/to/your/image.jpg");

    // 检查图像是否成功加载
    if (image.empty()) {
        std::cout << "Could not open or find the image" << std::endl;
        return -1;
    }

    // 显示图像
    imshow("Display window", image);

    // 等待按键 (0表示无限等待)
    waitKey(0);

    // 关闭所有窗口
    destroyAllWindows();

    return 0;
}
5.3.2 Python

可以使用cv2.imread()函数读取图像,使用cv2.imshow()函数显示图像,使用cv2.waitKey()函数等待按键,使用cv2.destroyAllWindows()函数关闭所有窗口。

Python

import cv2

# 读取图像
img = cv2.imread('path/to/your/image.jpg')

# 检查图像是否成功加载
if img is None:
    print("Could not open or find the image")
else:
    # 显示图像
    cv2.imshow('image', img)
    cv2.waitKey(0)
    cv2.destroyAllWindows()

注意: 请将 "path/to/your/image.jpg" 替换为实际的图像文件路径。

5.4 视频读写

5.4.1 C++

可以使用cv::VideoCapture类读取视频或摄像头数据,使用cv::VideoWriter类写入视频。

读取视频:

C++

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    // 打开视频文件
    VideoCapture cap("path/to/your/video.mp4");

    // 检查视频是否成功打开
    if (!cap.isOpened()) {
        std::cout << "Could not open the video file" << std::endl;
        return -1;
    }

    while (true) {
        Mat frame;
        // 从视频中读取一帧
        cap >> frame;

        // 如果没有更多帧,则退出循环
        if (frame.empty())
            break;

        // 显示帧
        imshow("Video Frame", frame);

        // 等待按键 (延迟25毫秒)
        if (waitKey(25) >= 0)
            break;
    }

    // 释放 VideoCapture 对象
    cap.release();
    destroyAllWindows();

    return 0;
}

写入视频:

C++

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    // 获取视频的属性 (例如,宽度、高度、帧率) - 这里假设你知道这些属性
    int frame_width = 640;
    int frame_height = 480;
    double fps = 30.0;

    // 创建 VideoWriter 对象
    VideoWriter writer("output.avi", VideoWriter::fourcc('M', 'J', 'P', 'G'), fps, Size(frame_width, frame_height));

    // 检查 VideoWriter 对象是否成功创建
    if (!writer.isOpened()) {
        std::cout << "Could not open the output video file" << std::endl;
        return -1;
    }

    // 创建一些帧并写入视频
    for (int i = 0; i < 100; ++i) {
        Mat frame(frame_height, frame_width, CV_8UC3, Scalar(i * 2, 255 - i * 2, 100));
        writer.write(frame);
    }

    // 释放 VideoWriter 对象
    writer.release();

    return 0;
}
5.4.2 Python

可以使用cv2.VideoCapture()函数读取视频或摄像头数据,使用cv2.VideoWriter()函数写入视频。

读取视频:

Python

import cv2

# 打开视频文件
cap = cv2.VideoCapture('path/to/your/video.mp4')

# 检查视频是否成功打开
if not cap.isOpened():
    print("Could not open the video file")
else:
    while True:
        ret, frame = cap.read()
        # ret 是一个布尔值,表示是否成功读取到帧
        # frame 是读取到的帧,如果成功读取则为图像数据,否则为 None

        if not ret:
            break

        # 显示帧
        cv2.imshow('Video Frame', frame)

        # 等待按键 (延迟25毫秒)
        if cv2.waitKey(25) & 0xFF == ord('q'):
            break

    # 释放 VideoCapture 对象
    cap.release()
    cv2.destroyAllWindows()

写入视频:

Python

import cv2

# 获取视频的属性 (例如,宽度、高度、帧率) - 这里假设你知道这些属性
frame_width = 640
frame_height = 480
fps = 30.0

# 定义编码器和创建 VideoWriter 对象
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('output.avi', fourcc, fps, (frame_width, frame_height))

# 创建一些帧并写入视频
for i in range(100):
    frame = np.zeros((frame_height, frame_width, 3), dtype=np.uint8)
    frame[:] = [i * 2, 255 - i * 2, 100]  # 设置颜色
    out.write(frame)

# 释放 VideoWriter 对象
out.release()
cv2.destroyAllWindows()

6. 常用方法详解

接下来,我们将介绍一些OpenCV中常用的图像处理方法。

6.1 色彩空间转换

OpenCV提供了多种色彩空间之间的转换功能,例如BGR(Blue, Green, Red)到灰度图、HSV(Hue, Saturation, Value)等。

6.1.1 C++

使用cv::cvtColor()函数进行色彩空间转换。

C++

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat image = imread("path/to/your/image.jpg");
    if (image.empty()) return -1;

    // 转换为灰度图
    Mat gray_image;
    cvtColor(image, gray_image, COLOR_BGR2GRAY);
    imshow("Original Image", image);
    imshow("Gray Image", gray_image);
    waitKey(0);
    destroyAllWindows();

    // 转换为HSV色彩空间
    Mat hsv_image;
    cvtColor(image, hsv_image, COLOR_BGR2HSV);
    imshow("HSV Image", hsv_image);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.1.2 Python

使用cv2.cvtColor()函数进行色彩空间转换。

import cv2

img = cv2.imread('path/to/your/image.jpg')
if img is None:
    exit()

# 转换为灰度图
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow('Original Image', img)
cv2.imshow('Gray Image', gray_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

# 转换为HSV色彩空间
hsv_img = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
cv2.imshow('HSV Image', hsv_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

常用的色彩空间转换代码包括:

  • COLOR_BGR2GRAY: BGR到灰度

  • COLOR_BGR2HSV : BGR到HSV

  • COLOR_GRAY2BGR : 灰度到BGR

  • COLOR_HSV2BGR : HSV到BGR

6.2 图像阈值处理

阈值处理用于将图像像素值二值化,即将大于或小于某个阈值的像素设置为一个特定的值。

6.2.1 C++

使用cv::threshold()函数进行阈值处理。

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat gray_image = imread("path/to/your/image.jpg", IMREAD_GRAYSCALE);
    if (gray_image.empty()) return -1;

    Mat thresh_binary;
    threshold(gray_image, thresh_binary, 127, 255, THRESH_BINARY);
    imshow("Binary Threshold", thresh_binary);

    Mat thresh_binary_inv;
    threshold(gray_image, thresh_binary_inv, 127, 255, THRESH_BINARY_INV);
    imshow("Binary Inverse Threshold", thresh_binary_inv);

    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.2.2 Python

使用cv2.threshold()函数进行阈值处理。

import cv2

gray_img = cv2.imread('path/to/your/image.jpg', cv2.IMREAD_GRAYSCALE)
if gray_img is None:
    exit()

ret, thresh_binary = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY)
cv2.imshow('Binary Threshold', thresh_binary)

ret, thresh_binary_inv = cv2.threshold(gray_img, 127, 255, cv2.THRESH_BINARY_INV)
cv2.imshow('Binary Inverse Threshold', thresh_binary_inv)

cv2.waitKey(0)
cv2.destroyAllWindows()

常见的阈值类型包括:

  • THRESH_BINARY : 如果像素值大于阈值,则设置为最大值(通常为255),否则设置为0。

  • THRESH_BINARY_INV : 与 THRESH_BINARY相反。

  • THRESH_TRUNC : 如果像素值大于阈值,则设置为阈值,否则保持不变。

  • THRESH_TOZERO: 如果像素值大于阈值,则保持不变,否则设置为0。

  • THRESH_TOZERO_INV: 与 THRESH_TOZERO相反。

6.3 滤波与平滑

滤波和平滑操作用于减少图像中的噪声。

6.3.1 C++

常用的滤波方法包括均值滤波、高斯滤波、中值滤波等。

均值滤波:

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat image = imread("path/to/your/image.jpg");
    if (image.empty()) return -1;

    Mat blur_image;
    blur(image, blur_image, Size(5, 5));
    imshow("Original Image", image);
    imshow("Blurred Image", blur_image);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

高斯滤波:

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat image = imread("path/to/your/image.jpg");
    if (image.empty()) return -1;

    Mat gaussian_blur_image;
    GaussianBlur(image, gaussian_blur_image, Size(5, 5), 0);
    imshow("Original Image", image);
    imshow("Gaussian Blurred Image", gaussian_blur_image);
    waitKey(0);
    destroyAllWindows();

    return 0;
}

中值滤波:

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat image = imread("path/to/your/image.jpg");
    if (image.empty()) return -1;

    Mat median_blur_image;
    medianBlur(image, median_blur_image, 5);
    imshow("Original Image", image);
    imshow("Median Blurred Image", median_blur_image);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.3.2 Python

均值滤波:

import cv2

img = cv2.imread('path/to/your/image.jpg')
if img is None:
    exit()

blur_img = cv2.blur(img, (5, 5))
cv2.imshow('Original Image', img)
cv2.imshow('Blurred Image', blur_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

高斯滤波:

import cv2

img = cv2.imread('path/to/your/image.jpg')
if img is None:
    exit()

gaussian_blur_img = cv2.GaussianBlur(img, (5, 5), 0)
cv2.imshow('Original Image', img)
cv2.imshow('Gaussian Blurred Image', gaussian_blur_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

中值滤波:

import cv2

img = cv2.imread('path/to/your/image.jpg')
if img is None:
    exit()

median_blur_img = cv2.medianBlur(img, 5)
cv2.imshow('Original Image', img)
cv2.imshow('Median Blurred Image', median_blur_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.4 边缘检测

边缘检测用于识别图像中亮度变化剧烈的区域。常用的边缘检测算法包括Canny、Sobel、Laplacian等。

6.4.1 C++

Canny边缘检测:

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat gray_image = imread("path/to/your/image.jpg", IMREAD_GRAYSCALE);
    if (gray_image.empty()) return -1;

    Mat canny_edges;
    Canny(gray_image, canny_edges, 30, 100);
    imshow("Original Image", gray_image);
    imshow("Canny Edges", canny_edges);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.4.2 Python

Canny边缘检测:

import cv2

gray_img = cv2.imread('path/to/your/image.jpg', cv2.IMREAD_GRAYSCALE)
if gray_img is None:
    exit()

edges = cv2.Canny(gray_img, 30, 100)
cv2.imshow('Original Image', gray_img)
cv2.imshow('Canny Edges', edges)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.5 形态学操作

形态学操作是基于图像形状的一些基本操作,如腐蚀、膨胀、开运算、闭运算等,常用于去除噪声、分离物体、连接断裂的区域等。

6.5.1 C++
#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat binary_image = imread("path/to/your/binary_image.png", IMREAD_GRAYSCALE);
    if (binary_image.empty()) return -1;

    // 定义结构元素
    Mat kernel = getStructuringElement(MORPH_RECT, Size(5, 5));

    // 膨胀
    Mat dilated_image;
    dilate(binary_image, dilated_image, kernel);
    imshow("Dilated Image", dilated_image);

    // 腐蚀
    Mat eroded_image;
    erode(binary_image, eroded_image, kernel);
    imshow("Eroded Image", eroded_image);

    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.5.2 Python
import cv2
import numpy as np

binary_img = cv2.imread('path/to/your/binary_image.png', cv2.IMREAD_GRAYSCALE)
if binary_img is None:
    exit()

# 定义结构元素
kernel = np.ones((5, 5), np.uint8)

# 膨胀
dilation = cv2.dilate(binary_img, kernel, iterations=1)
cv2.imshow('Dilated Image', dilation)

# 腐蚀
erosion = cv2.erode(binary_img, kernel, iterations=1)
cv2.imshow('Eroded Image', erosion)

cv2.waitKey(0)
cv2.destroyAllWindows()

常用的形态学操作包括:

  • MORPH_ERODE: 腐蚀
  • MORPH_DILATE : 膨胀
  • MORPH_OPEN : 开运算(先腐蚀后膨胀)
  • MORPH_CLOSE : 闭运算(先膨胀后腐蚀)

6.6 轮廓检测

轮廓检测用于找到图像中物体的边界。

6.6.1 C++
#include <opencv2/opencv.hpp>
using namespace cv;
#include <vector>

int main() {
    Mat binary_image = imread("path/to/your/binary_image.png", IMREAD_GRAYSCALE);
    if (binary_image.empty()) return -1;

    std::vector<std::vector<Point>> contours;
    std::vector<Vec4i> hierarchy;
    findContours(binary_image, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE);

    Mat image_with_contours = Mat::zeros(binary_image.size(), CV_8UC3);
    for (size_t i = 0; i < contours.size(); i++) {
        drawContours(image_with_contours, contours, (int)i, Scalar(0, 0, 255), 2, LINE_8, hierarchy, 0);
    }

    imshow("Original Binary Image", binary_image);
    imshow("Image with Contours", image_with_contours);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.6.2 Python
import cv2

binary_img = cv2.imread('path/to/your/binary_image.png', cv2.IMREAD_GRAYSCALE)
if binary_img is None:
    exit()

contours, hierarchy = cv2.findContours(binary_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

image_with_contours = cv2.cvtColor(binary_img, cv2.COLOR_GRAY2BGR)
cv2.drawContours(image_with_contours, contours, -1, (0, 0, 255), 2)

cv2.imshow('Original Binary Image', binary_img)
cv2.imshow('Image with Contours', image_with_contours)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.7 几何变换

几何变换包括图像的缩放、平移、旋转、仿射变换和透视变换等。

6.7.1 C++

缩放:

#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat image = imread("path/to/your/image.jpg");
    if (image.empty()) return -1;

    Mat resized_image;
    resize(image, resized_image, Size(), 2.0, 2.0, INTER_LINEAR); // 放大两倍
    imshow("Original Image", image);
    imshow("Resized Image", resized_image);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.7.2 Python

缩放:

import cv2

img = cv2.imread('path/to/your/image.jpg')
if img is None:
    exit()

resized_img = cv2.resize(img, None, fx=2, fy=2, interpolation=cv2.INTER_LINEAR) # 放大两倍
cv2.imshow('Original Image', img)
cv2.imshow('Resized Image', resized_img)
cv2.waitKey(0)
cv2.destroyAllWindows()

6.8 绘制函数

OpenCV提供了一些用于在图像上绘制基本形状的函数,如直线、矩形、圆、文本等。

6.8.1 C++
#include <opencv2/opencv.hpp>
using namespace cv;

int main() {
    Mat image(300, 400, CV_8UC3, Scalar(255, 255, 255)); // 创建白色图像

    // 绘制直线
    line(image, Point(50, 50), Point(350, 250), Scalar(255, 0, 0), 3);

    // 绘制矩形
    rectangle(image, Point(100, 100), Point(300, 200), Scalar(0, 255, 0), 2);

    // 绘制圆形
    circle(image, Point(200, 150), 40, Scalar(0, 0, 255), -1); // -1 表示填充

    // 绘制文本
    putText(image, "Hello OpenCV", Point(50, 280), FONT_HERSHEY_SIMPLEX, 1, Scalar(0, 0, 0), 2);

    imshow("Drawing", image);
    waitKey(0);
    destroyAllWindows();

    return 0;
}
6.8.2 Python
import cv2
import numpy as np

img = np.zeros((300, 400, 3), dtype=np.uint8) + 255 # 创建白色图像

# 绘制直线
cv2.line(img, (50, 50), (350, 250), (255, 0, 0), 3)

# 绘制矩形
cv2.rectangle(img, (100, 100), (300, 200), (0, 255, 0), 2)

# 绘制圆形
cv2.circle(img, (200, 150), 40, (0, 0, 255), -1) # -1 表示填充

# 绘制文本
cv2.putText(img, "Hello OpenCV", (50, 280), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 0), 2)

cv2.imshow('Drawing', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

7. 进阶技巧

在掌握了基本语法和常用方法后,你可以尝试一些更高级的技巧。

7.1 ROI 与模板匹配

ROI (Region of Interest) 是图像中你感兴趣的区域,可以单独对这部分区域进行处理。模板匹配是在一个大图中搜索与给定模板图像最相似的区域。

7.2 特征检测(ORB/SIFT/SURF)

特征检测算法用于提取图像中具有代表性的点(特征点),这些特征点在图像匹配、物体识别等任务中非常有用。常见的算法有ORB、SIFT、SURF等。

7.3 摄像头标定与透视变换

摄像头标定是获取摄像头内外参数的过程,可以用于校正图像畸变。透视变换可以将图像从一个视角变换到另一个视角,常用于图像矫正和拼接。

由于篇幅有限,这些进阶技巧将在后续的文章中详细介绍。

8. 常见问题与解决方案

  • 导入cv2模块失败: 确保OpenCV已经成功安装,并且Python环境配置正确。尝试重新安装或检查Python路径。
  • 无法打开图像或视频: 检查文件路径是否正确,文件是否存在,以及文件格式是否受OpenCV支持。
  • 编译错误: 检查CMake配置是否正确,依赖库是否安装完整,以及编译命令是否正确。
  • 运行缓慢: 尝试优化代码,例如减小图像尺寸,使用更高效的算法等。对于C++,可以尝试Release模式编译。

如果在学习过程中遇到其他问题,欢迎在评论区提问,或者加我的微信与我交流。

9. 总结与建议

恭喜你!通过本文的学习,你已经对OpenCV的安装、配置、基本语法和常用方法有了初步的了解。计算机视觉是一个充满挑战和乐趣的领域,OpenCV作为强大的工具,将帮助你实现各种有趣的想法。

我的建议是:

  • 多动手实践: 学习编程最好的方式就是不断练习,尝试用OpenCV处理不同的图像和视频。
  • 查阅官方文档: OpenCV的官方文档非常详细,遇到问题时可以查阅官方文档获取更深入的理解。
  • 参与社区交流: 积极参与OpenCV相关的论坛、社区,与其他开发者交流学习经验。
  • 持续学习: 计算机视觉技术发展迅速,保持学习的热情,不断探索新的知识和技术。

10. 参考资料

感谢大家的阅读!希望这篇文章能够帮助你顺利入门OpenCV。如果你在学习过程中有任何疑问或者想要进一步交流,欢迎加我的微信:[Solitudemind ]。期待与你一起探索更多有趣的计算机视觉应用!


如对本文内容有任何疑问、建议或意见,请联系作者,作者将尽力回复并改进📓;( 联系微信:Solitudemind )

点击下方名片,加入 IT 技术核心学习团队。一起探索科技的未来,共同成长。

为了让您拥有更好的交互体验,特将这行文字设置为可点击样式:点击下方名片,加入 IT
技术核心学习团队。一起探索科技的未来,共同成长。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

默语∿

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值